Architettura per un cliente / progetto / preventivo / sistema di ordini

4

Sto lavorando per capire l'architettura per mettere insieme un sistema modulare complesso che ha Ordini, Clienti, Progetti e Quotazioni.

Il cliente può avere più progetti. Per ogni progetto ci sarà almeno un ordine o preventivo associato, ma esiste la possibilità di avere più preventivi e ordini su ciascun progetto che appartiene a un cliente. Nei requisiti del software non dovrebbe essere possibile avere una quotazione o un ordine senza che sia legato a un progetto.

Il riaggancio che sto avendo sta cercando di capire come creare le classi attorno a questo sistema. È sbagliato avere una classe Customer che ha Projects , Orders e Quotes proprietà che contengono tutti gli elementi. Sembra che la classe Customers debba essere estesa ad alcuni come aggiungere questi elementi piuttosto che come proprietà hard-coded. C'è un modello di progettazione che potrei usare, come il motivo del decoratore?

    
posta Yamaha32088 16.11.2017 - 23:05
fonte

3 risposte

2

Certamente non sono richiesti modelli di ereditarietà o di ereditarietà per il tuo attuale requisito. Possiamo creare subito le classi Customer , Project , Order e Quote . Abbiamo bisogno di identificare attentamente le relazioni tra loro in modo che possiamo decidere di posizionare proprietà e metodi.

Hai detto che Customer può avere più Project s. Pertanto, la classe Customer avrà Lis<Project> e un metodo addProject(Project) .

    public class Customer {
        private List<Project> projects;

        public void addProject(Project project) {
            projects.add(project);
        }
    }

Allo stesso modo Project dovrebbe contenere un List<Quote> e List<Order> per memorizzare preventivi e ordini. Ma i metodi add***() devono essere progettati in modo più complicato.

Vediamo circa Quote e Order . I tuoi requisiti software indicano che Quote o Order non possono esistere senza essere associati a Project . Quindi hai bisogno di un costruttore in Quote e Order che accetta un'istanza Project . Alcune cose sono degne di nota qui.

  1. Abbiamo bisogno di aggiungere Quote o Order alla classe Project . Il posto giusto per farlo è il costruttore di Quote o Order .

    public class Quote {
        private Project project;
    
        public Quote(Project project) {
            project = p;
            project.addQuote(this);
        }
    }
    
    public class Order {
        private Project project;
    
        public Order(Project project) {
            project = p;
            project.addOrder(this);
        }
    }
    
  2. Spesso il posto giusto per scrivere queste classi è all'interno della classe Project (classi interne statiche). Puoi vedere questo modello in Menu e MenuItems , Tab e TabItems , ecc. Dove MenuItems e TabItems non possono esistere senza essere legati a Menu o Tab . Un altro esempio è Iterator e List .

  3. I loro costruttori sono resi inaccessibili rendendoli privati e il add***() diventerà metodi factory nella classe che li include e restituisce l'istanza.

    public class Project {
        private List<Quote> quotes;
        private List<Order> orders;
    
        public Quote addQuote(int id) {
            Quote quote = new Quote(this, id);
            quotes.add(quote);
            return quote;
        }
    
        public Order addOrder(int id) {
            Order order = new Order(this, id);
            orders.add(order);
            return order;
        }
    
        public static class Quote {
            private final int id;
            private final Project project;
    
            private Quote(Project project, int id) {
                project = p;
                this.id = id;
            }
        }
    
        public static class Order {
            private final int id;
            private final Project project;
    
            private Order(Project project, int id) {
                project = p;
                this.id = id;
            }
        }
    }
    

I parametri di addQuote() e addOrder() potrebbero essere modificati in base alle necessità.

Ora l'ultimo problema da affrontare è che dovrebbe esserci almeno un Quote o order in un Project . Possiamo risolvere questo problema con metodi di produzione statici in Project .

    public class Project {
        // Fields

        private Project() {
            // Initialise the fields
        }

        public static Project createWithQuote(int id) {
            Project p = new Project();
            p.addQuote(id);
            return p;
        }

        public static Project createWithQuotes(int[] ids) {
            Project p = new Project();
            for (int id : ids)
                p.addQuote(id);
            return p;
        }

        // Add similar static factories for Order

        // Rest of the code

    }

