Table of Contents

Možné řešení z minulého cvičení

https://gitlab.fel.cvut.cz/B181_B6B36OMO/seminar/tree/master/cv7_solution

Teorie

Vzor Interpreter

Problém

Pro určitý (formální) jazyk chceme vytvořit reprezentaci pomocí objektů v paměti, abychom mohli pracovat s výrazy v tomto jazyce a vyhodnocovat je.

Řešení

Vzor interpreter popisuje jak definovat gramatiku pro jednoduchý jazyk, reprezentovat výrazy v tomto jazyce a interpretovat je.

Hierarchická reprezentace výrazu obsahuje dva základní druhy prvků:

Podobná hierarchie je reprezentována návrhovým vzorem Composite, který má obecnější použití než jen pro reprezentaci výrazů.

Vzor Visitor

Problém

Chceme vytvořit operaci pracující s elementy objektové struktury. Může se jednat o mnoho samostatných a nesouvisejících operací. Chceme však zabránit znepřehlednění kódu objektů těmito operacemi a chceme mít možnost definovat nové operace beze změny tříd se kterými pracují.

Řešení

Vzor visitor primárně abstrahuje funkcionalitu, která může být aplikována na celou hierarchii objektů.

Triviálním řešením by bylo vytvoření třídy, do které umístíme samostatnou metodu pro každou podtřídu hierarchie objektů. Veřejná bude pouze metoda přijímající kořenovou třídu hierarchie a dále se pomocí if podmínek a ověření typu parametru rozhodne, kterou z následujících metod zavolá.

Efektivnější řešení využívá takzvaný double dispatch. Java však podporuje pouze single dispatch, při kterém je volání metody závislé na názvu metody a identifikaci příjemce. Návrhový vzor visitor toto rozšiřuje o identifikaci odesílatele. První směrování požadavku je od objektu Visitor ke konkrétnímu elementu, který odpovědí zpět objektu Visitor souhlasí s návštěvou a identifikuje typ třídy.

Příklady k řešení

Stáhněte si z repository základ cvičení 8:

https://gitlab.fel.cvut.cz/B171_B6B36OMO/seminar/tree/master/cv8_assignment

Přečtěte si o Immutable Collections

Implementace ve cvičení 8 bude v následujících krocích

1. Do připraveného programu doimplementujte výrazy (operátory), použijte vzor interpreter:

2. Přidejte podporu pro vzor visitor a naimplementujte třídu PrintListExpressionVisitor.

3. Naimplementujte visitor (SimplifyListExpressionVisitor), který bude schopen symbolicky zjednodušit výrazy podle následujícího pravidla:

Operátor instanceof je přípustný. Nemodifikujte původní vyraz.

Minimalizujte opakování kódu.

Užitečné tipy:

Převod ImmutableList → ArrayList:

List<Integer> list = new ArrayList<>(immutableList);
Převod List → ImmutableList:
ImmutableList<Integer> immutableList = ImmutableList.copyOf(list);
Odstranění všech výskytů prvků element ze seznamu:
list.removeAll(Collections.singleton(element));
Seznamy typu List<Integer> můžete tisknout přímo pomocí System.out.print().