装饰类设计模式

来源:互联网 发布:macbook装机必备软件 编辑:程序博客网 时间:2024/05/29 18:32

装饰类是什么概念呢?如果已有的对象的功能不够优化,我们就可以定义类,将已有的对象传入,基于已有的功能,并提供加强的功能。那么该类就成为装饰类。装饰类通常会通过构造方法接受被装饰的对象。并基于被装饰的对象的功能来通过加强功能。首先我们先来看一个例子:

//早期的人的吃饭方式class Person{public void chifan(){System.out.println("吃饭");}}//现在增强版的人吃饭方式class SuperPerson{private Person p;//建立对象引用//通过构造方法接受被装饰的对象SuperPerson(Person p){this.p = p;}//加强人吃饭的功能public void superchifan(){System.out.println("开胃酒");//调用被装饰类对象已有的功能p.chifan();System.out.println("甜点");System.out.println("来一根");}}public class PersonDemo {public static void main(String[] args) {Person p = new Person(); SuperPerson sp = new SuperPerson(p);//展示增强后的人吃法功能sp.superchifan();}}
下面我让我们来看两个体系:

MyReader //自定义的专门用于读取资源的类

|--MyTextReader//具体负责读取文本资源的类

  |--MyBufferTextReader//加入缓冲区的读取文本资源的类

|--MyMediaReader//具体负责读取媒体资源的类

  |--MyBufferedMediaReader//加入缓冲区的读取媒体资源的类

|--MyDataReader//具体负责读取数据的类

  |--MyBufferedDataReader//加入了缓冲技术的读取数据类

该体系虽然能用,但是程序显着非常臃肿,扩展性极差,这个体系虽然能用,但是考虑到程序的扩展性和阅读性我们要对其优化。那么怎么优化呢?我们需要重新思考。我们发现MyBufferTextReader、MyBufferedMediaReader、MyBufferedDataReader都是用的缓冲技术,我们发现这些扩展出来的子类用的都是同一种技术,既然它们子类用的技术都是一样的,有必要给它们单独的定义成单独的子类吗?

我们可以单独定义一个BufferReader缓冲区,谁用到缓冲区就把谁传进来,只需要对使用者进行增强即可

class MyBufferReader{

MyBufferReader(MyTextReader text){}

MyBufferReader(MyMediaReader media){}

MyBufferReader(MyDataReader data){}

............

发现这样设计程序也很臃肿,如果多一个子类,该类的构造函数还需要添加子类的缓冲增强,这样做扩展性极差

}


解决上面类扩展性差的问题,找到其参数的共同类型。通过多态的形势,可以提高扩展性。这样带着缓冲技术的read类MyBufferReader就创建好了,代表着更强的读取行为,增强读取的功能,本质上还是读,可以看做MyReader的子类,让其继承MyReader。

class MyBufferReader extends MyReader{

private MyReader r;

MyBufferReader(MyReader r){}

}

这样体系就发生了一些变化:

MyReader//专门用于读取数据的类

|--MyTextReader

|--MyMediaReader

|--MyDataReader

|--MyBufferReader

显然下面的这个体系比上面的更优!设计模式是为了优化而来的,这样由原来的继承体系一优化完,变成了一个更简单的方式,扩展性比前面的体系强的多。我们就给这种模式其起了一个名字:装饰。

MyBufferReader里面没有什么东西,其存在都是基于MyTextReader、MyMediaReader、MyBufferReader进行的功能增强。

装饰模式比继承要灵活,避免了继承体系的臃肿。而且降低了类与类之间的联系。装饰类因为增强已有对象,具备的功能和已有对象时相同的,只不过提供提供了更强的功能。所以装饰类和被装饰类通常属于一个体系中。这就是装饰设计模式的特点。这样实际上继承结构就变成了组合结构。

在开发中,继承需要书写,但是不能以继承为主,因为继承仅仅是为了里面的具体的某几个功能产生子类的话,这样程序的体系是非常臃肿的!可以通过装饰方式扩展这些类的功能。灵活的体现:比如说有一个功能是一年前建立的,这这时你可以自己书写一个类,只需要把已有的类的对象参数传入,如果当新定义的类出现了问题,我们此时还可以继续使用原来已有的类。如上面一个例子,可以用SuperPerson该类的功能

<pre name="code" class="java">sp.superchifan(),也可以用Person类的chifan()功能,这样一来灵活性就相当的强啦!

0 0