Il costruttore privato e le fabbriche statiche migliorano la leggibilità ed evitano conflitti di sovraccarico del costruttore. Se lo desideri, puoi usare anche costruttori con sovraccarico pubico. Se la classe deve essere sottoclasse, rendere il costruttore protetto.

    
risposta data 03.12.2017 - 11:30
fonte
3

It seems like the Customers class should be extended some how to add these items [...]

Perché? Estensione / ereditarietà viene utilizzata quando si desidera centralizzare il codice comune tra oggetti simili. Questo sarebbe un ottimo modo per definire più tipi di Customers dove potresti averne uno che ha un nome e un cognome per i clienti privati mentre potresti avere un altro con il nome di una società per le imprese. Entrambi condividono proprietà e implementazione comuni in Customer ma sono le loro rispettive classi in BusinessCustomer e PrivateCustomer .

Potresti chiedere "Qual è l'indirizzo del nostro cliente, signor Smith?" Ma potresti davvero chiedere "Qual è il premio del nostro cliente, signor Smith?" - quale premio? Il costo del suo progetto? Ha vinto un premio in un torneo? Questa non è una domanda valida perché questa proprietà non è direttamente associata al cliente ma con qualcos'altro, che a sua volta potrebbe portarci al cliente.

Quindi perché vorresti che il tuo cliente avesse un premio, un caposquadra, una data di inizio, una data di scadenza, informazioni bancarie, ...? Queste sono tutte proprietà che avresti nel tuo cliente, ma non fanno parte di ciò che rende un cliente un cliente, come nome, indirizzo, data di nascita, ...

Questo è il punto essenziale per avere classi separate.

[...] rather than hard-coded as properties

Proprietà hard-coded? Quelle sono variabili variabili con un buon contenuto variabile. Quelli non devono essere hard-coded affatto - non dovrebbero essere realmente.

Creerai e connetti nuovi oggetti in fase di runtime tramite un modulo nell'interfaccia utente.

Qui hai risposto alla tua domanda da solo:

[1] The customer can have multiple projects.

[2] For each project there will be at least one order or quote associated [...]

[3] In the software requirements it should not be possible to have a Quote or Order without it being tied to a project.

[1] Customer 1:n Projects
[2] Project 1:n Order
[2] Project 1:n Quote
[3] The constructor of your Order and Quote take a Project as parameter to which they will be bound.

Quindi definisci un cliente di classe in cui hai un elenco di progetti. Definisci un progetto di classe in cui hai un elenco di ordini e un elenco di citazioni.

Come detto prima: Ordini e Quotazioni prendono un Progetto per il costruttore e si aggiungono alla loro lista. Quindi puoi creare clienti e progetti e aggiungere i progetti all'elenco di progetti dei clienti.

Is there a design pattern I could be using, such as the decorator pattern?

Gli schemi di progettazione non rendono il tuo programma automaticamente valido ed è dovuto a persone come te, che cercano immediatamente un modello predefinito da seguire, che a molte persone non piacciono.

Inoltre non hai davvero bisogno di schemi complicati qui. Il compito più grande sarà quello di scoprire quali valori si desidera salvare, cosa fare con loro e come crearli in un'interfaccia utente significativa.

    
risposta data 17.11.2017 - 19:44
fonte
0

Dato che ti stai concentrando sulle relazioni tra gli oggetti (i dati, per lo più) con le loro cardinalità, questo suona molto più come un problema di database relazionale.

Se si progetta un buon database con i vincoli esistenti, è possibile creare automaticamente il codice dal database utilizzando i moderni IDE

Potrebbe essere molto utile guardare il seguente link per capire un approccio automatizzato per creare semplici vecchi oggetti (java) da una struttura di database esistente:

Java EE 6 Giornata per sviluppatori OTN in laboratorio , utilizzando VM .

    
risposta data 02.12.2017 - 23:21
fonte