Come incorporare i modelli di entità esterne nel modello concettuale?

6

Se voglio creare un modello concettuale per la mia nuova applicazione, e durante l'analisi, ho scoperto che alcuni oggetti come employee, department ..etc fa parte di un altro sistema. e tutti i dati relativi a loro come il nome o il numero del dipendente esistono in quel sistema.

Le mie domande qui:

  • Come gestire questo caso nel mio modello concettuale? Dovrei includere questi oggetti e le loro responsabilità nel mio modello concettuale?
  • Come implementarli nella mia applicazione (Suggerimento: lo userò asp.net MVC and EF6 code-first )
posta Anyname Donotcare 04.04.2018 - 13:06
fonte

4 risposte

6

IMHO dovresti modellare quegli oggetti esattamente nel grado in cui ne hai bisogno nella tua applicazione, niente di meno, non di più. Ad esempio, non modellare tutti gli attributi disponibili, basta modellare gli attributi richiesti dal programma. Se esiste un'entità esterna in cui è necessario solo uno o due attributi nel proprio sistema, è possibile considerare di aggiungere tali attributi a un'entità interna esistente. Se hai bisogno di più, considera di modellare l'entità esterna con gli attributi richiesti, ma prova a mantenere la denominazione identica o almeno coerente.

Questa è una informazione preziosa per l'implementazione del codice della tua applicazione. Se dovessi escludere gli oggetti dal tuo modello, scrivere una descrizione coerente diventerebbe molto più difficile.

Se ritieni che sia utile per il pubblico del tuo modello concettuale, usa un modo coerente di codificare le entità o gli attributi come entità esterne. Ad esempio, in UML è possibile introdurre uno stereotipo speciale per questo. Oppure usi qualche tipo di commenti o annotazioni, a seconda della notazione che stai utilizzando per il tuo modello.

In seguito, quando implementerai questo, probabilmente avrai bisogno di qualche tipo di oggetti proxy per accedere alle entità esterne, contenente esattamente gli attributi che hai modellato sopra. Quindi in questo senso, gli oggetti sono anche parte del tuo sistema, almeno in una certa misura.

Il modo in cui li implementate dipende in modo preciso dai dettagli. Ad esempio,

  • se il tuo sistema ha bisogno solo dell'accesso in sola lettura a tali entità esterne o anche dell'accesso in scrittura,

  • se ci sono chiavi immutabili in quelle entità che consentono al tuo sistema di creare riferimenti (o meno),

  • se ci sono alcune incoerenze tollerabili tra i proxy nel tuo sistema e il sistema esterno (almeno per un certo periodo di tempo)

  • che tipo di API fornisce il sistema esterno

A seconda di tali dettagli, puoi decidere tra

  • implementare tabelle proxy per quegli oggetti con qualche tipo di strategia di sincronizzazione, o semplicemente

  • implementandoli come visualizzazioni del database o

  • senza alcuna rappresentazione del database, semplicemente estraendo gli attributi negli oggetti client usando del codice.

risposta data 09.04.2018 - 19:56
fonte
4

OK così! la tua applicazione è una "app di gestione del turno"

In sostanza questa app non si preoccupa veramente dei dipendenti e dei reparti. Si prenderà cura di quando inizia e finisce il giorno lavorativo, quante persone lavorano in azienda, quanto è lungo un turno ecc.

Quindi dovresti escluderli dal tuo modello concettuale. Lo complicherà solo Forse ad esempio, a volte un turno non viene occupato da un "Dipendente" come definito dall'altro sistema. Forse è un lavoratore a contratto o alcuni di questi.

Crea nuovi modelli per l'oggetto di cui hai bisogno Shift, Person, Business Day ecc. e descrivi il sistema in questi termini.

Quando si arriva effettivamente a fare in modo che il sistema utilizzi quegli stessi oggetti, in modo che sia abbastanza flessibile da lavorare con qualsiasi dato, ma collegarlo agli altri sistemi con un livello di esportazione o mappatura separato.

Ad esempio. Immagina invece di scrivere la tua app di gestione Shift che hai deciso di acquistarne uno "pronto all'uso". Non ti aspetteresti che l'app off the shelf sia in grado di connettersi direttamente ai tuoi modelli di dipendenti esistenti. Doveva essere in grado di lavorare con molte possibili fonti di dati.

Ci si aspetterebbe comunque che ci fosse una API o una funzione di importazione / esportazione che consentisse di collegare i sistemi esistenti ad essa. Utilizzo dei dati dei dipendenti per compilare i relativi dati di ShiftWorker.

Scrivere il proprio prodotto in casa ti consentirà di legare più strettamente i due modelli rispetto a un prodotto standard. Ma dovresti comunque rispettare la separazione delle preoccupazioni tra i due sistemi e fornire un'astrazione di mappatura o anticorruzione tra loro.

    
risposta data 04.04.2018 - 13:35
fonte
2

Credo che la risposta di @Ewan copra lo specifico scenario fornito, quindi questo seguirà un percorso più generico / generale, ove possibile. (Nota che gli esempi seguenti sono usati solo per mostrare una prospettiva simile)

La prima cosa che ti viene in mente per aiutare con la tua confusione è mostrare alcuni problemi relativi visti quando si ha a che fare con diversi spazi dei nomi, in questo caso possiamo guardare alle enumerazioni. Ad esempio, se un oggetto in un livello dati viene utilizzato come enumerazione "principale" che definisce la digitazione per una determinata voce. (ES .: PersonEnum {Dipendente = 1, Manager = 2, Contractor = 3, CEO = 4, Fornitore = 5, ...})

