@startuml package com.iluwatar.abstractdocument.domain.enums { enum Property { + MODEL {static} + PARTS {static} + PRICE {static} + TYPE {static} + valueOf(name : String) : Property {static} + values() : Property[] {static} } } package com.iluwatar.abstractdocument.domain { class Car { + Car(properties : Map<String, Object>) } interface HasModel { + getModel() : Optional<String> } interface HasParts { + getParts() : Stream<Part> } interface HasPrice { + getPrice() : Optional<Number> } interface HasType { + getType() : Optional<String> } class Part { + Part(properties : Map<String, Object>) } } package com.iluwatar.abstractdocument { abstract class AbstractDocument { - properties : Map<String, Object> # AbstractDocument(properties : Map<String, Object>) + children(key : String, constructor : Function<Map<String, Object>, T>) : Stream<T> + get(key : String) : Object + put(key : String, value : Object) + toString() : String } class App { - LOGGER : Logger {static} + App() + main(args : String[]) {static} } interface Document { + children(String, Function<Map<String, Object>, T>) : Stream<T> {abstract} + get(String) : Object {abstract} + put(String, Object) {abstract} } } AbstractDocument ..|> Document Car ..|> HasModel Car ..|> HasPrice Car ..|> HasParts Car --|> AbstractDocument HasModel --|> Document HasParts --|> Document HasPrice --|> Document HasType --|> Document Part ..|> HasType Part ..|> HasModel Part ..|> HasPrice Part --|> AbstractDocument @enduml