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. A dokumentum szó a dokumentumorientált adatbázisokból származik. Definíció A 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.. 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 bélyegkép|jobbra|500px|Absztrakt dokumentum minta szerkezeti vázlata A 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 Az 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 interface 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 A 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

Fordítás

Kategória:Programtervezési minták Kategória:Java-kódpéldák