java 抽象属性 设计_设计模式之抽象文档模式

来自维基百科的介绍——

面向对象的结构

af0df95a2811d71b99d7f52fc2225591.gif

抽象文档模式的适用性和特点

需要动态添加新属性时而不影响组织结构,类属性变化频率较大

想要一种灵活的方式来组织树状结构中的域

想要更松散耦合的系统

通过集合存储属性

建立属性表统一维护类的属性

通过接口来配置获取和添加属性的方式

实例

1.抽象出基类,提供存储属性的集合。

2.通过接口定义存储和获取的方法

af0df95a2811d71b99d7f52fc2225591.gif代码示例类图

HasType 类型属性

HasPrice 价格属性

HasColor 颜色属性

HasSize 尺码属性

HasSeason 季节属性

HasClothes 用于关联下级映射关系

Goods 商品父接口

Hat 帽子实体

Clothes 衣服实体

Costume 服饰实体,实现HasClothes即可设置Clothes相关属性

/**

* 衣服类别

*/

public interface HasClothes extends Goods {

String PROPERTY = "clothes";

default Stream getClothes() {

return children(PROPERTY, Clothes::new);

}

}

/**

* 颜色属性

*/

public interface HasColor extends Goods {

String PROPERTY = "color";

default Optional getColor() {

return Optional.ofNullable((String) get(PROPERTY));

}

}

/**

* 价格属性

*/

public interface HasPrice extends Goods {

String PROPERTY = "price";

default Optional getPrice() {

return Optional.ofNullable((String) get(PROPERTY));

}

}

/**

* 季节属性

*/

public interface HasSeason extends Goods {

String PROPERTY = "season";

default Optional getSeason() {

return Optional.ofNullable((String) get(PROPERTY));

}

}

/**

* 尺码属性

*/

public interface HasSize extends Goods {

String PROPERTY = "size";

default Optional getSize() {

return Optional.ofNullable((String) get(PROPERTY));

}

}

/**

* 类型属性

*/

public interface HasType extends Goods {

String PROPERTY = "type";

default Optional getType() {

return Optional.ofNullable((String) get(PROPERTY));

}

}

/**

* 商品接口的抽象实现

*/

public abstract class AbstractGoods implements com.company.base.Goods {

private final Map properties;

protected AbstractGoods(Map properties) {

// 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

public Stream children(String key, Function, T> constructor) {

Optional>> any = Stream.of(get(key)).filter(el -> el != null).map(el -> (List>) 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);

Stream children(String key, Function, T> constructor);

}

/**

* 衣服的实体类

*/

public class Clothes extends AbstractGoods implements HasPrice, HasColor, HasType, HasSize {

public Clothes(Map properties) {

super(properties);

}

}

/**

* 服饰的实体

*/

public class Costume extends AbstractGoods implements HasSeason, HasClothes{

public Costume(Map properties) {

super(properties);

}

}

/**

* 帽子的实体类

*/

public class Hat extends AbstractGoods implements HasPrice, HasColor, HasType, HasSize {

public Hat(Map properties) {

super(properties);

}

}

/**

* 一种面向对象的结构设计模式,用于在松散类型的键值存储中组织对象并使用类型化视图公开数据。

* 该模式的目的是在强类型语言中实现组件之间的高度灵活性,其中可以动态地将新属性添加到对象

* 树,而不会失去对类型安全的支持。该模式利用特征将类的不同属性分成不同的接口

*/

public class App {

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

public App() {

Map clothesProperties = new HashMap<>();

clothesProperties.put(HasSize.PROPERTY, "XXL");

clothesProperties.put(HasPrice.PROPERTY, "399元");

clothesProperties.put(HasColor.PROPERTY, "棕色带图案");

clothesProperties.put(HasType.PROPERTY, "男士上衣");

Map clothes1Properties = new HashMap<>();

clothes1Properties.put(HasSize.PROPERTY, "中号");

clothes1Properties.put(HasPrice.PROPERTY, "188元");

clothes1Properties.put(HasColor.PROPERTY, "黑色");

clothes1Properties.put(HasType.PROPERTY, "鸭舌帽");

Map costumeProperties = 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("-->\t {}/{}/{}/{}",

clothes.getPrice().get(), clothes.getColor().get(),

clothes.getSize().get(), clothes.getType().get()));

}

public static void main(String[] args) {

new App();

}

}

af0df95a2811d71b99d7f52fc2225591.gif执行结果

总结

所有的属性都通过Map存储。所以存储的时候不需要关心具体的类型是什么。

对象可以有子对象。比如,Costume有Hat,Clothes。Hat和Clothes都是子对象。通过Costume可以获得Hat和Clothes子对象,通过子对象设置和获取子对象的属性。

通过继承接口,实现获取类型相关的属性。Costume继承并实现接口HasSeason。如果想获得 Costume的season属性,需要调用getSeason().get()。从而实现取出的属性类型相关。

通过基类封装基本操作。这样不同Costume或者Costume和Hat、Clothes之间可以共享实现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值