"围观"设计模式(13)--结构型之装饰模式(Decorator Pattern)

时间:2023-02-03 10:40:28

修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。----WIKIPEDIA


个人理解

相比而言我对装饰模式的理解还不是很深入,在项目中还不知道该怎么去使用它,或许是没有遇到需要装饰模式的情景吧,我对于装饰模式的理解是通过装饰模式可以实现对功能的扩充,由此我想到了面向切面编程,因为我记得AOP在实现的时候,就是对类的功能进行增强,可以在方法调用前执行、调用后、异常时等发生的时候去执行相应的处理,我在想会不会实现的时候采用的模式就是装饰模式呢?这里我先留着这个疑问后期有时间看源码的话再去探讨到底是不是用了这个模式。装饰模式中可以通过构造函数传入要装饰的类的实例,装饰类和被装饰的类要有相同的接口,保证当装饰类没有进行增强处理的时候,依然可以去执行被装饰类应该执行的方法。


实例演示


假设有这样的一个业务需要处理,比如保存数据到数据库中去,那么我想对这个数据库操作加事务机制,防止多个事务中某个事务失败而其他的事务成功造成数据不完整的问题。拿用户当做例子,假设用户信息除了包括基本的文本信息之外还要有多个头像,这样的话,需要保证用户基本信息保存也要保证头像的信息也保存了,那么需要对这两个保存的操作增加事务的装饰。


"围观"设计模式(13)--结构型之装饰模式(Decorator Pattern)

这样设计,你会发现这样的话,在UserDaoDecorator类和Dao会直接耦合,不是很好,我们在Decorator类之上再抽象出一个抽象类,让抽象类实现Dao并创建用于接收UserDao的实例,避免UserDaoDecorator直接与其他类耦合。


"围观"设计模式(13)--结构型之装饰模式(Decorator Pattern)

在UserDaoDecoratorParent抽象类中构造方法可以强制其子类实现带参数的构造方法。

主要的类如下(全部代码下载地址:设计模式代码下载地址):

public interface Dao {

public void saveUser(String user);

public void saveHeadImages(String[] images);

public void saveAll(String user, String[] images);
}

public class UserDao implements Dao{

@Override
public void saveUser(String user) {
System.out.println("保存用户基本信息:" + user);
}

@Override
public void saveHeadImages(String[] images) {
String imageInfo = "";
int index = 1;
for (String image : images) {
if(index == 1){
imageInfo += "index:"+ index + ""+ image;
}else{
imageInfo += "——index:"+ index + ""+ image;
}
index ++;
}
// ----->上面步骤打印辅助操作
System.out.println("保存用户头像:" + imageInfo);
}

@Override
public void saveAll(String user, String[] images) {
this.saveUser(user);
this.saveHeadImages(images);
}


}
装饰类的抽象类,实现了Dao接口,保证其子类和UserDao拥有同样的接口。
public abstract class UserDaoDecoratorParent implements Dao {

protected Dao userDao;

public UserDaoDecoratorParent(Dao userDao) {
super();
this.userDao = userDao;
}

public abstract void startTranscation();

public abstract void stopTranscation();

}

装饰类的具体实现

public class UserDaoDecorator extends UserDaoDecoratorParent {

public UserDaoDecorator(Dao userDao) {
super(userDao);
}

@Override
public void saveUser(String user) {
userDao.saveUser(user);
}

@Override
public void saveHeadImages(String[] images) {
userDao.saveHeadImages(images);
}

@Override
public void saveAll(String user, String[] images) {
// 开启事务
this.startTranscation();

this.saveUser(user);
this.saveHeadImages(images);

// 结束事务
this.stopTranscation();
}

@Override
public void startTranscation() {
System.out.println("开启事务..");
}

@Override
public void stopTranscation() {
System.out.println("关闭事务..");
}


}

装饰模式的优点

1.  装饰类和被装饰类可以独立发展而不会相互耦合,就是说装饰类不需要知道被装饰类的存在,而Decorator也不用知道装饰类的内部组成。

2.  装饰模式动态的扩展一个装饰类的功能。


装饰模式的缺点

多层的装饰比较复杂,尽量减少装饰类的数量,降低复杂度。