Quando si arriva a un caso d'uso, potrebbe esserci un'istanza in cui è definito un enum (ValidPersonEnum) per indicare quali valori di PersonEnum sono validi per il caso d'uso. Ad esempio, dipendenti e manager possono essere mostrati solo in un rapporto di stipendio, gli appaltatori possono essere mostrati sia nel rapporto sul salario sia nel riepilogo dei costi del progetto, e i fornitori esposti nel riepilogo dei costi del progetto.

Quando si controllano questi valori l'uno contro l'altro (è la voce data del tipo Employee?), si verifica un errore, in cui lo spazio dei nomi viene utilizzato per definire il tipo di enum. Con questo in mente, possiamo affrontare un punto di vista di alto livello usando il tuo esempio.

Per il Dipendente del sistema esterno, è definito all'interno di quel sistema come parte del suo concetto. Per il tuo sistema, puoi utilizzare Employee, tramite dati o metodi, ma il Dipendente viene sostanzialmente modificato in YourSystem.Employee piuttosto che in ExternalSystem.Employee.

Per il tuo modello, il Dipendente potrebbe quindi essere mostrato rispetto a come l'applicazione corrente lo usa piuttosto che come fa il sistema esterno. Per diramarsi sul punto @ Ewan, questa confusione potrebbe essere chiarita attraverso una qualche forma di astrazione. Questo potrebbe essere usato nella tua applicazione come un concetto di Persona come base, e come Dipendente come un'implementazione di Persona.

Essendo generale, vorrei sottolineare che ci possono essere delle volte in cui vorresti / potresti voler includere il concetto dal sistema esterno. Questi si ridurranno di più nelle applicazioni di tipo estensione, dove la nuova applicazione manipolerà (crea / modifica) i dati all'interno del sistema esterno.

Quindi, per la tua prima domanda, non dovresti necessariamente dichiarare le responsabilità del Dipendente rispetto al sistema esterno. Il dipendente deve essere dichiarato per le sue responsabilità nel modello e potrebbero esserci metodi simili a seconda di cosa è necessario. Questo modello sarebbe quindi rispetto all'applicazione di destinazione. Se hai provato a progettare il modello attorno a un altro sistema, allora potrebbe sembrare più un'aggiunta a quel sistema esistente piuttosto che un'applicazione separata.

Inoltre, se un modello dipendesse da come un oggetto viene usato in un sistema separato, allora potrebbe diventare più difficile ottenere alcune nuove applicazioni dal terreno, poiché l'oggetto (i) può cambiare in qualsiasi momento per qualsiasi motivo ( s) al di fuori della nuova applicazione (durante e dopo la progettazione di un modello di concetto).

Se si decide di indicare l'origine dati di ciascun elemento, è possibile includere il percorso (file, server di database, ecc.) o alcune dipendenze di processo denominate (aggiornamento notturno o qualche altra elaborazione dati esterna).

Per quanto riguarda la domanda di implementazione, questo è il punto in cui hai diversi livelli da recensire. Il concetto ti darà una road map per la tua applicazione (la classe X contiene un elenco di classi Y per determinare se l'azione Z può essere eseguita, o la classe M non può esistere senza la classe L). Quando si implementa il concetto, è possibile definire l'origine dei dati, poiché il concetto potrebbe non avere l'opportunità di definire una fonte. Questi passaggi di implementazione finirebbero per essere il luogo che definisce le interazioni con altri sistemi (i dati dei dipendenti vengono recuperati in base al sistema esterno).

Ancora una volta, gli esempi di cui sopra sono stati dati solo come un tentativo di mostrare una prospettiva simile, e penso che la risposta di @ Ewan copre gli stessi punti rispetto al tuo esempio. Spero che i miei esempi aiutino a collegare i concetti forniti.

    
risposta data 09.04.2018 - 19:21
fonte
1

Queste entità non sono realmente tue e possono essere modificate al di fuori del tuo "sistema", ma puoi fornire linkage a loro.

Ad esempio, ecco la tua Employee entità del modello (che sarà anche la prima classe del codice EF):

public class Employee
{
    // Your key and anything else besides whatever the external entity provides
    public int Id { get; set; }        

    // 1-to-1 relationship to the external entity
    public virtual ExternalEmployee ExternalEmployee { get; set; }
}

Ed ecco l'entità del modello ExternalEmployee (e codice prima classe) che fornisce le proprietà che vuoi dall'entità esterna mappando a una vista del database (vedi DbContext sotto ):

public class ExternalEmployee
{
    public int Id { get; set; }
    public string Name { get; set; }

    // 1-to-1 relationship to your Employee
    public virtual Employee Employee { get; set; }
}

L'EF DbContext ( vw_ExternalEmployees è una vista del database che fornisce tutti i dati a ExternalEmployee ):

public partial class MySystemContext : DbContext
{
    // ...

    public virtual DbSet<Employee> Employees { get; set; }
    public virtual DbSet<ExternalEmployee> vw_ExternalEmployees { get; set; }
}

Il tuo EmployeeRepository è responsabile solo per tuo Employee , ovviamente. Di conseguenza, nel tuo livello di servizio (ad esempio EmployeeService ) se è necessario apportare modifiche ai dati esterni, questi devono essere delegati ai servizi corrispondenti responsabili per le entità esterne.

    
risposta data 14.04.2018 - 12:43
fonte