capitolul trece prin șapte probleme care trebuie abordate pentru a proiecta corect Lexi, inclusiv orice constrângeri care trebuie urmate. Fiecare problemă este analizată în profunzime și sunt propuse soluții., Fiecare soluție este explicată în întregime, inclusiv pseudo-cod și o versiune ușor modificată a tehnicii de modelare obiect, dacă este cazul.în cele din urmă, fiecare soluție este asociată direct cu unul sau mai multe modele de design. Se arată modul în care soluția este o implementare directă a acestui model de proiectare.
Cele șapte probleme (inclusiv constrângerile lor) și soluțiile lor (inclusiv model(e) de referință), sunt după cum urmează:
Document Structurămodificare
documentul este „un aranjament de bază elemente grafice”, cum ar fi caractere, linii, alte forme, etc.,, care „captează conținutul informațional total al documentului” (PP.35). Structura documentului conține o colecție a acestor elemente și fiecare element poate fi, la rândul său, o substructură a altor elemente.
probleme și constrângeri
- textul și grafica ar trebui tratate în același mod (adică grafica nu este o instanță derivată a textului și nici invers)
- implementarea ar trebui să trateze structurile complexe și simple în același mod. Nu ar trebui să știe diferența dintre cele două.,derivatele specifice ale elementelor abstracte ar trebui să aibă elemente analitice specializate.o compoziție recursivă este o structură ierarhică a elementelor, care construiește” elemente din ce în ce mai complexe din cele mai simple ” (PP.36). Fiecare nod din structură cunoaște propriii copii și părintele său. Dacă o operație trebuie efectuată pe întreaga structură, fiecare nod apelează operația pe copiii săi (recursiv).aceasta este o implementare a modelului compozit, care este o colecție de noduri., Nodul este o clasă de bază abstractă, iar derivatele pot fi fie frunze (singulare), fie colecții de alte noduri (care la rândul lor pot conține frunze sau noduri de colectare). Când o operație este efectuată asupra părintelui, acea operație este transmisă recursiv în jos în ierarhie.
Formatingedit
formatarea diferă de structură. Formatarea este o metodă de construire a unei anumite instanțe a structurii fizice a documentului. Aceasta include ruperea textului în linii, utilizarea cratimelor, ajustarea lățimii marjei etc.,
probleme și constrângeri
- echilibru între (formatare) calitate, viteză și spațiu de stocare
- mențineți formatarea independentă (decuplată) de structura documentului.
soluție și model
o clasă de compozitoare va încapsula algoritmul folosit pentru a formata o compoziție. Compozitorul este o subclasă a obiectului primitiv al structurii documentului. Un compozitor are o instanță asociată a unui obiect de compoziție., Când un compozitor execută
Compose()
, iterează prin fiecare element al compoziției sale asociate și rearanjează structura prin inserarea obiectelor rând și coloană după cum este necesar.compozitorul în sine este o clasă abstractă, permițând claselor derivate să utilizeze diferiți algoritmi de formatare (cum ar fi spațiere dublă, margini mai largi etc.).)modelul de strategie este utilizat pentru a realiza acest obiectiv. O strategie este o metodă de încapsulare a mai multor algoritmi care urmează să fie utilizate pe baza unui context în schimbare., În acest caz, formatarea ar trebui să fie diferită, în funcție de text, grafică, elemente simple etc., sunt formatate.
înfrumusețarea interfeței cu Utilizatoruledit
posibilitatea de a schimba interfața grafică pe care utilizatorul o utilizează pentru a interacționa cu documentul.,
Probleme și Constrângeri
- Delimitează o pagină de text cu un chenar în jurul valorii de zona de editare
- bare de Defilare care permite utilizatorului de a vizualiza diferite părți ale paginii
- interfață de Utilizator obiecte nu ar trebui să știe despre ornamente
- Evita o „explozie de clase” care ar fi cauzat prin subclasarea pentru „fiecare combinație posibilă de ornamente” și elemente (p. 44)
Soluție și Model
utilizarea unei transparente cabina permite elemente care îmbunătățesc comportamentul de compoziție să fie adăugate la o compoziție., Aceste elemente, cum ar fi Border și Scroller, sunt subclase speciale ale elementului singular în sine. Acest lucru permite ca compoziția să fie mărită, adăugând în mod eficient elemente asemănătoare stării. Deoarece aceste măriri sunt parte din structura lor corespunzătoare
Operation()
va fi numit atunci când structura esteOperation()
se numește. Aceasta înseamnă că clientul nu are nevoie de cunoștințe speciale sau de interfață cu structura pentru a utiliza înfrumusețările.,acesta este un model de Decorator, unul care adaugă responsabilități unui obiect fără a modifica obiectul în sine.Sprijinirea mai multor standarde Look-and-Feeledit
Look-and-feel se referă la standardele UI specifice platformei. Aceste standarde ” definesc liniile directoare pentru modul în care aplicațiile apar și reacționează la utilizator „(PP. 47).
probleme și constrângeri
- editorul trebuie să implementeze standardele mai multor platforme, astfel încât să fie portabil
- să se adapteze cu ușurință la standardele noi și emergente
- permite schimbarea în timp a aspectului (adică.,: Nu hard-coding)
- au un set de subclase elementare abstracte pentru fiecare categorie de elemente (ScrollBar, butoane, etc.)
- au un set de subclase concrete pentru fiecare subclasă abstractă care poate avea un standard diferit de aspect și senzație. (ScrollBar având MotifScrollBar și PresentationScrollBar pentru Motif și Prezentarea look-și-simt)
Soluție și Model
De obiect crearea de diferite obiecte concrete nu se poate face la runtime, proces de creare obiect trebuie să fie captată., Acest lucru se face cu un guifactory abstract, care își asumă responsabilitatea de a crea elemente UI. Abstract guiFactory a betonului implementări, cum ar fi MotifFactory, care creează elemente de beton de tip corespunzător (MotifScrollBar). În acest fel, programul trebuie doar cere o bară de derulare și, la run-time, acesta va fi dat elementul de beton corect.
aceasta este o fabrică abstractă. O fabrică obișnuită creează obiecte concrete de un singur tip. O fabrică abstractă creează obiecte concrete de diferite tipuri, în funcție de implementarea concretă a fabricii în sine., Capacitatea de a se concentra nu doar obiecte concrete, ci familii întregi de obiecte concrete „se distinge de alte creatie modele, care implică doar un singur fel de produs, obiect” (p. 51).
Sprijinirea mai multor sisteme de Windowsedit
la fel cum aspectul este diferit pe platforme, la fel este și metoda de manipulare a windows. Fiecare platformă afișează, stabilește, se ocupă de intrare și de ieșire din, și straturi de ferestre diferit.,
probleme și constrângeri
- editorul de documente trebuie să ruleze pe multe dintre „sistemele de ferestre importante și în mare măsură incompatibile” care există (p. 52)
- o fabrică abstractă nu poate fi utilizată. Datorită standardelor diferite, nu va exista o clasă abstractă comună pentru fiecare tip de widget.
- nu creați un sistem de ferestre nou, nestandard
soluție și Model
este posibil să dezvoltăm „propriile noastre clase de produse abstracte și concrete”, deoarece „toate sistemele de ferestre fac în general același lucru” (p. 52)., Fiecare sistem de ferestre oferă operații pentru desenarea formelor primitive, iconificarea/de-iconificarea, Redimensionarea și reîmprospătarea conținutului ferestrei.
o bază abstractă
Window
clasa poate fi derivată la diferite tipuri de ferestre existente, cum ar fi application, iconified, dialog. Aceste clase vor conține operații care sunt asociate cu windows, cum ar fi remodelarea, reîmprospătarea grafică etc. Fiecare fereastră conține elemente ale căror funcțiiDraw()
sunt apelate de funcțiile propriiWindow
.,pentru a evita crearea subclaselor de ferestre specifice platformei pentru fiecare platformă posibilă, va fi utilizată o interfață.Window
class va pune în aplicare unWindow
punere în aplicare (WindowImp
) clasă abstractă. Această clasă va fi apoi derivată în mai multe implementări specifice platformei, fiecare cu operații specifice platformei., Prin urmare, doar un singur set deWindow
cursuri sunt necesare pentru fiecare tip deWindow
, și doar un singur set deWindowImp
cursuri sunt necesare pentru fiecare platformă (mai degrabă decât produsul Cartezian de toate tipurile disponibile și platforme). În plus, adăugarea unui nou tip de fereastră nu necesită nicio modificare a implementării platformei sau invers.acesta este un model de pod.Window
șiWindowImp
sunt diferite, dar înrudite.,Window
oferte cu ferestre în program, șiWindowImp
oferte cu ferestre pe o platformă. Una dintre ele se poate schimba fără a fi nevoie să o modifice pe cealaltă. Modelul de punte permite acestor două „ierarhii de clasă separate să lucreze împreună chiar și pe măsură ce evoluează independent” (p. 54).operațiuni Utilizatoredit
toate acțiunile pe care utilizatorul le poate lua cu documentul, de la introducerea textului, Schimbarea formatării, renunțarea, salvarea etc.,
Probleme și Constrângeri
- Operațiuni trebuie să fie accesate prin diferite intrări, cum ar fi o opțiune de meniu și o comandă rapidă de la tastatură pentru aceeași comandă
- Fiecare opțiune are o interfață, care ar trebui să fie modificabil
- Operațiuni sunt puse în aplicare în mai multe clase diferite
- În scopul de a evita cuplare, acolo nu trebuie să fie o mulțime de dependențe între punerea în aplicare și interfața cu utilizatorul clase.,
- Undo și redo comenzi trebuie să fie sprijinit pe majoritatea document schimbarea operațiuni, cu nici o limită arbitrară a numărului de niveluri de undo
- Funcțiile nu sunt viabile, deoarece acestea nu undo/redo cu ușurință, nu sunt ușor de asociat cu un stat, și sunt greu de a prelungi sau de reutilizare.meniurile trebuie tratate ca structuri compozite ierarhice. Prin urmare, un meniu este un element de meniu care conține elemente de meniu care pot conține alte elemente de meniu etc.,
soluție și Model
fiecare element de meniu, în loc să fie instanțiat cu o listă de parametri, se face în schimb cu un obiect de comandă.
comanda este un obiect abstract care are doar un singur abstract
Execute()
metodă. Derivate obiecte prelungiExecute()
metodă în mod corespunzător (de exemplu,PasteCommand.Execute()
va utiliza conținutul clipboard-tampon). Aceste obiecte pot fi folosite de widget-uri sau butoane la fel de ușor cum pot fi utilizate de elementele de meniu.,Pentru a sprijini undo și redo,
Command
este, de asemenea, datUnexecute()
șiReversible()
. În clasele derivate, prima conține cod care va anula acea comandă, iar cea de-a doua returnează o valoare booleană care definește dacă comanda este undoable.Reversible()
permite unele comenzi să fie non-undoable, cum ar fi o comandă de salvare.toate executate
Commands
sunt păstrate într-o listă cu o metodă de păstrare a unui marker” prezent ” imediat după cea mai recentă comandă executată., O cerere de anulare va apelaCommand.Unexecute()
direct înainte de „prezent”, apoi mutați „prezent” înapoi o comandă. În schimb, o solicitareRedo
va apelaCommand.Execute()
după” prezent „și va muta” prezent ” înainte.această abordare
Command
este o implementare a modelului de comandă. Acesta încapsulează cereri în obiecte, și utilizează o interfață comună pentru a accesa aceste cereri. Astfel, clientul poate gestiona diferite solicitări, iar comenzile pot fi împrăștiate în întreaga aplicație.,Verificare ortografică și Cratimeedit
aceasta este capacitatea editorului de documente de a analiza textual conținutul unui document. Deși există multe analize care pot fi efectuate, verificarea ortografică și formatarea prin cratimă sunt în centrul atenției.
Probleme și Constrângeri
- Permite mai multe moduri de a verifica ortografia și să identifice locuri de despărțire în silabe
- Permite extinderea pentru analiza viitoare (de exemplu, numărul de cuvinte, gramatica verificați)
- Fi capabil de a parcurge un text conținutul fără acces la textul efectiv structura (de exemplu,,, array, linked list, string)
- permite orice mod de traversare a documentului (început până la sfârșit, sfârșit până la început, ordine alfabetică etc.)
soluție și Model
eliminarea indexului bazat pe număr întreg din elementul de bază permite implementarea unei interfețe iterative diferite. Acest lucru va necesita metode suplimentare pentru traversare și regăsire obiect. Aceste metode sunt puse într-un abstract
Iterator
interfață., Fiecare element atunci implementează o derivare dinIterator
, în funcție de modul în care element își păstrează lista (ArrayIterator
,LinkListIterator
, etc.).funcții pentru traversare și regăsire sunt puse în interfața iterator abstract. Iteratorii viitori pot fi derivați pe baza tipului de listă pe care o vor itera, cum ar fi matrice sau liste legate. Astfel, indiferent de tipul de metodă de indexare pe care o folosește orice implementare a elementului, acesta va avea Iteratorul corespunzător.aceasta este o implementare a modelului Iterator., Acesta permite clientului să traverseze prin orice colecție obiect, fără a fi nevoie pentru a accesa conținutul colecției direct, sau să fie preocupat de tipul de listă structura colecției utilizează.acum, că traversal a fost manipulat, este posibil să se analizeze elementele unei structuri. Nu este posibil să se construiască fiecare tip de analiză în structura elementului în sine; fiecare element ar trebui să fie codificat și o mare parte din cod ar fi același pentru elemente similare.
În schimb, o metodă generică
CheckMe()
este încorporată în clasa abstractă a elementului., Fiecare Iterator este dat o referire la un algoritm specific (cum ar fi verificarea ortografică, verificare gramaticală, etc.). Când Iteratorul iterează prin colecția sa, apelează fiecare elementCheckMe
, trecând algoritmul specificat.CheckMe
apoi trece o referință la elementul său înapoi la algoritmul menționat pentru analiză.astfel ,pentru a efectua o verificare ortografică, un iterator front-to-end ar primi o referință la un obiectSpellCheck
., Iteratorul va accesa apoi fiecare element, executând metodaCheckMe()
cu parametrulSpellCheck
. FiecareCheckMe
ar apoi apelSpellCheck
, trece o referință la elementul potrivit.în acest mod, orice algoritm poate fi utilizat cu orice metodă de traversare, fără cuplare hard-Cod unul cu celălalt. De exemplu, Find poate fi folosit ca „find next” sau „find previous”, în funcție de dacă a fost folosit un iterator „forward” sau un iterator „backwards”.,în plus, algoritmii înșiși pot fi responsabili pentru tratarea diferitelor elemente. De exemplu, un
SpellCheck
algoritm ar ignora unGraphic
element, mai degrabă decât a fi nevoie să program în fiecareGraphic
derivate element să nu se trimite la unSpellCheck
.