设计模式-抽象文档模式

定义:用于组织松散类型的键值存储中的对象并使用类型化的视图公开数据。 该模式的目的是在强类型语言中实现组件之间的高度灵活性,在这种语言中,可以在不丢失类型安全支持的情况下,将新属性动态地添加到对象树中。 该模式利用特征将类的不同属性分成不同的接口。

类图:

示例:考虑由多个部分组成的汽车。 但是,我们不知道特定汽车是否真的拥有所有零件,或者仅仅是零件中的一部分。 我们的汽车是动态而且非常灵活的。

代码示例:

1.创建Document接口,定义基本行为

public interface Document {
    void put(String key,Object object);
    Object get(String key);
   <T> Stream<T> children(String key, Function<Map<String,Object>,T> constructor);

}

2.创建抽象类AbstractDoucument实现Document接口,实现抽象方法具体逻辑,定义属性,存放数据对象

public abstract class AbstractDocument implements  Document{

    private final Map<String, Object> properties;


    protected AbstractDocument(Map<String, Object> properties) {
        Objects.requireNonNull(properties, "properties map is required");
        this.properties = properties;
    }

    @Override
    public void put(String key, Object object) {
        properties.put(key, object);
    }

    @Override
    public Object get(String key) {

        return properties.get(key);
    }

    @Override
    public <T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor) {

        Optional<List<Map<String, Object>>> any = Stream.of(get(key))
                .filter(el -> el != null)
                .map(el -> (List<Map<String, Object>>) el)
                .findAny();
        return any.isPresent() ? any.get().stream().map(constructor) : Stream.empty();

    }

    @Override
    public String toString() {

        StringBuilder builder = new StringBuilder();
        builder.append(getClass().getName()).append("[");
        properties.entrySet().forEach(e->builder.append("[").append(e.getKey()).append(":").append(e.getValue()).append("]"));
        builder.append("]");

        return builder.toString();
    }
}

 3.定义枚举类,内容为文档的增强属性。

public enum Property {

    PARTS, //零件
    TYPE, //类型
    PRICE,//价格
    MODEL //模型

}

4.创建零件接口

public interface HasModel extends Document {

    default Optional<String> getModel() {

        return Optional.ofNullable((String) get(Property.MODEL.toString()));
    }
}


public interface HasPrice extends Document{

    default Optional<Number> getPrice(){

        return Optional.ofNullable( (Number) get(Property.PRICE.toString()));
    }


}


public interface HasType extends Document{


    default Optional<String> getType(){
        return Optional.ofNullable((String) get(Property.TYPE.toString()));
    }


}

 5.创建Part类,作为汽车零件的实现类

public class Part extends  AbstractDocument implements  HasPrice,HasModel,HasType{
    public Part(Map<String, Object> properties) {
        super(properties);
    }
}

6.创建零件接口,返回零件对象

public interface HasParts extends Document {

    default Stream<Part> getParts() {

        return   children(Property.PARTS.toString(),Part::new);
    }

}

7.测试

public class Test {
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put(Property.MODEL.toString(),"300Ls");
        map.put(Property.PRICE.toString(),1000L);

        Map<String, Object> wheelProperties = new HashMap<>();
        wheelProperties.put(Property.TYPE.toString(), "wheel");
        wheelProperties.put(Property.MODEL.toString(), "15C");
        wheelProperties.put(Property.PRICE.toString(), 100L);
        Map<String, Object> doorProperties = new HashMap<>();
        doorProperties.put(Property.TYPE.toString(), "door");
        doorProperties.put(Property.MODEL.toString(), "Lambo");
        doorProperties.put(Property.PRICE.toString(), 300L);
        map.put(Property.PARTS.toString(), Arrays.asList(wheelProperties,doorProperties));
        Car car = new Car(map);


            car.getParts().forEach(x-> {System.out.println(x.getType());
                System.out.println(x.getModel());
                System.out.println(x.getPrice());
            });

        System.out.println("<---------->");
        System.out.println(car.getPrice());
        System.out.println(car.getModel());

    }
}

输出为:

Optional[wheel]
Optional[15C]
Optional[100]
Optional[door]
Optional[Lambo]
Optional[300]
<---------->
Optional[1000]
Optional[300Ls]

参考:

https://java-design-patterns.com​​​​​​

https://github.com/iluwatar/java-design-patterns-vuepress-web

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值