【设计模式】JAVA Design Patterns——Abstract-document(抽象文档模式)

简介: 【设计模式】JAVA Design Patterns——Abstract-document(抽象文档模式)

🔍 目的


使用动态属性,并在保持类型安全的同时实现非类型化语言的灵活性。


🔍 解释


抽象文档模式使您能够处理其他非静态属性。 此模式使用特征的概念来实现类型安全,并将不同类的属性分离为一组接口

真实世界例子

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

通俗的说

抽象文档模式允许在对象不知道的情况下将属性附加到对象。

维基百科

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


🔍 程序示例

让我们首先定义基类DocumentAbstractDocument。 它们基本上使对象拥有属性映射和任意数量的子对象。

public interface Document {
 
  Void put(String key, Object value);
 
  Object get(String key);
 
  <T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor);
}
 
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) {
    return Stream.ofNullable(get(key))
        .filter(Objects::nonNull)
        .map(el -> (List<Map<String, Object>>) el)
        .findAny()
        .stream()
        .flatMap(Collection::stream)
        .map(constructor);
  }
  ...
}


接下来,我们定义一个枚举“属性”和一组类型,价格,模型和零件的接口。 这使我们能够为Car类创建静态外观的界面。

public enum Property {
 
  PARTS, TYPE, PRICE, MODEL
}
 
public interface HasType extends Document {
 
  default Optional<String> getType() {
    return Optional.ofNullable((String) get(Property.TYPE.toString()));
  }
}
 
public interface HasPrice extends Document {
 
  default Optional<Number> getPrice() {
    return Optional.ofNullable((Number) get(Property.PRICE.toString()));
  }
}
public interface HasModel extends Document {
 
  default Optional<String> getModel() {
    return Optional.ofNullable((String) get(Property.MODEL.toString()));
  }
}
 
public interface HasParts extends Document {
 
  default Stream<Part> getParts() {
    return children(Property.PARTS.toString(), Part::new);
  }
}


我们准备介绍Car

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


完整示例中的Car构造和使用方式。

    LOGGER.info("Constructing parts and car");
 
    var wheelProperties = Map.of(
        Property.TYPE.toString(), "wheel",
        Property.MODEL.toString(), "15C",
        Property.PRICE.toString(), 100L);
 
    var doorProperties = Map.of(
        Property.TYPE.toString(), "door",
        Property.MODEL.toString(), "Lambo",
        Property.PRICE.toString(), 300L);
 
    var carProperties = Map.of(
        Property.MODEL.toString(), "300SL",
        Property.PRICE.toString(), 10000L,
        Property.PARTS.toString(), List.of(wheelProperties, doorProperties));
 
    var car = new Car(carProperties);
 
    LOGGER.info("Here is our car:");
    LOGGER.info("-> model: {}", car.getModel().orElseThrow());
    LOGGER.info("-> price: {}", car.getPrice().orElseThrow());
    LOGGER.info("-> parts: ");
    car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}",
        p.getType().orElse(null),
        p.getModel().orElse(null),
        p.getPrice().orElse(null))
    );
 
    // Constructing parts and car
    // Here is our car:
    // model: 300SL
    // price: 10000
    // parts: 
    // wheel/15C/100
    // door/Lambo/300


🔍 类图

8e945deb4c9f4fadaa256e15629347ba.png


🔍 适用性


使用抽象文档模式当

  • 需要即时添加新属性
  • 你想要一种灵活的方式来以树状结构组织域
  • 你想要更宽松的耦合系统

5ff60e89324042e3a1f29fbe59cffc14.gif

相关文章
|
18天前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的网上手机销售系统附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的网上手机销售系统附带文章和源代码设计说明文档ppt
23 0
|
5天前
|
设计模式 存储 安全
Java中的23种设计模式
Java中的23种设计模式
6 1
|
6天前
|
数据可视化 Java API
【JAVA】javadoc,如何生成标准的JAVA API文档
【JAVA】javadoc,如何生成标准的JAVA API文档
7 0
|
12天前
|
Java 数据安全/隐私保护
Java使用PDFBox开发包实现对PDF文档内容编辑与保存
Java使用PDFBox开发包实现对PDF文档内容编辑与保存
26 7
|
18天前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的生鲜在线销售系统附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的生鲜在线销售系统附带文章和源代码设计说明文档ppt
14 0
|
18天前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的经典电影推荐网站附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的经典电影推荐网站附带文章和源代码设计说明文档ppt
14 0
|
18天前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的餐馆点餐系统附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的餐馆点餐系统附带文章和源代码设计说明文档ppt
17 0
|
18天前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的影视创作论坛附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的影视创作论坛附带文章和源代码设计说明文档ppt
19 0
|
18天前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的航空票务推荐系统附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的航空票务推荐系统附带文章和源代码设计说明文档ppt
15 0
|
18天前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的仓库管理系统附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的仓库管理系统附带文章和源代码设计说明文档ppt
19 0