A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 韩秀山 中级黑马   /  2013-5-15 21:27  /  1982 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

装饰类是什么?是封装类吗?他们有什么关系?什么时候使用装饰类??他的作用是什么??

3 个回复

倒序浏览
装饰设计模式
概念: 当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有功能,并提供加强功能 那么自定义的该类称为装饰类
由来:举例说明
例如现在有如下类的设计用于读取数据
[java] view plaincopy
MyReader//专门用于读取数据的类。  
    |--MyTextReader//用于读取文本  
    |--MyMediaReader//用于读取媒体  
后来发现两个子类的读取功能太差,就想引入缓冲技术,从继承角度思考,我们需要把每一个类分别创建子类,增加缓冲的功能,于是改变其体系结构如下
[java] view plaincopy
MyReader//专门用于读取数据的类。  
    |--MyTextReader//用于读取文本  
        |--MyBufferTextReader  
    |--MyMediaReader//用于读取媒体  
        |--MyBufferMediaReader  
这样一来 如果MyReader类再有新的子类,我们还要再创建其子类的带有缓冲功能的子类,如下
[java] view plaincopy
MyReader//专门用于读取数据的类。  
    |--MyTextReader//用于读取文本  
        |--MyBufferTextReader  
    |--MyMediaReader//用于读取媒体  
        |--MyBufferMediaReader  
    |--MyDataReader//用于读取数据  
        |--MyBufferDataReader  
不难发现,这样的体系结构有两个缺点:1、扩展性极差;2、体系臃肿
于是我们想能不能把带有缓冲技术的子类抽取出来,做一个公共的类,将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。这样继承体系就变得很简单。优化了体系结构。
于是写一个有缓冲功能的类

[java] view plaincopy
class MyBufferReader  
{  
     MyBufferReader(MyTextReader text){}  
     MyBufferReader(MyMediaReader media){}  
}  
发现这样扩展性很差,于是找到其参数的共同类型,使用多态的形式,提高了程序的扩展性,修改如下
[java] view plaincopy
class MyBufferReader extends MyReader  
{  
         private MyReader r;  
         MyBufferReader(MyReader r){}  
}   
这里MyBufferReader就是所谓的装饰类,之所以要继承MyReader,装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。这样类的结构就改变为
[java] view plaincopy
MyReader//专门用于读取数据的类。  
         |--MyTextReader  
         |--MyMediaReader  
         |--MyDataReader  
         |--MyBufferReader  
装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。
回复 使用道具 举报
Java装饰模式
装饰模式:给一个类添加一些额外的职责,并且在添加这些额外的职责时不会控制该类的执行逻辑。
回复 使用道具 举报
Java装饰模式
装饰模式:给一个类添加一些额外的职责,并且在添加这些额外的职责时不会控制该类的执行逻辑。

UML类图:


组成部分:
抽象构件:原始的功能接口
具体构件:具体的原始功能类
装饰角色:持有具体构件类的对象,以便执行原有功能
具体装饰:具体扩展的功能在这里

下面看一个对开车功能拓展的实例(晚上+开车):
抽象构件:

Java代码  
1.package com.gjy.drector;   
2.  
3./**  
4. * 抽象接口,规范准备接收附加责任的对象  
5. * @author gjy  
6. */  
7.public interface Component {   
8.    public void operation();   
9.}  
package com.gjy.drector;

/**
* 抽象接口,规范准备接收附加责任的对象
* @author gjy
*/
public interface Component {
        public void operation();
}

具体构件:

Java代码  
1.package com.gjy.drector;   
2.  
3./**  
4. * 接收附加责任, 此类型的类可以有多个, 只对应一个Decorator类  
5. * @author gjy  
6. */  
7.public class ConcreteComponent implements Component {   
8.    public ConcreteComponent(){}   
9.    public void operation()   
10.    {   
11.           System.out.println("开车");   
12.    }   
13.}  
package com.gjy.drector;

/**
* 接收附加责任, 此类型的类可以有多个, 只对应一个Decorator类
* @author gjy
*/
public class ConcreteComponent implements Component {
        public ConcreteComponent(){}
    public void operation()
    {
           System.out.println("开车");
    }
}

装饰角色:

Java代码  
1.package com.gjy.drector;   
2.  
3./**  
4. * 装饰角色,持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口  
5. * @author gjy  
6. */  
7.public class Decorator implements Component {   
8.    private Component component;   
9.    public Decorator(){}   
10.  
11.    public Decorator(Component component)   
12.    {   
13.           this.component = component;   
14.    }   
15.  
16.    public void operation() {   
17.           component.operation();   
18.    }   
19.}  
package com.gjy.drector;

/**
* 装饰角色,持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口
* @author gjy
*/
public class Decorator implements Component {
        private Component component;
    public Decorator(){}

    public Decorator(Component component)
    {
           this.component = component;
    }

    public void operation() {
           component.operation();
    }
}

具体装饰:

Java代码  
1.package com.gjy.drector;   
2.  
3./**  
4. * 添加附加责任  
5. * @author gjy  
6. */  
7.public class ConcreteDecorator extends Decorator {   
8.  
9.    public ConcreteDecorator(){}   
10.  
11.    public ConcreteDecorator(Component component)   
12.    {   
13.           super(component);   
14.    }   
15.  
16.    public void operation()   
17.    {   
18.         this.addedOperation();   
19.         super.operation();   
20.    }   
21.  
22.    public void addedOperation()   
23.    {   
24.           System.out.println("晚上");   
25.    }   
26.}  
package com.gjy.drector;

/**
* 添加附加责任
* @author gjy
*/
public class ConcreteDecorator extends Decorator {

        public ConcreteDecorator(){}

    public ConcreteDecorator(Component component)
    {
           super(component);
    }

    public void operation()
    {
             this.addedOperation();
         super.operation();
    }

    public void addedOperation()
    {
           System.out.println("晚上");
    }
}

测试:

Java代码  
1.package com.gjy.drector;   
2.  
3./**  
4. * 客户端类  
5. * @author gjy  
6. */  
7.  
8.public class Client {   
9.       public static void main(String[] args) {   
10.              Component component = new ConcreteComponent();   
11.              Decorator decorator = new ConcreteDecorator(component);   
12.              //客户端不变, 但已增加了责任   
13.              decorator.operation();   
14.                 
15.       }   
16.}  
package com.gjy.drector;

/**
* 客户端类
* @author gjy
*/

public class Client {
       public static void main(String[] args) {
              Component component = new ConcreteComponent();
              Decorator decorator = new ConcreteDecorator(component);
              //客户端不变, 但已增加了责任
              decorator.operation();
              
       }
}

输出结果:
晚上
开车

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马