všetky vzory

Twin

Nahradí viacnásobné dedenie párom objektov, ktoré sa navzájom držia.

class Teleso {  posun(dx, dy) { throw new Error('abstraktná metóda'); }} class Widget {  prekresli() { throw new Error('abstraktná metóda'); }} // Prvá polovica: patrí do sveta fyziky.class LoptaTeleso extends Teleso {  constructor() {    super();    this.dvojca = null;  }   posun(dx, dy) {    this.x += dx;    this.y += dy;    this.dvojca.prekresli();  }} // Druhá polovica: patrí do sveta kreslenia.class LoptaWidget extends Widget {  constructor() {    super();    this.dvojca = null;  }   prekresli() {    nakresliKruh(this.dvojca.x, this.dvojca.y);  }} const teleso = new LoptaTeleso();const widget = new LoptaWidget(); teleso.dvojca = widget;widget.dvojca = teleso;

Celý priebeh v texte (8 krokov)
  1. Lopta má byť dve veci naraz: teleso vo svete fyziky a widget vo svete kreslenia. Oba svety žiadajú, aby sa dedilo z ich základnej triedy — a jazyk dovolí dediť len z jednej.
  2. Vzor ju preto rozdelí na dvojicu. Prvá polovica dedí z Telesa a o kreslení nevie nič.
  3. Druhá dedí z Widgetu a nevie nič o fyzike. Sú to dva objekty dvoch rôznych tried, každý vo svojej hierarchii.
  4. A tu je vzor: držia sa navzájom. Nie jedna druhú, ale obe navzájom — lanká vedú oboma smermi a práve to z dvoch objektov robí jednu vec.
  5. Fyzika posunie loptu. Volá polovicu, ktorá je teleso — o tej druhej nevie a ani nemusí.
  6. Tá si zmenu spraví u seba a povie o nej svojmu dvojčaťu. Bez toho odkazu by sa to nemalo ako dozvedieť.
  7. Widget sa prekreslí na novej pozícii — a tú si vypýta od dvojčaťa, lebo sám ju nemá. Do sveta fyziky pritom nikdy nevstúpil.
  8. Navonok jedna lopta, vnútri dvojica. Každá polovica sedí vo svojom svete a ani jeden z tých svetov sa nemusel meniť. Cena je v tom lanku: polovice o sebe musia vedieť po celý život a nesmú sa rozísť — kto zruší jednu, musí zrušiť aj druhú.

Kedy použiť

  • Objekt musí patriť do dvoch hierarchií naraz a jazyk viacnásobné dedenie nemá. Rozdelenie na dvojicu je vtedy jediná cesta, ako splniť obe.
  • Dva rámce vyžadujú, aby ste dedili z ich základnej triedy. Každá polovica sa prihlási do svojho a ani jeden rámec sa nemusí meniť.
  • Dedenie sa nedá nahradiť delegovaním, lebo rámec žiada svoj typ. Keby stačilo správanie, stačil by pomocník — tu je potrebná príslušnosť k typu.
  • Jedna vec má dve odlišné role s vlastným stavom. Každá polovica si drží svoje a spoločne tvoria jeden celok.

Pasce

  • Dvojica sa musí držať pohromade po celý život. Kto zruší jednu polovicu a druhú nechá, dostane objekt, ktorý sa tvári funkčne, ale jeho dvojča ukazuje do prázdna.
  • Navonok to nevyzerá ako jedna vec. Volajúci musí vedieť, ktorú polovicu má v ruke, a niekedy si podávajú obe — čím sa stráca práve to zjednodušenie, kvôli ktorému vzor vznikol.
  • Vzájomné odkazy tvoria cyklus. Polovice sa držia navzájom, takže bez zásahu ich nemá kto uvoľniť a upratovanie prestáva byť samozrejmé.
  • Stav sa rozdelí zle a začne sa duplikovať. Keď obe polovice vedú vlastnú kópiu polohy, skôr či neskôr sa rozídu a nikto nevie, ktorá má pravdu.
  • Je to náhrada za chýbajúcu vlastnosť jazyka, nie návrhový zámer. Kde je viacnásobné dedenie alebo primiešavanie k dispozícii, je vzor zbytočná komplikácia.
  • Dvojica sa dá zameniť s delegovaním. Tam má pomocníka len jedna strana a je súkromný; tu sú si polovice rovnocenné, poznajú sa navzájom a každá patrí do inej hierarchie.