设计模式之抽象文档模式 -mile米乐体育
java学习
2020年04月19日 22:35
0
来自维基百科的介绍——抽象文档模式
面向对象的结构设计模式,用于在松散类型的键值存储中组织对象并使用类型化视图公开数据。该模式的目的是在强类型语言中实现组件之间的高度灵活性,其中可以动态地将新属性添加到对象树,而不会失去对类型安全的支持。该模式利用特征将类的不同属性分成不同的接口。“文档”的灵感来自面向文档的数据库。
抽象文档模式的适用性和特点
需要动态添加新属性时而不影响组织结构,类属性变化频率较大
想要一种灵活的方式来组织树状结构中的域
想要更松散耦合的系统
通过集合存储属性
建立属性表统一维护类的属性
通过接口来配置获取和添加属性的方式
实例
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
/** * 商品的超级接口 */ public interface goods { void put(string key, object value); object get(string key);streamchildren(string key, function
/** * 衣服的实体类 */ 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之间可以共享实现。
展开全文