阅读Java-design-pattern源码abstractdocument(写的不是很容易懂,可以直接下载源码)

写的不是很容易懂,可以直接查看源码https://github.com/iluwatar/java-design-patterns

今天看到abstractdocument这个模式,我也不知道它的中文名字,但是我觉得这个模式还是非常有用。

首先有一辆Car代码如下


/**
 * Car entity
 */
public class Car extends AbstractDocument implements HasModel, HasPrice, HasParts {

  public Car(Map<String, Object> properties) {
    super(properties);
  }

}

从这个类中就可以直观的看到它实现了三个接口:HasModel,HasPrice , hasParts

三个接口不一一贴出,就贴一个HasModel

/**
 * HasModel trait for static access to 'model' property
 */
public interface HasModel extends Document {

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

}

可能看起来一头雾水,但是结构确实很清晰,车子是有车型,有价格,有具体某一部分

再贴出一段代码,看起来就会非常明了了


/**
 * Abstract implementation of Document interface
 */
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 value) {
    properties.put(key, value);
    return null;
  }

  @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();
  }

}

其实中间具体实现方法没有必要过多的纠结,我们从代码中就能看到,有一个map专门用来存放HasPrice , HasModel......等具体的实现类的

大概思路   就是   Car   有一个Map存放了车子一些属性

通过这种实现方式有什么好处呢,通过代码调用我们就能看出来这一点了

public class App {

  private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

  /**
   * Executes the App
   */
  public App() {
    LOGGER.info("Constructing parts and car");

    Map<String, Object> carProperties = new HashMap<>();
    carProperties.put(Property.MODEL.toString(), "300SL");
    carProperties.put(Property.PRICE.toString(), 10000L);

    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);

    carProperties.put(Property.PARTS.toString(), Arrays.asList(wheelProperties, doorProperties));

    Car car = new Car(carProperties);

    LOGGER.info("Here is our car:");
    LOGGER.info("-> model: {}", car.getModel().get());
    LOGGER.info("-> price: {}", car.getPrice().get());
    LOGGER.info("-> parts: ");
    car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}", p.getType().get(), p.getModel().get(), p.getPrice().get()));
  }

  /**
   * Program entry point
   *
   * @param args command line args
   */
  public static void main(String[] args) {
    new App();
  }

}

总结一下

通过泛型定义了车子所有的属性,car需要实现所有属性的接口,这样car才能通过get直接获取特定的属性

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值