kapitlet går igenom sju problem som måste åtgärdas för att korrekt utforma Lexi, inklusive eventuella begränsningar som måste följas. Varje problem analyseras på djupet och lösningar föreslås., Varje lösning förklaras i sin helhet, inklusive pseudo-kod och en något modifierad version av Objektmodelleringsteknik där så är lämpligt.
slutligen är varje lösning associerad direkt med ett eller flera designmönster. Det visas hur lösningen är ett direkt genomförande av det designmönstret.
de sju problemen (inklusive deras begränsningar) och deras lösningar (inklusive mönstret(mönstren) som refereras) är följande:
Document StructureEdit
dokumentet är ”ett arrangemang av grundläggande grafiska element” som tecken, linjer, andra former etc.,, att ”fånga den totala informationsinnehållet i dokumentet” (s. 35). Dokumentets struktur innehåller en samling av dessa element, och varje element kan i sin tur vara en understruktur av andra element.
problem och begränsningar
- Text och grafik bör behandlas på samma sätt (det vill säga grafik är inte en härledd instans av text, eller vice versa)
- genomförandet bör behandla komplexa och enkla strukturer på samma sätt. Det borde inte behöva veta skillnaden mellan de två.,
- specifika derivat av abstrakta element bör ha specialiserade analyselement.
lösning och mönster
en rekursiv komposition är en hierarkisk struktur av element, som bygger ”alltmer komplexa element av enklare” (S.36). Varje nod i strukturen känner till sina egna barn och dess förälder. Om en operation ska utföras på hela strukturen, kallar varje nod operationen på sina barn (rekursivt).
detta är en implementering av det sammansatta mönstret, vilket är en samling noder., Noden är en abstrakt basklass, och derivat kan antingen vara löv (singular) eller samlingar av andra noder (som i sin tur kan innehålla löv eller samlingsnoder). När en operation utförs på den överordnade skickas den åtgärden rekursivt ner i hierarkin.
FormattingEdit
formatering skiljer sig från struktur. Formatering är en metod för att konstruera en viss instans av dokumentets fysiska struktur. Detta inkluderar att bryta text i rader, använda bindestreck, justera för marginalbredder etc.,
problem och begränsningar
- balans mellan (formatering) kvalitet, hastighet och lagringsutrymme
- Håll formateringen oberoende (frikopplad) från dokumentstrukturen.
lösning och mönster
en Kompositörsklass kommer att inkapsla algoritmen som används för att formatera en komposition. Compositor är en underklass av det primitiva objektet i dokumentets struktur. En kompositör har en associerad instans av ett Kompositionsobjekt., När en kompositör kör sinCompose()
, itererar den genom varje element i dess associerade sammansättning och omarrangerar strukturen genom att infoga rad-och Kolumnobjekt efter behov.
kompositören själv är en abstrakt klass, vilket gör det möjligt för derivatklasser att använda olika formateringsalgoritmer (t.ex. dubbelavstånd, bredare marginaler etc.)
Strategimönstret används för att uppnå detta mål. En strategi är en metod för att inkapsla flera algoritmer som ska användas baserat på en föränderlig sammanhang., I det här fallet bör formateringen vara annorlunda beroende på om text, grafik, enkla element etc. är formateras.
försköna användargränssnittet
möjligheten att ändra det grafiska gränssnittet som användaren använder för att interagera med dokumentet.,
problem och begränsningar
- avgränsa en sida med text med en kant runt redigeringsområdet
- rullningslister som låter användaren visa olika delar av sidan
- användargränssnitt objekt bör inte veta om utsmyckningar
- Undvik en ”explosion av klasser” som skulle orsakas av underklassificering för ”varje möjlig kombination av utsmyckningar” och element (s. 44)
lösning och mönster
p >
användningen av ett genomskinligt hölje gör det möjligt att lägga till element som förstärker kompositionens beteende i en komposition., Dessa element, såsom gräns och Scroller, är speciella underklasser av det singulära elementet själv. Detta gör att kompositionen kan ökas och effektivt lägga till statsliknande element. Eftersom dessa förstärkningar är en del av strukturen anropas deras lämpliga Operation()
när strukturens Operation()
anropas. Det innebär att kunden inte behöver någon speciell kunskap eller gränssnitt med strukturen för att kunna använda utsmyckningarna.,
detta är en dekoratör mönster, en som lägger ansvar för ett objekt utan att ändra själva objektet.
stöd för flera utseende och känsla StandardsEdit
Look-and-feel refererar till plattformsspecifika UI-standarder. Dessa standarder ”definierar riktlinjer för hur applikationer visas och reagerar på användaren” (s.47).
problem och begränsningar
- redaktören måste implementera standarder för flera plattformar så att den är bärbar
- enkelt anpassa sig till nya och framväxande standarder
- tillåta run-time förändring av utseende och känsla (dvs.,: Ingen hårdkodning)
- har en uppsättning abstrakta elementära underklasser för varje kategori av element (rullningslist, knappar, etc.)
- har en uppsättning konkreta underklasser för varje abstrakt underklass som kan ha ett annat utseende och känsla standard. (ScrollBar har MotifScrollBar och PresentationScrollBar för motiv och Presentation look-and-feels)
lösning och mönster
eftersom objektskapande av olika konkreta objekt inte kan göras vid körning måste objektskapningsprocessen abstraheras., Detta görs med en abstrakt guiFactory, som tar på sig ansvaret för att skapa UI-element. Den abstrakta guiFactory har konkreta implementationer, som MotifFactory, vilket skapar konkreta element av lämplig typ (MotifScrollBar). På så sätt behöver programmet bara be om en rullningslist och vid körning kommer det att ges rätt konkret element.
detta är en abstrakt fabrik. En vanlig fabrik skapar konkreta föremål av en typ. En abstrakt fabrik skapar konkreta föremål av olika slag, beroende på det konkreta genomförandet av fabriken själv., Dess förmåga att fokusera på inte bara konkreta föremål, utan hela familjer av konkreta föremål ”skiljer det från andra kreationsmönster, som bara involverar ett slags produktobjekt” (s.51).
stödja flera fönster SystemsEdit
precis som look-and-feel är olika mellan plattformar, så är metoden för hantering av windows. Varje plattform visar, lägger ut, hanterar ingång till och utgång från och lager fönster annorlunda.,
problem och begränsningar
- dokumentredigeraren måste köras på många av de ”viktiga och till stor del inkompatibla fönstersystem” som finns (s. 52)
- en abstrakt fabrik kan inte användas. På grund av olika standarder kommer det inte att finnas en gemensam abstrakt klass för varje typ av widget.
- skapa inte ett nytt, icke-standardiserat fönstersystem
lösning och mönster
det är möjligt att utveckla ”våra egna abstrakta och konkreta produktklasser”, eftersom ”alla fönstersystem gör i allmänhet samma sak” (s. 52)., Varje fönstersystem tillhandahåller operationer för att rita primitiva former, ikonifying/de-iconifying, resizing och uppfriskande fönsterinnehåll.
en abstrakt basWindow
– klass kan härledas till de olika typerna av befintliga fönster, till exempel program, ikonifierad dialogruta. Dessa klasser kommer att innehålla operationer som är associerade med windows, såsom omformning, grafiskt uppfriskande, etc. Varje fönster innehåller element, vars Draw()
funktioner anropas av funktionerna Window
egen draw-relaterade funktioner.,
för att undvika att behöva skapa plattformsspecifika Fönsterunderklasser för alla möjliga plattformar, kommer ett gränssnitt att användas. KlassenWindow
implementerar enWindow
– implementering (WindowImp
) abstrakt klass. Denna klass kommer då i sin tur att härledas till flera plattformsspecifika implementeringar, var och en med plattformsspecifika operationer., Därför behövs endast en uppsättning Window
klasser för varje typ av Window
, och endast en uppsättning WindowImp
klasser behövs för varje plattform (snarare än den kartesiska produkten av alla tillgängliga typer och plattformar). Dessutom behöver inte lägga till en ny fönstertyp någon ändring av plattformsimplementering, eller vice versa.
detta är ett Bromönster. Window
ochWindowImp
är olika, men relaterade., Window
handlar om fönsterläggning i programmet, och WindowImp
handlar om fönsterläggning på en plattform. En av dem kan förändras utan att någonsin behöva ändra den andra. Bromönstret gör det möjligt för dessa två ”separata klasshierarkier att arbeta tillsammans även när de utvecklas självständigt” (s.54).
User OperationsEdit
alla åtgärder som användaren kan vidta med dokumentet, allt från att skriva in text, ändra formatering, sluta, spara etc.,
problem och begränsningar
- operationer måste nås via olika ingångar, till exempel ett menyalternativ och en tangentbordsgenväg för samma kommando
- varje alternativ har ett gränssnitt, vilket bör vara modifierbart
- operationer implementeras i flera olika klasser
- för att undvika koppling får det inte finnas många beroenden mellan implementering och användargränssnittsklasser.,
- Ångra och gör om kommandon måste stödjas på de flesta dokumentbytesoperationer, utan någon godtycklig gräns för antalet nivåer av ångra
- funktioner är inte genomförbara, eftersom de inte ångra / gör om lätt, är inte lätt associerade med ett tillstånd, och är svåra att förlänga eller återanvända.
- menyer bör behandlas som hierarkiska kompositstrukturer. Därför är en meny ett menyalternativ som innehåller menyalternativ som kan innehålla andra menyalternativ etc.,
lösning och mönster
Varje menyalternativ, snarare än att instansieras med en lista med parametrar, görs istället med ett Kommandoobjekt.
kommandot är ett abstrakt objekt som bara har en enda abstraktExecute()
metod. Derivatobjekt förlängerExecute()
– metoden på lämpligt sätt (dvs. PasteCommand.Execute()
skulle använda innehållets urklippsbuffert). Dessa objekt kan användas av widgets eller knappar lika enkelt som de kan användas av menyalternativ.,
för att stödja ångra och gör om,Command
ges ocksåUnexecute()
ochReversible()
. I derivatklasser innehåller den förstnämnda kod som kommer att ångra det kommandot, och den senare returnerar ett booleskt värde som definierar om kommandot är omöjligt. Reversible()
tillåter att vissa kommandon inte kan återställas, t.ex. ett Spara-kommando.
alla utfördaCommands
hålls i en lista med en metod för att hålla en ”närvarande” markör direkt efter det senast utförda kommandot., En begäran om att ångra kommer att ringaCommand.Unexecute()
direkt före ”present” och sedan flytta ”present” tillbaka ett kommando. Omvänt kommer enRedo
– begäran att ringaCommand.Execute()
efter ”present” och flytta ”present” framåt en.
dettaCommand
tillvägagångssätt är en implementering av Kommandomönstret. Det inkapslar förfrågningar i objekt, och använder ett gemensamt gränssnitt för att komma åt dessa förfrågningar. Således kan klienten hantera olika förfrågningar, och kommandon kan spridas i hela programmet.,
stavningskontroll och avstavning
det här är dokumentredigerarens förmåga att textuellt analysera innehållet i ett dokument. Även om det finns många analyser som kan utföras, stavningskontroll och avstavning-formatering är fokus.
problem och begränsningar
- tillåta flera sätt att kontrollera stavning och identifiera platser för avstavning
- tillåta expansion för framtida analys (t. ex. ordräkning, grammatikkontroll)
- kunna iterera genom en Texts innehåll utan tillgång till textens faktiska struktur (t. ex.,, array, linked list, string)
- Tillåt för alla typer av traversering av dokument (börjar till slut, slutar till början, alfabetisk ordning, etc.)
lösning och mönster
att ta bort heltalsbaserat index från grundelementet gör det möjligt att implementera ett annat iterationsgränssnitt. Detta kommer att kräva extra metoder för traversal och object retrieval. Dessa metoder sätts in i ett abstraktIterator
gränssnitt., Varje element implementerar sedan en härledning avIterator
, beroende på hur det elementet behåller sin lista (ArrayIterator
,LinkListIterator
, etc.).
funktioner för korsning och hämtning sätts in i det abstrakta iteratorgränssnittet. Framtida iteratorer kan härledas baserat på vilken typ av Lista de kommer att iterera igenom, till exempel Arrays eller länkade listor. Således, oavsett vilken typ av indexeringsmetod någon implementering av elementet använder, kommer det att ha lämplig Iterator.
detta är en implementering av Iteratormönstret., Det gör det möjligt för kunden att passera genom någon objektsamling, utan att behöva komma åt innehållet i samlingen direkt, eller vara oroad över vilken typ av lista samlingens struktur använder.
nu när traversal har hanterats är det möjligt att analysera elementen i en struktur. Det är inte möjligt att bygga varje typ av analys i elementstrukturen själva; varje element skulle behöva kodas, och mycket av koden skulle vara densamma för liknande element.
istället är en generiskCheckMe()
– metod inbyggd i elementets abstrakta klass., Varje Iterator ges en hänvisning till en specifik algoritm (t.ex. stavningskontroll, grammatikkontroll etc.). När Iteratorn itererar genom sin samling, anropar det varje Elements CheckMe
, som passerar den angivna algoritmen. CheckMe
skickar sedan en referens till dess element tillbaka till nämnda algoritm för analys.
För att utföra en stavningskontroll skulle en front-to-end-iterator få en hänvisning till ett SpellCheck
– objekt., Iteratorn skulle sedan komma åt varje element och köra dessCheckMe()
– metod medSpellCheck
– parameter. VarjeCheckMe
skulle då ringaSpellCheck
och skicka en referens till lämpligt element.
På detta sätt kan vilken algoritm som helst användas med vilken traversalmetod som helst, utan hårdkodskoppling med den ena med den andra. Till exempel kan hitta användas som” Hitta nästa ”eller” hitta föregående”, beroende på om en” framåt ”- iterator användes eller en” bakåt ” – iterator.,
dessutom kan algoritmerna själva vara ansvariga för att hantera olika element. Till exempel skulle enSpellCheck
-algoritm ignorera ettGraphic
– element, snarare än att behöva programmera varjeGraphic
– härlett element för att inte skicka sig till ettSpellCheck
.