SW_11. Strategie - Strategy Šablona metoda template

Podobné dokumenty
APLIKACE NÁVRHOVÝCH VZORŮ

Úvod do programovacích jazyků (Java)

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Typický prvek kolekce pro české řazení

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

typová konverze typová inference

20. Projekt Domácí mediotéka

Java - řazení objektů

OOPR_05. Případové studie

Abstraktní třída a rozhraní

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Výčtový typ strana 67

Generické programování

Teoretické minimum z PJV

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

1. Téma 12 - Textové soubory a výjimky

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

boolean hasnext() Object next() void remove() Kolekce

KTE / ZPE Informační technologie

Seminář Java IV p.1/38

7. Dynamické datové struktury

Abstraktní datové typy: zásobník

1. Dědičnost a polymorfismus

SW_10. Dekorátor - Decorator Stav - State

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

3. Třídy. Základní pojmy objektového programování. Třídy

OOPR_05. Případové studie

Třídy. Instance. Pokud tento program spustíme, vypíše následující. car1 má barvu Red. car2 má barvu Red. car1 má barvu Blue.

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

Algoritmizace a programování

9. přednáška - třídy, objekty

Třídy, polymorfismus. A0B36PR2-Programování 2 Fakulta elektrotechnická České vysoké učení technické

1. Programování proti rozhraní

RMI Remote Method Invocation

IRAE 07/08 Přednáška č. 1

Projekty pro výuku programování v jazyce Java

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

9. Polymorfismus a rozhraní

Generické typy. Podrobněji: The Java Language Specification ( Third Edition ) , 18

PREPROCESOR POKRAČOVÁNÍ

Návrh softwarových systém. Návrh softwarových systémů

Základy objektové orientace I. Únor 2010

Úvod do programování - Java. Cvičení č.4

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

Java Enum Java, zimní semestr ,2017 1

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

Třídy a dědičnost. A0B36PR1-Programování 1 Fakulta elektrotechnická České vysoké učení technické

PB161 Programování v jazyce C++ Přednáška 7

Jazyk C# (seminář 3)

Java a XML. 10/26/09 1/7 Java a XML

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

PB161 Programování v jazyce C++ Přednáška 7

PŘETĚŽOVÁNÍ OPERÁTORŮ

Java Výjimky Java, zimní semestr

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Programování v Javě I. Leden 2008

Vzor Továrna - Factory

Motivační příklad reálný svět. výroba (assembly line)

Java - výjimky. private void vstup() throws IOException {... }

Programování v Javě I. Únor 2009

SW_12. Vzor Příkaz - Command Vzor Návštěvník - Visitor

OMO. 4 - Creational design patterns A. Singleton Simple Factory Factory Method Abstract Factory Prototype Builder IoC

