Progettazione: problema di architettura dell'app Web .NET

3

Sto prendendo la mia prima incursione in .NET e sto progettando un'applicazione web che è pesante su altri servizi web in questo momento. Ho intenzione di fare quanto segue:

  1. Prendi l'input dell'utente (un numero USDOT)
  2. Richiedi i dati da un'API pubblica pubblica su quel numero DOT (a condizione che non sia disponibile nella memoria locale)
  3. Impegna in DB (se necessario)
  4. Passa a un calcolatore del punteggio di rischio che:
    • Separa i dati e cerca le bandiere rosse (come se il corriere non ha autorità) e altri rischi
    • Passa la determinazione del rischio alla vista in modo che l'utente possa prendere una decisione informata sul corriere.

L'applicazione sarà in stile questionario e farò affidamento sull'input dell'utente, ma ci sono alcuni fattori critici che possono essere generati immediatamente senza alcun input. Se questi fattori restituiscono qualcosa di brutto, l'utente probabilmente si fermerà lì perché ha ciò di cui ha bisogno per prendere una decisione sul corriere. Quindi ci sarà un call / return iniziale su fattori critici, quindi un call / return più approfondito che valuta la risposta dell'utente alle domande.

Mi aspetto di restituire un punteggio intero di rischio, in modo da poter fornire all'utente un "alto / medio / basso rischio" insieme a raccomandazioni individuali per aiutare a prendere una decisione informata.

Ho trovato un'ottima app di esempio chiamata AccountAtAGlance di Dan Wahlin ( link ). Sono rimasto impressionato da quanto ho conservato dalla rivista e dai libri che sto leggendo, perché ho capito la maggior parte delle sue app di esempio con facilità.

Sto lottando con il modo migliore per implementare il passaggio dei dati dal modello Carrier al Risk Score Calculator e al Risk Score Calculator rimandandolo al Controller e sto cercando aiuto.

La struttura del mio file sta sostanzialmente simulando l'esempio di AccountAtAGlance.

In questo momento la mia idea è la seguente:

  1. Rendi RiskScoreRepository.cs disponibile per il controller e chiamala RiskScoreRepository.GetCarrierRisk(int dotnumber)
  2. Ecco dove mi blocco: GetCarrierRisk chiama qualcosa in modo che possa valutare il rischio iniziale e restituirlo al controller.

Quindi, un paio di domande che ho:

Un repository è il posto appropriato per GetCarrierRisk ? Dove dovrebbe andare GetCarrierRisk per ottenere i dati valutati e restituiti? Questo è ciò a cui mi riferisco come il Risk Score Calculator. Dovrebbe essere un RiskScoreEngine ? Simile a link ?

Penso che sia meglio, per testabilità, avere ciascun fattore di rischio (ad esempio se il vettore ha autorità e se il vettore ha ispezioni) di avere un proprio metodo che accetta un valore grezzo e restituisce il rischio appropriato. Ma in che modo la richiesta fluisce in questi metodi? GetCarrierRisk fa un sacco di chiamate al calcolatore del punteggio di rischio e inserisce il rendimento in qualcosa come una lista che viene trasmessa al controllore?

    
posta I Love You 27.06.2015 - 21:02
fonte

1 risposta

2

Devi dividere "ottenere informazioni" da "valutare le informazioni"

Hai (al momento) due fonti di informazioni, il risultato USDOT e il modulo. Ti consiglio di compilare questi risultati in un oggetto RiskInfo che puoi trasferire a un motore di CalcRisk.

CalcRisk dovrebbe essere un calcolo stateless puramente in memoria in modo da poterlo testare in modo estensivo.

Vorrei prendere in considerazione la possibilità di chiamare lo stesso motore per le informazioni RiskInfo complete e parziali. questo rende più difficili i test ma il flusso di lavoro è semplice. Probabilmente aggiungerai ulteriori informazioni a RiskInfo man mano che il prodotto si svilupperà in modo da non voler separare artificialmente il "calc iniziale" e il "calc completo" perché in seguito avrai "calc totali con extra" e così via.

Userei i repository, ma li terrei lontani dalla logica di calcolo ad esempio:

namespace Risk
{
    /// <summary>
    /// the information you get back from the US gov about a dot number
    /// </summary>
    public class USDOTReport
    { }

    /// <summary>
    /// the information you collect from your form
    /// </summary>
    public class FormInformation
    {
        public int USDOTNumber { get; set; }
    }

    /// <summary>
    /// a data access layer for saving and retrieving usdotreports from/to a database
    /// </summary>
    public interface IUSDOTRepository
    {
        USDOTReport Get(string id);
        void Save(USDOTReport report);
    }

    /// <summary>
    /// encapsulate the USDOT webservice so you can make calls to get reports
    /// </summary>
    public interface IUSDOTService
    {
        USDOTReport Get(int usDotNumber);
    }

    /// <summary>
    /// a repository for storing/retrieving form info on a database
    /// </summary>
    public interface IFormInfoRepository
    {
        FormInformation Get(string id);
        void Save(FormInformation forminfo);
    }

    /// <summary>
    /// a combined risk information object which includes all the data you might use calculating the risk info result
    /// </summary>
    public class RiskInfo_v1
    {
        public USDOTReport DotReport { get; set; }
        public FormInformation Form { get; set; }
    }

    /// <summary>
    /// the result of a risk calculation
    /// </summary>
    public class RiskInfoResult
    {
        double RiskScore { get; set; }
    }

    /// <summary>
    /// Risk calculators should calculate the riskinforesult soley from the riskinfo object 
    /// </summary>
    public interface IRiskCalculator_v1
    {
        RiskInfoResult CalculateRisk(RiskInfo_v1 RiskInfo);
    }

    /// <summary>
    /// this is your top level applicaiton or website
    /// </summary>
    public class RiskCalcService
    {
        IFormInfoRepository repoForm;
        IUSDOTRepository repoDot;
        IRiskCalculator_v1 riskCalculator;
        IUSDOTService dotService;

        public RiskInfoResult CalcRisk(FormInformation formInfoSoFar)
        {
            //save form
            repoForm.Save(formInfoSoFar);

            //get dotreport
            USDOTReport report = dotService.Get(formInfoSoFar.USDOTNumber);

            //save it
            repoDot.Save(report);

            //create the risk info
            RiskInfo_v1 ri = new RiskInfo_v1()
            {
                DotReport = report,
                Form = formInfoSoFar
            };

            //calc risk
            RiskInfoResult result = riskCalculator.CalculateRisk(ri);

            return result;
        }

    }
}
    
risposta data 28.06.2015 - 12:16
fonte

Leggi altre domande sui tag