Már áttekintettük a singleton objektumok használatát, de lehet, hogy még nem veszi észre, hogy ez a stratégia tervezési minta, és az egyik leggyakrabban használt.
Valójában nagyon sok ilyen minta létezik, és céljuk szerint osztályozhatók.
Minta osztályozás
Mintatípus | Alkalmazás |
---|---|
Kreatív | Egy típus, amely megoldja az objektum létrehozási problémát |
Szerkezeti | Minták, amelyek segítségével helyes és bővíthető osztályhierarchiát építhetünk fel architektúránkban |
Viselkedési | Ez a mintacsoport biztonságos és kényelmes interakciót tesz lehetővé a program objektumai között. |
A mintát jellemzően az általa megoldott probléma jellemzi. Vessünk egy pillantást néhány mintára, amelyekkel leggyakrabban találkozunk, amikor Java-val dolgozunk:
Minta | Célja |
---|---|
Szingli | Már ismerjük ezt a mintát – egy olyan osztály létrehozására és elérésére használjuk, amelynek nem lehet több példánya. |
Iterátor | Ezt is ismerjük. Tudjuk, hogy ez a minta lehetővé teszi, hogy egy gyűjteményobjektum felett iteráljunk anélkül, hogy felfednénk annak belső reprezentációját. Gyűjteményekhez használják. |
Adapter | Ez a minta összekapcsolja az inkompatibilis objektumokat, hogy együtt tudjanak működni. Azt hiszem, az adapterminta neve segít elképzelni, hogy ez pontosan mit is csinál. Íme egy egyszerű példa a való életből: USB adapter fali aljzathoz. |
Sablon módszer |
Egy viselkedési programozási minta, amely megoldja az integrációs problémát, és lehetővé teszi az algoritmus lépéseinek megváltoztatását anélkül, hogy megváltoztatná az algoritmus szerkezetét. Képzeljük el, hogy van egy autó-összeszerelési algoritmusunk az összeszerelési lépések sorozata formájában: Alváz -> Karosszéria -> Motor -> Fülke belső Ha megerősített vázat, erősebb motort vagy kiegészítő világítással ellátott belsőt teszünk bele, akkor nem kell az algoritmust módosítanunk, és az absztrakt sorrend változatlan marad. |
Lakberendező | Ez a minta burkolókat hoz létre az objektumokhoz, hogy hasznos funkciókat biztosítson nekik. Ezt a cikk részeként fogjuk figyelembe venni. |
A Java.io-ban a következő osztályok valósítanak meg mintákat:
Minta | Hol használják a java.io-ban |
---|---|
Adapter |
|
Sablon módszer | |
Lakberendező |
Dekorátor minta
Képzeljük el, hogy egy lakberendezési modellt írunk le.
Általában a megközelítés így néz ki:
Kezdetben többféle háztípus közül válogathatunk. A minimális konfiguráció egy emelet tetővel. Ezután mindenféle lakberendezőt használunk további paraméterek megváltoztatására, ami természetesen befolyásolja a ház árát.
Létrehozunk egy absztrakt House osztályt:
public abstract class House {
String info;
public String getInfo() {
return info;
}
public abstract int getPrice();
}
Itt van 2 módszerünk:
- A getInfo() információkat ad vissza házunk nevéről és jellemzőiről;
- A getPrice() az aktuális házkonfiguráció árát adja vissza.
Vannak szabványos házmegvalósításaink is – tégla és fa:
public class BrickHouse extends House {
public BrickHouse() {
info = "Brick House";
}
@Override
public int getPrice() {
return 20_000;
}
}
public class WoodenHouse extends House {
public WoodenHouse() {
info = "Wooden House";
}
@Override
public int getPrice() {
return 25_000;
}
}
Mindkét osztály örökli a Ház osztályt, és felülírja annak ármódszerét, egyéni árat állítva be egy standard házhoz. Beállítjuk a nevet a konstruktorban.
Ezután dekorátor órákat kell írnunk. Ezek az osztályok a House osztályt is öröklik . Ehhez létrehozunk egy absztrakt dekoratőr osztályt.
Itt további logikát helyezünk el egy objektum megváltoztatásához. Kezdetben nem lesz további logika, és az absztrakt osztály üres lesz.
abstract class HouseDecorator extends House {
}
Ezután dekorátor megvalósításokat készítünk. Több osztályt hozunk létre, amelyek segítségével további funkciókat adhatunk a házhoz:
public class SecondFloor extends HouseDecorator {
House house;
public SecondFloor(House house) {
this.house = house;
}
@Override
public int getPrice() {
return house.getPrice() + 20_000;
}
@Override
public String getInfo() {
return house.getInfo() + " + second floor";
}
}
Egy lakberendező, aki második emelettel bővíti házunkat |
A lakberendező kivitelező olyan házat fogad el, amit mi "bedíszítünk", azaz módosítunk. És felülírjuk a getPrice() és getInfo() metódusokat, és a régi alapján adunk vissza információkat az új frissített házról.
public class Garage extends HouseDecorator {
House house;
public Garage(House house) {
this.house = house;
}
@Override
public int getPrice() {
return house.getPrice() + 5_000;
}
@Override
public String getInfo() {
return house.getInfo() + " + garage";
}
}
Egy lakberendező, aki garázzsal bővíti házunkat |
Most már lakberendezőkkel is felfrissíthetjük házunkat. Ehhez létre kell hoznunk egy házat:
House brickHouse = new BrickHouse();
Ezután beállítjuk a sajátunkatházváltozó megegyezik egy új lakberendezővel, ami házunkban megy el:
brickHouse = new SecondFloor(brickHouse);
A miénkházváltozó most egy második emeletes ház.
Nézzük a lakberendezők felhasználási eseteit:
Példa kód | Kimenet |
---|---|
|
Téglaház 20000 |
|
Tégla ház + második emelet 40000 |
|
Tégla ház + második emelet + garázs 45000 |
|
Faház + garázs + második emelet 50000 |
|
Faház 25000 Faház + garázs 30000 |
Ez a példa szemlélteti egy objektum dekorátorral történő frissítésének előnyeit. Tehát nem változtattunkfaházmagát az objektumot, hanem egy új objektumot hozott létre a régi alapján. Itt láthatjuk, hogy az előnyöknek hátrányai is vannak: minden alkalommal új objektumot hozunk létre a memóriában, növelve a memóriafelhasználást.
Tekintse meg programunk UML diagramját:
A dekoratőr rendkívül egyszerű megvalósítással rendelkezik, és dinamikusan változtatja az objektumokat, frissíti azokat. A dekorátorokat a konstruktorok ismerhetik fel, amelyek paraméterként az aktuális osztályéval azonos absztrakt típusú vagy interfész objektumokat vesznek fel. A Java nyelven ezt a mintát széles körben használják az I/O osztályokban.
Például, ahogy már említettük, a java.io.InputStream , OutputStream , Reader és Writer összes alosztályának van egy konstruktora, amely elfogadja az azonos osztályú objektumokat.
GO TO FULL VERSION