Eksempel: et ordresystem note 5 Lagdeling s. 1 Eksempel: et ordre-system NiceHair er et firma, som sælger udstyr, inventar og frisørartikler til frisørsaloner over hele landet. Det er ejet af et ægtepar (Sanne og Ulrik). Analyse Aktører Der er følgende aktører til systemet: Salgschefen, som registrer ordrerne, der indtelefoneres af sælgerne. Det er i øjeblikket Sanne, der varetager rollen som salgschef. Lagerekspedient, som ser i systemet, hvilke ordrer, der skal ekspederes. Det er Sannes far, der har den rolle i dag. Indkøber, som ser i systemet, hvor stor omsætning er på de enkelte varer, for at planlægge indkøb. Ulrik har den rolle. Use cases Der er følgende use cases i systemet: Modtag varer Modtag ordre Ekspeder ordre Planlæg indkøb Afhold status Lav regnskab Modtag varer: (brief) Når der kommer varer hjem, er det indkøberen, der kontrollerer om det modtagne svarer til det, der er bestilt, og lægger varerne ud til lagerekspedienten, som lægger varerne på plads. Indkøberen slår den enkelte vare op i systemet vha. varenr, og registrerer det modtagne antal og viser den nye beholdning for hver af de modtagne varer. Hvis varen er en ny vare, opretter indkøberen den i systemet med oplysninger om varenr, betegnelse og pris. Modtag ordre: (brief) Når en sælger ringer en ordre ind, undersøger salgschefen først om kunden findes i systemet vha. af kundenr. Hvis kunden ikke findes, registrerer salgschefen kunden i systemet med kundenr, navn, adresse, mm. 1 1 I denne udgave ser vi bort fra kunden
Eksempel: et ordresystem note 5 Lagdeling s. 2 Herefter registrerer salgschefen ordren med ordredato og leveringsdato og derefter varenr og antal for hver ordrelinie. Ekspeder ordre: (brief) Hver dag åbner lagerekspedienten systemet for at checke, om der er ordrer, der skal ekspederes. Systemet viser en oversigt over de ordrer, der skal ekspederes den pågældende dag, og lagerekspedienten vælger en ordre fra oversigten. Systemet viser ordren med varenr, betegnelse og antal for hver vare, og lagerekspedienten pakker nu ordren, og registrer dette i systemet, som automatisk nedskriver antallet for de berørte varer. (casual) Når systemet opstiller oversigten over ordrer, der skal pakkes den pågældende dag, undersøger systemet, om der er de varer på lager, der skal pakkes. Hvis der er en ordre, hvor dette ikke er tilfældet, kommer ordren ikke med på listen, men systemet sender en email med oplysning om ordrenr, varenr, betegnelse, antal på ordrelinien og det registrerede antal på lager til indkøberen. Planlæg indkøb: (brief) Hver dag trækker indkøberen en lagerliste fra systemet. Indkøberen løber listen igennem, og checker, om der er varer, hvor beholdningen er så lav, at han skal bestille nye varer hjem. Indkøberen checker også flere gange om dagen sine emails, for at se, om systemet har sendt emails med besked om ordrer, der ikke kan leveres, fordi der ikke er varer nok på lager. Når der er kommet en sådan besked, foretager indkøberen et haste-indkøb. Afhold status: (brief) Cirka en gang i kvartalet afholder indkøberen sammen med lagerekspedienten status over lageret. Først trækker lagerekspedieneten en lagerliste fra systemet. Dernæst gennemgår han lageret for ukurante varer, som han derefter smider ud og fjerner fra systemet. Endelig vurderer indkøberen, om der skal ske en justering af pris og evt betegnelse på nogle varer, og foretager de nødvendige justeringer i systemet. Lav regnskab: (brief) Gennem året laver salgschefen løbende opfølgning på regnskabet (cirka en gang i kvartalet). I den forbindelse slår han op i systemet, for at se den samlede lagerbinding for alle varerne.
Eksempel: et ordresystem note 5 Lagdeling s. 3 I use case-diagrammet gives et overblik over systemets aktører og use cases: Planlæg indkøb Modtag varer Indkøber Afhold status Ekspeder ordre Lagerekspedient Modtag ordre Salgschef Lav regnskab
Eksempel: et ordresystem note 5 Lagdeling s. 4 Eksempler på objekter for systemet: Vare-objekter: Ordrelinieobjekter Ordre-objekter: 2345 zigzag-saks 345,- 20 stk 2 167 20/8-09 25/8-09 plukket 2346 10 stålkamme 257,- 30 pk 1 2347 føntørrer de luxe 1275,- 12 stk 5 198 20/9-09 27/9-09 ikke plukket 1 Domænemodellen for systemet ser således ud: Vare -varenr -betegnelse -pris -beholdning Ordrelinie -antal 1 0..* 0..* 1 ordre -ordrenr -ordredato -leveringsdato -plukket
Eksempel: et ordresystem note 5 Lagdeling s. 5 Design og kode GRASP Når vi designer sekvensdiagrammer (se nedenfor) skal vi anvende GRASP-mønstrene til at designe efter. I denne omgang har vi især anvendt følgende GRASP-mønstre: High Cohesion (høj samhørighed). Dette mønster betyder, at der skal være høj samhørighed i en klasse eller sagt på en anden måde, at en klasse ikke må bruges som skraldespand for alt muligt, der ikke kar noget med hinanden at gøre. Dette mønster bruges til at opdele vores formular-klasse i to klasser: én som har med selve brugergrænsefladen at gøre, og én, som har med administration af varer at gøre (VareCollection) Information Expert. Dette mønster betyder, at metoder skal placeres på den klasse, hvor de naturligt hører hjemme, dvs på den klasse som har de oplysninger (attributter), som metoden skal bruge. Eksempler på hvor dette mønster er anvendt: o Get og Set-proporties o Tilføjelse, fjernelse og justering af vare ligger naturligt på VareCollection-klassen som har en liste over varerne og dermed også kan finde den vare, som skal behandles. o Beregning af lagerbinding for en vare ligger naturligt på vare-klassen (som har pris og beholdnings-attributterne), hvorimod beregning af samlet lagerbinding ligger på VareCollection klassen som har en liste over alle varerne. Creator. Dette mønster betyder, at der skal være en creator for forretningsobjekterne. Hvis en anden forretningsklasse er naturlig creater, bruges denne, ellers laves en collection-klasse. Som creator for VareCollection-klassen er det naturligt at bruger brugergrænsefladen (formularen) Ifm creator-mønstret taler man om, at de objekter, der bliver skabt af creatoren, er aggregeret op i creatoren. Low Coupling (Lav kobling). Dette mønster betyder, at der skal være en lav kobling mellem klasserne for at gøre deres indbyrdes afhængighedsforhold så lille som muligt. Derved opnår man, at ændringer i én klasse medfører få eller ingen ændringer i en anden klasse. Mønsteret bruges f.eks. i forbindelse med systemoperationen VisLagerliste. Frem for at returnere den interne datastruktur i Collection-klassen (en liste), returneres i stedet en iterator, som er uafhængig af listen. Controller. Dette mønster betyder, at brugergrænsefladen kontakter systemet gennem et controller-objekt (dette gælder i det mindste for det første kald til systemet i et Systemsekvens-diagram). Controller-objekter udfører ikke selv domæne-logik, men delegerer ansvaret videre til de underlæggende objekter. I frisør-eksemplet hedder kontroller-klassen FrisørSystem, og den aggregerer collection-klasserne Ordre-Collection og Vare-Collection op i sig. Men ellers har controller-klassen ikke nogen selvstændige attributter.
Eksempel: et ordresystem note 5 Lagdeling s. 6 Der findes to videreudviklinger af controller-mønstret, nemlig Facade-controlleren og Session-controlleren. Session-controlleren bruges i use-casene Modtag ordre og Ekspeder ordre. Ideen er, at controlleren husker den aktuelle ordre mellem systemoperationerne, så den ikke skal findes frem ved hvert kald. Facade-controlleren sørger for at skjule domæne-objekterne for brugergrænsefladen, og er dermed med til at mindske koblingen. Dette gøres ved at sende interfaces til domæneklasserne op i brugergrænsefladen, når der skal læses domæne-data. Disse interfaces inderholder kun Get-properties til domæne-klasserne Arkitektur (Nyt) Udover indkapslingen i klasser, findes en bredere indkapsling i såkaldte lag, også kaldet komponenter (Namespaces i C# og Packages i Java og UML). Et lag indeholder en gruppe af klasser, et subsystem, som er ansvarlig for en større del af systemet. De klassiske lag består af: Brugergrænseflade Model (Domæne logik) Teknisk lag, f.eks. Data Source lag, som er ansvarlig for persistens af data. I vores system, ser arkitekturen således:
Eksempel: et ordresystem note 5 Lagdeling s. 7 Her repræsenterer GUI brugergrænseflade-laget og Model model-laget Ansvaret for persistens af data er lagt ind i klassen FrisørSystem (den er fejlagtigt kaldtordresystem i figuren ovenfor det retter jeg når jeg får tid). Denne klasse fungerer også som Facade og Sessioncontroller, derfor er laget kaldt Controller. Interfaces-laget er ikke et rigtigt lag i klassisk forstand, men er medtaget af hensyn til Facademønstret, dvs det er et lag, som GUI en har kendskab til (udover til controlleren). Lagene og deres indbyrdes afhængigheder er implementeret vha Namespaces, idet hvert lag har sit eget Namespace. Når man lagdeler et projekt, skal de lag, der ikke indeholder GUI oprettes som tomme projekter /empty projects. Hvis man skal opdele et eksisterende projekt er der følgende trin: Opret et projekt til laget Træk eller cut - og - paste de filer, der skal ligge på laget ind i projektet Sørg for, at de får et name space svarende til projektet Når man er færdig med at opdele i lag, kender de forskellige lag ikke hinanden. Derfor skal man lave de nødvendige forbindelser mellem lagene (du kan se hvilke der er nødvendige på skitsen ovenfor, men for en sikkerheds skyld skriver jeg dem også lige her): GUI skal have reference til Controller og Interfaces og skal også tilføje using directives til deres name spaces Controller skal have reference til model og interfaces, og skal også tilføje using directives til deres name spaces Model skal have reference til Interface skal også tilføje using directive til dens name spaces
Eksempel: et ordresystem note 5 Lagdeling s. 8 Kode - generelt Controlleren FrisørSystem har de collection-klasser VareCollection og OrdreCollection aggregeret op i sig og sørger generelt for at delegere kaldene videre til disse klasser. Den er desuden en kombination mellem en session- og facade-controller. Som session-data gemmes den den aktuelle ordre. Facaden sørger for at der altid returneres interfaces til brugergrænsefladen, når det er domæne-objekter (f.eks metoden FindVare): class FrisørSystem private OrdreCollection ordrecol; private VareCollection varecol; [NonSerialized] private Ordre aktuelordre; // aggregering af ordrecollection // aggregering af varecollection // session-variabel for aktuel ordre // Konstruktør public FrisørSystem() ordrecol = new OrdreCollection(); varecol = new VareCollection(); aktuelordre = null; VareCollection-klassen er lavet vha. en liste: class VareCollection private List<Vare> varer; // aggregering af nul til mange varer // Konstruktør public VareCollection() varer = new List<Vare>(); // pga aggregering skal vareliste skabes Vare-klassens attributter ser således ud: class Vare : IVaredata // her ses at vareklassen implementerer interfacet IVaredata // ************ Attributter ************ private long varenr; private string betegnelse; private double pris; private uint beholdning; Vare-klassen implementerer interfacet IVaredata: // interface: bruges til at sørge for, at andre dele af programmet kun kan læse et objekts data, men ikke rette/slette dem interface IVaredata
Eksempel: et ordresystem note 5 Lagdeling s. 9 long Varenr get; string Betegnelse get; double Pris get; uint Beholdning get; OrdreCollection-klassen er lavet efter samme princip som VareCollection-klassen. Ordre-klassen er creator for ordrelinierne, dvs. at klassen udover attributterne også har aggregeret ordrelinierne op i sig. OrdreCollection-klassen implementerer interfacet IOrdredata: class Ordre : IOrdredata private int ordrenr; private DateTime ordredato; private DateTime leveringsdato; private bool plukket; private List<Ordrelinie> ordrelinier; // aggregering af ordrelinier // Konstruktør public Ordre(int ordrenr, DateTime ordredato, DateTime leveringsdato) this.ordrenr = ordrenr; this.ordredato = ordredato; this.leveringsdato = leveringsdato; plukket = false; ordrelinier = new List<Ordrelinie>(); // Skab ordrelinie-list // interface: bruges til at sørge for, at andre dele af programmet kun kan læse et objekts data, men ikke rette/slette dem interface IOrdredata DateTime LeveringsDato get; DateTime OrdreDato get; int Ordrenr get; Ordrelinie-klassen er associeret til én vare og implementerer interfacet IOrdreliniedata: class Ordrelinie private int antal; private Vare vare; // Associéring til vare public void TilknytVare(Vare vare) this.vare = vare; // antallet af varer på ordrelinien // associéring til én vare
Eksempel: et ordresystem note 5 Lagdeling s. 10 public Vare GetVare() return vare; // get associeret vare interface IOrdreliniedata int Antal get; Vare Vare get; I note 3 brugte vi en hjemmelavet iterator i VareCollection. Den skulle sende én vare ad gangen op i GUI I denne version af programmet benyttes to iteratorer af typen IEnumerator, som findes i.net. En iterator over varerne og en iterator over ordrelinierne på en ordre. Vare-iteratoren hentes (via controlleren) vha. metoden GetVareIterator, som ligger på VareCollection-klassen. Metoden returnerer interfacet IEnumerator, som har iterator-metoderne Reset og MoveNext samt property en Current: using System.Collections; // skal bruges til IEnumerator class VareCollection public IEnumerator GetVareIterator() return varer.getenumerator(); // varer (List<T> implementerer Ienumerator og kan // derfor returnere den videre via metoden // GetEnumerator() I brugergrænsefladen bruges iteratoren således (husk at tilføje Using directivet): // Udskriver lagerliste private void btnvislagerliste_click(object sender, EventArgs e) IVaredata varedata; IEnumerator vareiterator = frisørsystem.getvareenumerator(); vareiterator.reset(); // Sæt iterator til at pege før første element while (vareiterator.movenext()) // så længe der er varer varedata = (IVaredata)vareiterator.Current; // læs aktuel vare // Udskriv vare txtlagerliste.text += string.format(format, varedata.varenr, varedata.betegnelse, varedata.pris, varedata.beholdning) + "\r\n"; FrisørSystem skal også modificeres, for ellers virker frisørsystem.getvareenumerator() ikke: public IEnumerator GetVareEnumerator()
Eksempel: et ordresystem note 5 Lagdeling s. 11 return varecol.getvareiterator(); Ligesom Vare-klassen har Ordre-klassen en iterator over ordrelinierne, som fungerer på samme vis.
Eksempel: et ordresystem note 5 Lagdeling s. 12 Iteration I. Use case: Modtag varer System-sekvens-diagram for Modtag varer Operationskontrakt for FindVarenumre varenumre=findvarenumre() Use cases: Modtag varer, Afhold status, Modtag ordre Pre: ingen Post: uændret Output: varenumrene vises på skærmen Sekvensdiagram for FindVarenumre
Eksempel: et ordresystem note 5 Lagdeling s. 13 Kode for FindVarenumre UI: List<long> varenumre = frisørsystem.findvarenumre(); FrisørSystem: public List<long> FindVarenumre() return varecol.getvarenumre(); VareCollection: // returnerer liste med varenumre public List<long> GetVarenumre() List<long> varenumre = new List<long>(); foreach (Vare vare in varer) varenumre.add(vare.varenr); return varenumre;
Eksempel: et ordresystem note 5 Lagdeling s. 14 Operationskontrakt for FindVare vare=findvare(varenr) Use cases: Modtag varer, Afhold status, Modtag Ordre Pre: Varen med varenr findes Post: uændret Output: varen vises på skærmen Sekvensdiagram for FindVare :FrmVare frisørsystem:frisørsystem varecol:varecollection :Vare vare = FindVare(varenr) vare = FindVare(varenr) loop [Varenr er forskellig fra aktueltvarenr ] aktueltvarenr = Varenr Kode for FindVare UI (user interface): Vare vare = varecol.findvare(varenr); FrisørSystem: public Vare FindVare(long varenr) return varecol.findvare(varenr); VareCollection: // Finder og returnerer varen udfra varenr public Vare FindVare(long varenr) int i = 0; long aktueltvarenr = varer[i].varenr; while (varenr!= aktueltvarenr) i++; aktueltvarenr = varer[i].varenr; return varer[i]; Vare: public long Varenr get return varenr;
Eksempel: et ordresystem note 5 Lagdeling s. 15 public string Betegnelse get return betegnelse; public double Pris get return pris; public uint Beholdning get return beholdning; NB: her har jeg sat get Properties på alle attributter, fordi vi kalder dem fra FrmVare Operationskontrakt for TilføjVare TilføjVare(varenr, betegnelse, pris) Use cases: Modtag varer Pre: varen med varenr findes ikke Post: en vare med varenr, betegnelse og pris og en beholdning på 0 er oprettet Sekvensdiagram for TilføjVare :UI TilføjVare(varenr, betegnelse, pris) frisørsystem:frisørsystem varecol:varecollection TilføjVare(varenr, betegnelse, pris) <<create>>(varenr, betegnelse, pæris :Vare Varen tilføjes listen Kode for TilføjVare UI: frisørsystem.tilføjvare(varenr, betegnelse, pris); Frisørsystem public void TilføjVare(long varenr, string betegnelse, double pris) varecol.tilføjvare(varenr, betegnelse, pris);
Eksempel: et ordresystem note 5 Lagdeling s. 16 VareCollection: // Tilføjer vare public void TilføjVare(long varenr, string betegnelse, double pris) Vare vare = new Vare(varenr, betegnelse, pris); varer.add(vare); Vare: public Vare(long varenr, string betegnelse, double pris) this.varenr = varenr; this.betegnelse = betegnelse; this.pris = pris; this.beholdning = 0; Operationskontrakt for ModtagVarer nybeholdning=modtagvare(varenr, antal) Use cases: Modtag varer pre: en vare med varenr findes post: antallet af modtagne varer er lagt til varens beholdning output: ny beholdning vises på skærmen Sekvensdiagram for ModtagVarer :UI frisørsystem:frisørsystem varecol:varecollection nybeholdning = modtagvarer(varenr, antal) nybeholdning = modtagvarer(varenr, antal) vare = FindVare(varenr) :Vare beholdning = ModtagVarer(antal) NB: Findvare(varenr) er vist tidligere Kode for ModtagVarer FrmVare: uint nybeholdning = frisørsystem.modtagvarer(varenr, antal);// Modtag varer Frisørsystem: public uint ModtagVarer(long varenr, int antal)
Eksempel: et ordresystem note 5 Lagdeling s. 17 return varecol.modtagvarer(varenr, antal); VareCollection: public uint ModtagVarer(long varenr, uint antal) Vare vare = FindVare(varenr); uint beholdning = vare.modtagvarer(antal); return beholdning; Vare: public uint ModtagVarer(uint antal) beholdning += antal; return beholdning;
Eksempel: et ordresystem note 5 Lagdeling s. 18 Iteration II. Use case: Afhold status System-sekvens-diagram for Afhold status
Eksempel: et ordresystem note 5 Lagdeling s. 19 Operationskontrakt for FjernVare FjernVare(varenr) Use cases: Afhold status pre: en vare med varenr findes i systemet post: varen er slettet output: ingen Sekvensdiagram for FjernVare :UI frisørsystem:frisørsystem varecol:varecollection :Vare FjernVare(varenr) FjernVare(varenr) vare = FindVare(varenr) <<destroy>> Kode for FjernVare UI: frisørsystem.fjernvare(varenr); Frisørsystem: public void FjernVare(long varenr) varecol.fjernvare(varenr); VareCollection: // Fjerner vare med varenr public void FjernVare(long varenr) Vare vare = FindVare(varenr); varer.remove(vare); Vare: Ingen kode.
Eksempel: et ordresystem note 5 Lagdeling s. 20 Operationskontrakt for VisLagerliste lagerliste = VisLagerliste() Use cases: Afhold status pre: ingen post: uændret output: Lagerlisten vises på skærmen. Operationen laves vha en iterator på VareCollection, derfor vises ingen sekvensdiagram.
Eksempel: et ordresystem note 5 Lagdeling s. 21 Operationskontrakt for JusterVare JusterVare(varenr, betegnelse, pris) Use cases: Afhold status pre: et vare-objekt med varenr findes i systemet post: betegnelse og pris er justeret på varen output: ingen Sekvensdiagram for JusterVare :UI frisørsystem:frisørsystem varecol:varecollection Justervare(varenr, betegnelse, pris) Justervare(varenr, betegnelse, pris) vare = FindVare(varenr) vare:vare Betegnelse=betegnelse Pris= pris Kode for JusterVare UI: frisørsystem.justervare(varenr, betegnelse, pris); Frisørsystem: public void JusterVare(long varenr, string betegnelse, double pris) varecol.justervare(varenr, betegnelse, pris); Vare: public string Betegnelse set betegnelse = value; public double Pris set pris = value; NB: her har jeg sat set properties på Pris og Betegnelse fordi de skal kunne rettes
Eksempel: et ordresystem note 5 Lagdeling s. 22 Iteration III. Use case: Lav regnskab System-sekvens-diagram for Lav regnskab Operationskontrakt for VisLagerbinding lagerbinding=vislagerbinding() Use cases: Lav regnskab pre: ingen post: uændret output: Den samlede lagerbinding vises på skærmen. Lagerbindingen for en vare er varens antal * pris, og den samlede lagerbinding er summen af lagerbindingen på hver af varerne. Sekvensdiagram for VisLagerbinding :UI frisørsystem:frisørsystem varecol:varecollection vare:vare lagerbinding = Vislagerbinding() lagerbinding = VisLagerbinding() loop varebinding = BeregnVarebinding() [så længe der er varer] Kode for VisLagerbinding UI: double lagerbinding = frisørsystem.vislagerbinding(); FrisørSystem: public double VisLagerbinding() return varecol.vislagerbinding(); VareCollection: public double VisLagerbinding()
Eksempel: et ordresystem note 5 Lagdeling s. 23 double lagerbinding = 0.0; double varebinding; foreach (Vare vare in varer) varebinding = vare.beregnvarebinding(); lagerbinding += varebinding; return lagerbinding; Vare: public double BeregnVarebinding() return beholdning * pris;
Eksempel: et ordresystem note 5 Lagdeling s. 24 Iteration IV. Use case: Modtag ordre System-sekvens-diagram for Modtag Ordre
Eksempel: et ordresystem note 5 Lagdeling s. 25 Operationskontrakt for RegistrerOrdre RegistrerOrdre(ordrenr, ordredato, leveringsdato) Use cases: Modtag Ordre pre: Ordre-objekt med ordrenr findes ikke i forvejen post: Der er oprettet et ordre-objekt med ordrenr, ordredato, leveringsdato og plukket lig false samt en tom ordrelinieliste output: Sekvensdiagram for RegistrerOrdre Kode for RegistrerOrdre UI: frisørsystem.registrerordre(ordrenr, ordredato, leveringsdato); Frisørsystem: public void RegistrerOrdre(int ordrenr, DateTime ordredato, DateTime leveringsdato) ordrecol.opretordre(ordrenr, ordredato, leveringsdato); OrdreCollection: public void OpretOrdre(int ordrenr, DateTime ordredato, DateTime leveringsdato) Ordre ordre = new Ordre(ordrenr, ordredato, leveringsdato); ordrer.add(ordre); Ordre: public Ordre(int ordrenr, DateTime ordredato, DateTime leveringsdato) this.ordrenr = ordrenr; this.ordredato = ordredato; this.leveringsdato = leveringsdato; plukket = false; ordrelinier = new List<Ordrelinie>(); // Skab ordrelinie-list
Eksempel: et ordresystem note 5 Lagdeling s. 26 Operationskontrakt for RegistrerOrdrelinie RegistrerOrdrelinie(ordrenr, varenr, antal) Use cases: Modtag Ordre pre: Ordre-objekt med ordrenr samt vare-objekt med varenr findes i forvejen post: Der er oprettet et ordrelinie-objekt med antal, som er aggregeret op i ordre-objektet (med ordrenr) og associeret til vare-objektet (med varenr) output: Sekvensdiagram for RegistrerOrdrelinie Kode for RegistrerOrdrelinie UI: frisørsystem.registrerordrelinie(ordrenr, varenr, antal); Frisørsystem: public void RegistrerOrdrelinie(int ordrenr, long varenr, int antal) Vare vare = varecol.findvare(varenr); ordrecol.opretordrelinie(ordrenr, vare, antal); OrdreCollection: public void OpretOrdrelinie(int ordrenr, Vare vare, int antal) Ordre ordre = FindOrdre(ordrenr); ordre.opretordrelinie(vare, antal); public void OpretOrdrelinie(int ordrenr, Vare vare, int antal) Ordre ordre = FindOrdre(ordrenr);
Eksempel: et ordresystem note 5 Lagdeling s. 27 ordre.opretordrelinie(vare, antal); public Ordre FindOrdre(int ordrenr) foreach (Ordre minordre in ordrer) if (minordre.ordrenr == ordrenr) return minordre; return null; Ordre: public void OpretOrdrelinie(Vare vare, int antal) Ordrelinie ordrelinie; ordrelinie = new Ordrelinie(antal); // skab ordrelinie ordrelinie.tilknytvare(vare); // tilknyt vare til ordrelinie ordrelinier.add(ordrelinie); // placer ordrelinie i liste public long Ordrenr get return ordrenr; Ordrelinie: public Ordrelinie(int antal) this.antal = antal; // Associéring til vare public void TilknytVare(Vare vare) this.vare = vare; public long Ordrenr get return ordrenr;
Eksempel: et ordresystem note 5 Lagdeling s. 28 Iteration V. Use case: Ekspedér ordre System-sekvens-diagram for Ekspedér Ordre
Eksempel: et ordresystem note 5 Lagdeling s. 29 Operationskontrakt for FindordrenumreEksp ordrenumre = FindordrenumreEksp() Use cases: Ekspeder Ordre pre: ingen post: ingen output: En liste med ordrenumre, hvis ordrer er klar til at blive ekspederet, dvs hvor leveringsdatoen er nået (eller overskredet) og som ikke er plukket. Kode for FindordrenumreEksp UI: List<int> ordrenumreeksp = frisørsystem.findordrenumreeksp(); Frisørsystem: public List<int> FindOrdrenumreEksp() return ordrecol.findordrenumreeksp(); OrdreCollection: public List<int> FindOrdrenumreEksp() List<int> ordrenumre = new List<int>(); foreach (Ordre ordre in ordrer) if (ordre.skalekspederes()) ordrenumre.add(ordre.ordrenr); return ordrenumre;
Eksempel: et ordresystem note 5 Lagdeling s. 30 Ordre: public bool SkalEkspederes() return (DateTime.Now.CompareTo(leveringsdato) >= 0) &&!plukket; public int Ordrenr get return ordrenr; Operationskontrakt for FindOrdre ordre = FindOrdre(ordrenr) Use cases: Ekspeder Ordre, Modtag Ordre pre: Ordre-objekt med ordrenr findes post: ingen output: Ordre. Operationen er analog med operationen FindVare, derfor vises ingen sekvensdiagram. Operationskontrakt for VisOrdrelinier(ordrenr) ordrerlinier = VisOrdrelinier(ordrenr) Use cases: Ekspeder Ordre pre: Ordre-objekt med ordrene findes post: ingen output: Ordrelinier med vareinformationer. Operationen laves vha en iterator over ordrelinier, derfor vises ingen sekvensdiagram.
Eksempel: et ordresystem note 5 Lagdeling s. 31 Operationskontrakt for KanEkspederes kanekspederes = KanEkspederes(ordrenr) Use cases: Ekspeder Ordre pre: ingen post: ingen output: En boolsk værdi, som fortæller om ordren med ordrenr kan ekspederes, dvs. om der er varer nok på lageret til alle ordrelinierne. NB: vare.getbeholdning() hedder vare.beholdning Kode for KanEkspederes UI: kanekspederes = frisørsystem.kanekspederes(ordrenr); Frisørsystem: public bool KanEkspederes(int ordrenr) return ordrecol.kanekspederes(ordrenr); OrdreCollection: public bool KanEkspederes(int ordrenr) Ordre ordre = FindOrdre(ordrenr); return ordre.kanekspederes();
Eksempel: et ordresystem note 5 Lagdeling s. 32 Ordre: public bool KanEkspederes() foreach (Ordrelinie ordrelinie in ordrelinier) if (!ordrelinie.kanekspederes()) return false; return true; Ordrelinie: public bool KanEkspederes() return (antal <= vare.beholdning); Vare: public int Beholdning get return beholdning;
Eksempel: et ordresystem note 5 Lagdeling s. 33 Operationskontrakt for EkspederOrdre EkspedererOrdre (ordrenr) Use cases: Ekspeder Ordre pre: Ordren skal findes og skal kunne ekspederes, se operationen KanEkspederes post: Varebeholdningen er nedskrevet med antal for alle ordrelinier output: Kode for EkspedererOrdre UI: frisørsystem.ekspederordre(ordrenr); Frisørsystem: public void EkspederOrdre(int ordrenr) ordrecol.ekspederordre(ordrenr); OrdreCollection: public void EkspederOrdre(int ordrenr) Ordre ordre = FindOrdre(ordrenr); ordre.ekspederordre(); Ordre: public void EkspederOrdre() foreach (Ordrelinie ordrelinie in ordrelinier) ordrelinie.ekspederordrelinie(); plukket = true;
Eksempel: et ordresystem note 5 Lagdeling s. 34 Ordrelinie: public void EkspederOrdrelinie() vare.plukvarer((uint)antal); Vare: public void PlukVarer(uint antal) beholdning -= antal;
Eksempel: et ordresystem note 5 Lagdeling s. 35 Iteration I. Use case: Planlæg indkøb System-sekvens-diagram for Planlæg indkøb
Eksempel: et ordresystem note 5 Lagdeling s. 36 Designmodel Her er vist et Designklassediagram med de metoder, sekvensdiagrammerne fører til.