黑马程序员技术交流社区

标题: 【石家庄校区】掌握java设计模式之装饰者模式 [打印本页]

作者: 坚持到底王宝    时间: 2018-6-27 23:00
标题: 【石家庄校区】掌握java设计模式之装饰者模式
本帖最后由 小石姐姐 于 2018-6-29 11:15 编辑

java的设计模式有23种 ,今天与大家分享一下其中的经典模式之一,装饰者模式.
一.定义: 装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
二.装饰者模式的特点:
(1)装饰者和被装饰者有相同的接口(或有相同的父类)。
(2)装饰者保存了一个被装饰者的引用。
(3)装饰者接受所有客户端的请求,并且这些请求最终都会返回给被装饰者(参见韦恩图)。
(4)在运行时动态地为对象添加属性,不必改变对象的结构。
三.适用性:
以下情况使用Decorator模式
1. 需要扩展一个类的功能,或给一个类添加附加职责。
2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
四.装饰者模式举例
                                                 
模型
[AppleScript] 纯文本查看 复制代码
interface Waiter{
    public void server();
}

public class Waitress implements Waiter{
    public void server(){
        System.out.println(“服务中…”);
    }
}

public class WaitressWrapper implements Waiter{
    private Waiter waiter;
    public WaitressWrapper(Waiter waiter){
        this.waiter = waiter;
    }

    public void server(){
        System.out.println(“微笑…”)
        waiter.server();
    }
}

五.个人理解
首先分析需求:装饰者模式的出现是因为之前有一个java类,但是它本身的方法不能满足要求,所以需要在不丧失原有功能的情况下,对它进行包装,以增强它的功能.既然叫装饰者模式,顾名思义,就是要装饰一个类,所以必须能够拿到被装饰类的一个引用,然后重写它之前的方法,或者增加方法.以实现功能的增强.例如大家熟知的IO流,FileReader是java.io.Reader的实现类,它可以读取文件,但是效率比较慢,并且只能一次读取一字符或字符数组,而通过装饰者模式,构建了BufferedReader类,BufferedReader类也实现了java.io.Reader接口,在创建BufferedReader对象时,我们传入被装饰的FileReader对象,就可以增强读取的功能,实现高效读取,并且可以实现一次读取一行数据.
我们学习的连接池,采用的也是相同的思路,原有的释放资源方法close(),由于现在的需求由摧毁Connection对象改为归还到连接池中,所以需要增强close()方法,


[AppleScript] 纯文本查看 复制代码
public class MyConnectionWrapper extends ConnectionWrapper{

    private Connection conn;
    private List<Connection> connList;

    public MyConnectionWrapper(Connection conn,List<Connection> connList) {
        super(conn);
        this.conn = conn;
        this.connList= connList;
    }
   
    // 增强某个方法:
    @Override
    public void close() throws SQLException {
//        super.close();
        // 归还连接:
        connList.add(conn);
    }

}

六.为什么使用装饰者而不使用继承?
我们知道要增强一个类的某个功能,其实不一定非要使用装饰者模式,使用继承重写方法一样可以解决,装饰者和集成一样都是要扩展对象的功能。那么为什么选用装饰者模式呢?
装饰模式可以提供比继承更多的灵活性。装饰模式允许动态增加或删除一个装饰的功能。继承需要在此之前就要确定好对应的类,,然后才能编写装饰类。而装饰者模式只需要实现同一个接口,并且在构造方法中利用多态传入一个类的引用即可.





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2