设计模式之抽象文档模式 _ JAVA
来自维基百科的介绍——抽象文档模式
面向对象的结构设计模式,用于在松散类型的键值存储中组织对象并使用类型化视图公开数据。该模式的目的是在强类型语言中实现组件之间的高度灵活性,其中可以动态地将新属性添加到对象树,而不会失去对类型安全的支持。该模式利用特征将类的不同属性分成不同的接口。“文档”的灵感来自面向文档的数据库。
抽象文档模式的适用性和特点
需要动态添加新属性时而不影响组织结构,类属性变化频率较大
想要一种灵活的方式来组织树状结构中的域
想要更松散耦合的系统
通过集合存储属性
建立属性表统一维护类的属性
通过接口来配置获取和添加属性的方式
实例
1.抽象出基类,提供存储属性的集合。2.通过接口定义存储和获取的方法
HasType 类型属性
HasPrice 价格属性
HasColor 颜色属性
HasSize 尺码属性
HasSeason 季节属性
HasClothes 用于关联下级映射关系
Goods 商品父接口
Hat 帽子实体
Clothes 衣服实体
Costume 服饰实体,实现HasClothes即可设置Clothes相关属性
/** * 衣服类别 */ public interface HasClothes extends Goods { String PROPERTY = "clothes"; default StreamgetClothes() { return children(PROPERTY, Clothes::new); } }
/** * 颜色属性 */ public interface HasColor extends Goods { String PROPERTY = "color"; default OptionalgetColor() { return Optional.ofNullable((String) get(PROPERTY)); } }
/** * 价格属性 */ public interface HasPrice extends Goods { String PROPERTY = "price"; default OptionalgetPrice() { return Optional.ofNullable((String) get(PROPERTY)); } }
/** * 季节属性 */ public interface HasSeason extends Goods { String PROPERTY = "season"; default OptionalgetSeason() { return Optional.ofNullable((String) get(PROPERTY)); } }
/** * 尺码属性 */ public interface HasSize extends Goods { String PROPERTY = "size"; default OptionalgetSize() { return Optional.ofNullable((String) get(PROPERTY)); } }
/** * 类型属性 */ public interface HasType extends Goods { String PROPERTY = "type"; default OptionalgetType() { return Optional.ofNullable((String) get(PROPERTY)); } }
/** * 商品接口的抽象实现 */ public abstract class AbstractGoods implements com.company.base.Goods { private final Mapproperties; protected AbstractGoods(Mapproperties) { // JDK工具类,是一些静态方法组成,主要用于操作对象、计算对象的哈希码,返回对象的字符串和比较两个对象 Objects.requireNonNull(properties, "properties map is required"); this.properties = properties; } @Override public Object get(String key) { return properties.get(key); } @Override public void put(String key, Object value) { properties.put(key, value); } @Override publicStreamchildren(String key, Function<Map, T> constructor) { Optional<List<Map>> any = Stream.of(get(key)).filter(el -> el != null).map(el -> (List<Map>) el).findAny(); return any.isPresent() ? any.get().stream().map(constructor) : Stream.empty(); } }
/** * 商品的超级接口 */ public interface Goods { void put(String key, Object value); Object get(String key);Streamchildren(String key, Function<Map, T> constructor); }
/** * 衣服的实体类 */ public class Clothes extends AbstractGoods implements HasPrice, HasColor, HasType, HasSize { public Clothes(Mapproperties) { super(properties); } }
/** * 服饰的实体 */ public class Costume extends AbstractGoods implements HasSeason, HasClothes{ public Costume(Mapproperties) { super(properties); } }
/** * 帽子的实体类 */ public class Hat extends AbstractGoods implements HasPrice, HasColor, HasType, HasSize { public Hat(Mapproperties) { super(properties); } }
/** * 一种面向对象的结构设计模式,用于在松散类型的键值存储中组织对象并使用类型化视图公开数据。 * 该模式的目的是在强类型语言中实现组件之间的高度灵活性,其中可以动态地将新属性添加到对象 * 树,而不会失去对类型安全的支持。该模式利用特征将类的不同属性分成不同的接口 */ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); public App() { MapclothesProperties = new HashMap<>(); clothesProperties.put(HasSize.PROPERTY, "XXL"); clothesProperties.put(HasPrice.PROPERTY, "399元"); clothesProperties.put(HasColor.PROPERTY, "棕色带图案"); clothesProperties.put(HasType.PROPERTY, "男士上衣"); Mapclothes1Properties = new HashMap<>(); clothes1Properties.put(HasSize.PROPERTY, "中号"); clothes1Properties.put(HasPrice.PROPERTY, "188元"); clothes1Properties.put(HasColor.PROPERTY, "黑色"); clothes1Properties.put(HasType.PROPERTY, "鸭舌帽"); MapcostumeProperties = new HashMap<>(); costumeProperties.put(HasSeason.PROPERTY, "春季新款"); costumeProperties.put(HasClothes.PROPERTY, Arrays.asList(clothesProperties, clothes1Properties)); com.company.Costume costume = new com.company.Costume(costumeProperties); LOGGER.debug("季节上新:"); LOGGER.debug("-------------------------"); LOGGER.debug("--> 季节: {}", costume.getSeason().get()); LOGGER.debug("--> 明细: "); costume.getClothes().forEach(clothes -> LOGGER.debug("--> {}/{}/{}/{}", clothes.getPrice().get(), clothes.getColor().get(), clothes.getSize().get(), clothes.getType().get())); } public static void main(String[] args) { new App(); } }
总结
所有的属性都通过Map存储。所以存储的时候不需要关心具体的类型是什么。
对象可以有子对象。比如,Costume有Hat,Clothes。Hat和Clothes都是子对象。通过Costume可以获得Hat和Clothes子对象,通过子对象设置和获取子对象的属性。
通过继承接口,实现获取类型相关的属性。Costume继承并实现接口HasSeason。如果想获得 Costume的season属性,需要调用getSeason().get()。从而实现取出的属性类型相关。
通过基类封装基本操作。这样不同Costume或者Costume和Hat、Clothes之间可以共享实现。
推荐阅读
-
Java实战之医院管理系统的实现
-
elasticsearch索引index之Translog数据功能分析
-
java实现简单发送邮件功能
-
Java实现图片比率缩放
-
Java中的JetCache 实战
-
elasticsearch索引index之engine读写控制结构实现
-
elasticsearch索引index之Mapping实现关系结构示例
-
LeetCode 动态规划之矩阵区域和详情
-
elasticsearch索引的创建过程index create逻辑分析
目录索引的创建过程materOperation方法实现clusterservice处理建立索引修改配置总结索引的创建过程从本篇...
-
java实现上传图片尺寸修改和质量压缩
本文实例为大家分享了java实现上传图片尺寸修改和质量压缩的具体代码,供大家参考,具体内容如下packagecom.zity....