Absztrakt dokumentum minta
Az absztrakt dokumentum minta egy szerkezeti programtervezési minta, arra, hogy az objektumokat lazán típusozott kulcs-érték szerkezetbe rendezze, amit különböző típusú nézetekkel lehet megnézni. Célja, hogy nagy mértékű hajlékonyságot érjen el egy erősen típusozott nyelvben, ahol az objektumfa menet közben új tulajdonságokkal bővíthető a típusbiztonság támogatásának elvesztése nélkül. A minta vonásokat használ, hogy egy osztály tulajdonságait különböző interfészekbe ossza.[1] A dokumentum szó a dokumentumorientált adatbázisokból származik.
Definíció
szerkesztésA dokumentum egy objektum, ami több különböző tulajdonságot tartalmaz. Ez lehet egy érték, szám vagy string, vagy más dokumentumok listája. Minden tulajdonságot kulccsal hivatkoznak..[2] A dokumentumfa beutazásakor a felhasználó meghatároz egy konstruktort, amivel a következő szint osztályának megvalósítását létrehozza. Ezek gyakran különböző vonások uniója, amelyek a dokumentum (Docemunent) interfészt terjesztik ki, és lehetővé teszik, hogy önállóan kezeljék a tulajdonságok átadását és módosítását.
Szerkezete
szerkesztésA Document interfész megállapítja, hogy mely tulajdonságok olvashatók és írhatók get és put metódiusokkal, továbbá az aldokumentumok bejárhatók a children metódussal. Ez függvényreferenciát igényel egy metódusra, ami képes egy gyerek típusozott nézetét generálni annak a mapnek az ismeretében, ami hivatkozza azokat az adatokat, amelyeket a gyereknek tartalmaznia kell. A hivatkozásokra azért van szükség, hogy ha itt megváltoztatnak valamit, akkor az eredeti is megváltozzon.
A megvalósítások több traitből is örökölhetnek, amelyek különböző tulajdonságokat írnak le, habár lehetnek több traitből örökölt tulajdonságok is. Az egyetlen korlátozás az, hogy a megvalósítás állapotmentes legyen, kivéve a BaseDocumentből örökölt tulajdonságokat.
Használata
szerkesztésAz absztrakt dokumentumminta megengedi, hogy a programozó úgy tárolja a változókat, mint konfigurációs változókat egy nem típusozott dokumentumfában, és a dokumentumokat típusozott nézetekben szerkesztheti. Az újabb nézetek vagy megvalósítások nem érintik a belső dokumentumszerkezetet. Ennek az az előnye, hogy lazítja a kapcsolatot az elemek között, de növeli a típuskonverzióból következő hibák valószínűségét, mivel a tulajdonságok típusa nem mindig nyilvánvaló.
Pszeudokód
szerkesztésinterface Document put(key : String, value : Object) : Object get(key : String) : Object children(key : String, constructor : Map<String, Object> -> T) : T[] abstract class BaseDocument : Document properties : Map<String, Object> constructor(properties : Map<String, Object>) this->properties := properties implement put(key : String, value : Object) : Object return this->properties->put(key, value) implement get(key : String) : Object return this->properties->get(key) implement children(key : String, constructor : Map<String, Object> -> T) : T[] var result := new T[] var children := this->properties->get(key) castTo Map<String, Object>[] foreach ( child in children ) result[] := constructor->apply(child) return result
Implementációs példa
szerkesztésA következő példák Java nyelvűek.
Document.java
public interface Document {
Object put(String key, Object value);
Object get(String key);
<T> Stream<T> children(
String key,
Function<Map<String, Object>, T> constructor
);
}
BaseDocument.java
public abstract class BaseDocument implements Document {
private final Map<String, Object> entries;
protected BaseDocument(Map<String, Object> entries) {
this.entries = requireNonNull(entries);
}
@Override
public final Object put(String key, Object value) {
return entries.put(key, value);
}
@Override
public final Object get(String key) {
return entries.get(key);
}
@Override
public final <T> Stream<T> children(
String key,
Function<Map<String, Object>, T> constructor) {
final List<Map<String, Object>> children =
(List<Map<String, Object>>) get(key);
return children == null
? Stream.empty()
: children.stream().map(constructor);
}
}
Usage.java
Map<String, Object> source = ...;
Car car = new Car(source);
String model = car.getModel();
int price = car.getPrice();
List<Wheel> wheels = car.children("wheel", Wheel::new)
.collect(Collections.toList());
Jegyzetek
szerkesztés- ↑ Forslund, Emil: Age of Java: The Best of Both Worlds. Ageofjava.blogspot.com , 2016. január 15. [2016. január 18-i dátummal az eredetiből archiválva]. (Hozzáférés: 2016. január 23.)
- ↑ Fowler, Martin: Dealing with Properties. (Hozzáférés: 2016. január 29.)
Fordítás
szerkesztésEz a szócikk részben vagy egészben az Abstract Document Pattern című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.