public class Karel { private int position; public boolean issmiling; public int getposition() { return position;

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Programování v C++ 1, 6. cvičení

Vytváření a použití knihoven tříd

Java efektivně. Lukáš Zapletal liberix.cz. Pokročilejší techniky programování v Javě

Datové struktury. alg12 1

Deklarace a vytváření

4. ZÁKLADNÍ POJMY Z OBJEKTOVĚ ORIENTOVANÉHO PROGRAMOVÁNÍ

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

Datové abstrakce v programovacích jazycích

Seminář Java II p.1/43

Programové konvence, dokumentace a ladění. Programování II 2. přednáška Alena Buchalcevová

10 Generické implementace

Semin aˇr Java V yjimky Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Unor 2008 Radek Koˇc ı Semin aˇr Java V yjimky 1/ 25

Kód, který se nebude často měnit

11. Dědičnost. Dědičnost strana 103

Objektové programování

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

Principy objektově orientovaného programování

17. Projekt Trojúhelníky

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

8 Třídy, objekty, metody, předávání argumentů metod

Lambda funkce Novinky v interfaces Streamy Optional - aneb zbavujeme se null. Java 8. Ondřej Hrstka

Návrhové vzory Design Patterns

IB111 Programování a algoritmizace. Objektově orientované programování (OOP)

Základní pojmy. Matice(řádky, sloupce) Matice(4,6) sloupce

8. přednáška: Soubory a proudy

SOUBORY, VSTUPY A VÝSTUPY POKRAČOVÁNÍ

Regulární výrazy. Vzory

State. Známý jako. Účel. Použitelnost. Stav, Object for States. umožňuje objektu měnit svoje chování v závislosti na stavu objekt mění svou třídu

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

7.5 Diagram tříd pokročilé techniky

Návrhové vzory. Jakub Klemsa, Jan Legerský. 30. října Objektově orientované programování.

Parametrizované třídy Generics generické třídy. JDK zavádí mimo jiné tzv. parametrizované třídy - generics

Dědičnost (inheritance)

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

Transkript:

SW_11 Strategie - Strategy Šablona metoda template 1

Strategie Vzor strategie definuje množinu algoritmů, která každý zapouzdřuje a umožňuje je zaměňovat. Strategie dovoluje, aby se algoritmus měnit (pozměnil) nezávisle na klientovi, který ho používá. Záměrem vzoru strategie je zapouzdřit alternativní přístupy nebo strategie v samostatných třídách, kde každá implementuje danou operaci. 2

Strategy Kontext: Simulační hra s kachnami na rybníce. Simulace plavání (swim) a kvákání (quack). Společné metody v nadtřídě. Metoda display() je abstraktní. MallardDuck display() { // looks like a mallard Duck quack() swim() display() fly() // other duck-like methods RedheadDuck display() { // looks like a readhead Another types of ducks inherit from the Duck class 3

Strategy Inovace: plavající kachny. Zařazením metody fly() do nadtřídy všechny kachny v podtřídách mají metody fly(). Ale ne všechny kachny v podtřídách umí létat. display() { // looks like a mallard MallardDuck Duck quack() swim() display() fly() // other duck-like methods RedheadDuck display() { // looks like a readhead RubberDuck quack() { // overridden to Squeak display() { // looks like a rubberduck 4

Strategy Ve třídě RubberDuck nutno zastínit (override) metodu fly() stejně jako ostatní nerelevantní metody. Třída DecoyDuck kachna vábnička je také třeba zastínit metodu fly(). RubberDuck quack() { //squeak display() { // rubber duck fly() { // override to do nothing DecoyDuck quack() { // override to do nothing display() { // decoy duck fly() { // override to do nothing 5

Strategy Co použít rozhraní? Rozhraní Flyable mají pouze kachny které létají, Quackable pouze kvákající kachny. 6

Strategy Ne všechny podtřídy by měly mít chování flyable nebo quackable. Implementací uvedených rozhraní se řeší jen část problému. RubberDuck fly()?? Místo pro zavedení vzoru. Jedna základní pravda při tvorbě programového vybavení : ZMĚNA 7

Strategy - zaměření se na problém Využití dědičnosti nesplňovalo všechny požadavky chování kachny se mění v podtřídách není vhodné, aby to ostatní podtřídy z nadtřídy dědily. Rozhraní Flyable a Quackable nadějné, ale pouze kachny, které skutečné létají by měly implementovat Flyable. Navíc rozhraní nemá žádný kód => nutnost přepisování kódu v podtřídách, potenciální zdroj chyb. 8

Návrhový princip (zásada) Identifikujte aspekty aplikace, které se mění a oddělte je od těch, které zůstávají stejné. Aspekty aplikace, které se mění s každým dalším požadavkem (při přidání dalšího typu kachny). Vezměte části, které se mění a zapouzdřete je, takže je později můžete měnit nebo rozšiřovat bez ovlivňování neměnných částí. Nechte danou část systému měnit nezávisle na dalších částech systému. 9

Separace toho co se mění od toho co zůstává stejné Výsledek: méně nechtěných závislostí při změnách kódu a více pružnosti celého systému. Metody fly() a quack() jsou části, které se s dalšími požadavky na nadtřídu Duck mění. Oddělme toto chování od třídy Duck a vytvořme množinu tříd, reprezentující každé chování. Implementace fly() a quack() jsou v řadě tříd. 10

Návrhový princip (zásada) Chceme zavést novou podtřídu MallardDuck a inicializovat se specifickým typem létání. Programujte k rozhraní ne k implementaci. Rozhraní Flyable bude implementovat různé druhy létání. Třídy implementují konkrétní typ např. létání a jsou nezávislé liší se od předchozího. FlyWithWings fly() fly() { // implements duck flying «interface» FlyBehavior FlyNoWay fly() { // do nothing - can t fly 11

Návrhový princip (zásada) Programováním proti rozhraní umožňuje si pak vybrat konkrétní typ létání ne ho implementovat. Programování proti implementaci: Dog d = new Dog(); d.bark(); Programování proti rozhraní: Animal animal = new Dog(); animal.makesound(); Dog makesound() { bark(); bark() { // bark sound Animal makesound() Cat makesound() { meow(); meow() { // meow sound 12

Implementace chování kachny 13

Integrace chování kachny Klíčové v chování kachny delegování jejího chování létání, kvákání místo deklarování létání a kvákání uvnitř nadtřídy Duck. flybehavior, quackbehavior datové atributy odkazující se na uvedená rozhraní; mohou se dále polymorficky měnit na podtypy konkrétních rozhraní. 14

Integrace chování kachny 1. Jsou přidány dva datové atributy flybehavior, quackbehavior, jako typy rozhraní. 2. Konkrétní implementace kvákání: public class Duck { QuackBehavior quackbehavior; // dalsi kod public void performquack() { quackbehavior.quack(); 15

Integrace chování kachny 3. Jak jsou nastaveny datové atributy flybehavior, quackbehavior public class MallardDuck extends Duck { public MallardDuck() { quackbehavior = new Quack(); flybehavior = new FlyWithWings(); public void display() { System.out.println( I am a real Mallard duck ); 16

Integrace chování kachny Zásada neprogramovat proti implementaci. V konstruktoru jsme vytvořili novou instanci konkrétní třídy Quack. Zatímco v konstruktoru nastavujeme chování na konkrétní třídu (FlyWithWings, Quack), za běhu programu jsme schopni toto snadno změnit. Změnu umožňuje polymorfismus. 17

public abstract class Duck { FlyBehavior flybehavior; QuackBehavior quackbehavior; public Duck() { Testování kódu abstract void display(); public void performfly() { flybehavior.fly(); public void performquack() { quackbehavior.quack(); public void swim() { System.out.println("All ducks float, even decoys!"); 18

public interface FlyBehavior { public void fly(); public class FlyWithWings implements FlyBehavior { public void fly() { System.out.println("I'm flying!!"); public class FlyNoWay implements FlyBehavior { public void fly() { System.out.println("I can't fly");

public interface QuackBehavior { public void quack(); public class Quack implements QuackBehavior { public void quack() { System.out.println("Quack"); public class MuteQuack implements QuackBehavior { public void quack() { System.out.println("<< Silence >>"); public class Squeak implements QuackBehavior { public void quack() { System.out.println("Squeak");

public class MiniDuckSimulator { public static void main(string[] args) { MallardDuck mallard = new MallardDuck(); RubberDuck rubberduckie = new RubberDuck(); DecoyDuck decoy = new DecoyDuck(); ModelDuck model = new ModelDuck(); mallard.performquack(); rubberduckie.performquack(); decoy.performquack(); model.performfly(); model.setflybehavior(new FlyRocketPowered()); model.performfly(); java MiniDuckSimulator Quack I m flying!!

Přidáme dvě nové metody do třídy Duck: public void setflybehavior (FlyBehavior fb) { flybehavior = fb; Nastavení chování dynamicky public void setquackbehavior(quackbehavior qb) { quackbehavior = qb; Třída Duck Vytvoříme novou třídu DuckType public class ModelDuck extends Duck { public ModelDuck() { flybehavior = new FlyNoWay(); quackbehavior = new Quack(); public void display() { System.out.println("I'm a model duck"); Vytvoříme novou třídu pro chování: FlyRocketPowered public class FlyRocketPowered implements FlyBehavior { public void fly() { System.out.println("I'm flying with a rocket");

public class MiniDuckSimulator1 { public static void main(string[] args) { Duck mallard = new MallardDuck(); mallard.performquack(); mallard.performfly(); Změníme testovací třídu Duck model = new ModelDuck(); model.performfly(); model.setflybehavior(new FlyRocketPowered()); model.performfly(); java MiniDuckSimulator1 Quack I m flying!! I can t fly I m flying with a rocket

Velký obrázek zapouzdřeného chování 24

Kompozice HAS-A může být lepší než hierarchie IS-A Relace HAS-A zajímavá v tom, že každá kachna má FlyBehavior a QuackBehavior na něž deleguje flying a quacking (létání a kvákání). Místo dědění, d kachny získávaní své chování tím, že jsou složeny s pravým objektem jejich chování. Upřednostňujte skládání před dědičností. 25

Kompozice & dědičnost Vytvoření systému používající skládání (kompozice) dává více flexibility. Nejen že dovoluje zapouzdřit rodinu algoritmů do jejich vlastní množiny tříd, ale také dovoluje měnit chování za běhu (run time). 26

Další příklad: Vzor Strategie Vzor Strategie (Strategy) definuje množinu (rodinu) algoritmů, zapouzdřuje každý z nich a umožňuje jejich zaměnitelnost. Strategie dovoluje algoritmu měnit se nezávisle na klientech, kteří je používají. 27

interface FindMinima { // Line is a sequence of points: double[] algorithm(double[] line); // ruzne strategie: class LeastSquares implements FindMinima { public double[] algorithm(double[] line) { return new double[] { 1.1, 2.2 ; // Dummy class NewtonsMethod implements FindMinima { public double[] algorithm(double[] line) { return new double[] { 3.3, 4.4 ; // Dummy class Bisection implements FindMinima { public double[] algorithm(double[] line) { return new double[] { 5.5, 6.6 ; // Dummy class ConjugateGradient implements FindMinima { public double[] algorithm(double[] line) { return new double[] { 3.3, 4.4 ; // Dummy

// The "Context" controls the strategy: class MinimaSolver { private FindMinima strategy; public MinimaSolver(FindMinima strat) { strategy = strat; double[] minima(double[] line) { return strategy.algorithm(line); void changealgorithm(findminima newalgorithm) { strategy = newalgorithm; programováni proti rozhraní

class ArrayX { private ArrayX() { public static String tostring(double[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); result.append("]"); return result.tostring(); Převádí pole na textovou reprezentaci

public class StrategyPattern { public static void main(string args[]) { MinimaSolver solver = new MinimaSolver(new LeastSquares()); double[] line = { 1.0, 2.0, 1.0, 2.0, -1.0, 3.0, 4.0, 5.0, 4.0 ; System.out.println( ArrayX.toString(solver.minima(line))); solver.changealgorithm(new Bisection()); System.out.println( ArrayX.toString(solver.minima(line))); [1.1, 2.2] [5.5, 6.6]

Šablona - Template Kontext: Definice metod, které mají společný obecný základ, ale liší se v implementaci konkrétních kroků. Problém: Při definování metody bychom rádi definovali pouze základní obrysy (návrh) algoritmu a ponechali možnost rozdílné implementace jistých kroků. 32

Řešení: Šablona Zavedení vzoru Šablona (Template method), jejímž cílem je implementovat daný algoritmus v metodě, přičemž odkládá definování některých kroků algoritmu tak, že je jiné třídy mohou redefinovat (dodefinovat). Nejdříve uvedeme příklad objasňující vzor šablona na příkladu přípravy kávy a čaje. Dále je uveden klasický příklad třídění. 33

public class Coffee { final void preparerecipe() { boilwater(); // vaření vody brew(); // spaření pourincup(); //nalévání do šálku addsugarandmilk(); //přidání cukru a mléka public void boilwater() { System.out.println("Vaření vody"); Metoda preparerecipe() obsahuje celý postup přípravy kávy. Dílčí metody jsou uvedeny dále. public void void brewcoffeegrinds() { System.out.println("Překapání kávy přes filtr"); public void pourincup() { System.out.println("Nalití kávy do šálku"); public void addsugarandmilk() { System.out.println("Přidání cukru a mléka"); Metoda preparerecipe() je pro třídu Tea podobná, má však dvě různé metody. 34

public class Tea { final void preparerecipe() { boilwater(); steepteabag(); // vyluhování čajového sáčku pourincup(); addlemon(); // přidání citronu... 35

Šablona Z kódu vidíme, že dvě metody jsou stejné jako ve třídě Coffee a dvě jsou různé. 36

Šablona Abstraktní třída CoffeineBeverage (kofejnový nápoj) má dvě podtřídy, z nichž každá předeklarovává metodu preparerecipe(). Toto řešení dále upravíme tak, že zavedeme nové metody brew() a addcondiments() do metody preparerecipe(). To pak znamená, že tato metoda nemusí být předeklarovaná v podtřídách. 37

public abstract class CaffeineBeverage { final void preparerecipe() { boilwater(); brew(); // metoda předeklarovaná v podtřídách pourincup(); addcondiments(); // metoda předeklarovaná v // podtřídách abstract void brew(); // příprava nápoje abstract void addcondiments(); // přidání dochucovadel void boilwater() { System.out.println("Boiling water"); void pourincup() { System.out.println("Pouring into cup"); 38

public class Coffee extends CaffeineBeverage { public void brew() { System.out.println("Dripping Coffee through filter"); public void addcondiments() { System.out.println("Adding Sugar and Milk"); 39

Definice vzoru šablona Jak vidíme z předchozího postupu, návrhový vzor šablona definuje kroky algoritmu a dovoluje podtřídám implementovat některé z jeho kroků. Vzor šablona definuje kostru algoritmu v metodě, která odsouvá některé ze svých kroků do podtříd. Metoda šablona dovoluje podtřídám předefinovat jisté kroky algoritmu, beze změn struktury algoritmu. 40

public abstract class AbstractClass { final void templatemethod() { // metoda předeklarovaná v podtřídě primitiveoperation1(); // metoda předeklarovaná v podtřídě primitiveoperation2(); concreteoperation(); abstract void primitiveoperation1(); abstract void primitiveoperation2(); void concreteoperation() { // implementace metody void hook() { 41

Šablona Metoda templatemethod() je finální, což znamená, že nemůže být předeklarovaná v podtřídách. Ta vlastně tvoří kostru algoritmu. Metody primitivnioperace1,2() jsou abstraktní a musí být předeklarované v podtřídách. Metoda hook() (háček, skoba) je konkrétní metoda a nemusí dělat nic. Pomáhá při nastavování defaultních hodnot. 42

public abstract class CaffeineBeverageWithHook { void preparerecipe() { boilwater(); brew(); pourincup(); // zákazník chce přísady (cukr..) if (customerwantscondiments()) { addcondiments(); abstract void brew(); abstract void addcondiments(); void boilwater() { System.out.println("Boiling water"); void pourincup() { System.out.println("Pouring into cup"); // metoda hook(), podtřída ho může ale // nemusí předeklarovat boolean customerwantscondiments() { return true; 43

public class CoffeeWithHook extends CaffeineBeverageWithHook { public void brew() { System.out.println("Dripping Coffee through filter"); public void addcondiments() { System.out.println("Adding Sugar and Milk"); // podtřída předeklaruje metodu nadtřídy public boolean customerwantscondiments() { String answer = getuserinput(); if (answer.tolowercase().startswith("y")) { return true; else { return false; 44

private String getuserinput() { String answer = null; System.out.print("Would you like milk and sugar with your coffee (y/n)? "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); try { answer = in.readline(); catch (IOException ioe) { System.err.println("IO error trying to read your answer"); if (answer == null) { return "no"; return answer; Jak je vidět z podtřídy, ta má možnosti metodu hook() předeklarovat a ptá se zákazníka, zda chce nebo nechce přísady do zvoleného nápoje. 45

public class BeverageTestDrive { public static void main(string[] args) { Coffee coffee = new Coffee(); System.out.println("\nMaking coffee..."); coffee.preparerecipe(); CoffeeWithHook coffeehook = new CoffeeWithHook(); System.out.println("\nMaking coffee..."); coffeehook.preparerecipe(); Třída CaffeineBeverage je naše vysoko úrovňová komponenta. Ta má kontrolu nad algoritmem, který je uveden v metodě preparerecipe() a volá podtřídy, pouze když jsou potřebné pro implementaci metody. 46

Klasický případ třídění Třídící algoritmy se liší v přístupu a v rychlosti, ale každý třídící algoritmus spočívá na základních krocích porovnání dvou položek nebo atributů. Třídění je dávný příklad vzoru šablona. Je to postup, který nám dovoluje měnit jeden kritický krok a tím je porovnání dvou objektů, tak, aby se algoritmus dal použít vícekrát pro různé kolekce objektů. 47

Šablona třídění Třídy Array a Collection v Javě poskytují metodu sort(), která je deklarovaná jako třídní (statická) a pole (array), které se má setřídit, se jí zadává jako argument. Dále metoda někdy požaduje volitelný Comparator (rozhraní). Collection c = Collection.sort(array) 48

Šablona třídění Naproti tomu třída ArrayList poskytuje instanční metodu sort(), která třídí příjemce této zprávy. ArrayList al = arraylist.sort() 49

Šablona třídění Oba přístupy jsou ale závislé na rozhraních Comparable a Comparator. Rozdíl mezi nimi je pouze v tom, že rozhraní Comparable očekává oba porovnávané objekty jako argumenty, zatímco Comparator očekává pouze jeden argument (porovnávaný objekt), druhý objekt představuje Comparator sám. 50

Šablona třídění Metoda sort() ve třídách Array a Collection dovoluje využívat ke třídění instance rozhraní Comparator. Pokud ji neuvedeme, metoda sort() bude využívat metodu compareto() rozhraní Comparable. Většina primitivních typů včetně třídy String implementuje rozhraní Comparable. 51

Šablona třídění Třídění (řazení) primitivních typů probíhá podle implicitně implementovaného rozhraní Comparable v těchto typech (třídách). Objektový typ - obsahující více typů (objektových, primitivních) - nejdříve nutno implementovat rozhraní Comparable, aby bylo jasné, podle kterých datových atributů objektového typu se bude třídit (porovnávat). 52

Šablona třídění Rozhraní Comparable obsahuje následující metodu: public interface Comparable { public int compareto(t o); Metoda compareto() porovnává přijímající objekt (příjemce zprávy) se specifikovaným objektem jako argumentem metody a vrací: 0 obě hodnoty jsou stejné 1 příjemce je větší, než objekt specifikovaný jako argument (kladné číslo) -1 příjemce je menší, než objekt specifikovaný jako argument (záporné číslo) 53

public class OsobaJmeno implements Comparable<OsobaJmeno> { private String jmeno, prijmeni; public OsobaJmeno(String jmeno, String prijmeni){ this.jmeno = jmeno; this.prijmeni = prijmeni; public String getjmeno(){ return jmeno; public String getprijmeni(){ return prijmeni; public boolean equals(object o){ if(!(o instanceof OsobaJmeno)) return false; OsobaJmeno oj = (OsobaJmeno) o; return oj.getjmeno().equals(jmeno) && oj.getprijmeni().equals(prijmeni); public String tostring(){ return "Jmeno: "+jmeno+" prijmeni: "+prijmeni; public int compareto(osobajmeno oj){ int porovnani = prijmeni.compareto(oj.prijmeni); return (porovnani!= 0? porovnani : jmeno.compareto(oj.jmeno)); 54

public class OsobaJmenoTest { public static void main(string[] args) { OsobaJmeno o1, o2, o3, o4; o1 = new OsobaJmeno("Jan", "Zelenka"); o2 = new OsobaJmeno("Jan","Zehnal"); o3 = new OsobaJmeno("Jan","Zehnal"); o4 = new OsobaJmeno("Adam","Sedlacek"); System.out.println("o1 + o2 "+o1.compareto(o2)); System.out.println("o2 + o3 "+o2.compareto(o3)); System.out.println("o1 + o4 "+o1.compareto(o4)); System.out.println("o4 + o3 "+o4.compareto(o3)); 55

import java.util.*; public class OsobaJmenoSort { public static void main(string args[]){ OsobaJmeno polejmen[] = { new OsobaJmeno("Jiri","Maly"), new OsobaJmeno("Odlrich","Maly"), new OsobaJmeno("Adam","Maly"), new OsobaJmeno("Alena","Mala"), new OsobaJmeno("Anna","Maliskova") ; List<OsobaJmeno> jmena = Arrays.asList(poleJmen); Collections.sort(jmena); System.out.println(jmena); Využití třídění 56

public interface Comparator<t> { int compare(t o1, T o2); boolean equals(object o); Další porovnávání objektů je možné dělat s využitím rozhraní Comparator, které deklaruje dvě metody: 57

import java.util.comparator; public class TimeComparator implements Comparator< Time2 > { public int compare( Time2 time1, Time2 time2 ) { // porovná hodiny int hourcompare = time1.gethour() - time2.gethour(); // nejdříve test hodin - hour if ( hourcompare!= 0 ) return hourcompare; // porovná minuty int minutecompare = time1.getminute() - time2.getminute(); Třída TimeComparator implementuje rozhraní Comparator k porovnání dvou objektů třídy Time // potom test minut if ( minutecompare!= 0 ) return minutecompare; // porovná vteřiny int secondcompare = time1.getsecond() - time2.getsecond(); return secondcompare; // vrací výsledek porovnání 58

// Třídění seznamu s použitím tříd Comparator a // TimeComparator. import java.util.list; import java.util.arraylist; import java.util.collections; public class Sort3 { public void printelements() { // vytvoření seznamu List< Time2 > list = new ArrayList< Time2 >(); list.add( new Time2( 6, 24, 34 ) ); list.add( new Time2( 18, 14, 58 ) ); list.add( new Time2( 6, 05, 34 ) ); list.add( new Time2( 12, 14, 58 ) ); list.add( new Time2( 6, 24, 22 ) ); // výstup prvků seznamu System.out.printf( "Unsorted array elements:\n%s\n", list ); // třídění s využitím comparator Collections.sort( list, new TimeComparator() ); 59

// výstup prvků seznamu System.out.printf( "Sorted list elements:\n%s\n", list ); // konec metody printelements() public static void main( String args[] ) { Sort3 sort3 = new Sort3(); sort3.printelements(); 60

Shrnutí Záměrem vzoru šablona je definovat algoritmus v metodě a nechat při tom některé kroky abstraktní, nebo definovat rozhraní, které může být implementováno rozdílně v různých třídách. Další třídy pak mohou doplňovat chybějící kroky, nebo implementovat rozhraní různě podle svých potřeb. 61