您的位置:首页 > 编程语言 > Java开发

java设计模式4-装饰者模式

2016-03-14 18:33 459 查看
什么是装饰者模式?

在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

重点理解一句话:动态的扩展一个对象的功能.

我理解的装饰者模式:把一个东西用另一个东西来包装一下,以增加这个东西本身的功能.

装饰者与继承的不同点.

Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。

装饰者模式设计原则(了解):

1,多用组合,少用继承.

   利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为.然而,如果有组合的做法扩展对象的行为,就可以运行进动态地进行扩展.

   在前面提到策略模式中也提到了,多用组合.那么策略模式装饰者有什么不一样的呢?

    1,装饰对象包含一个真实对象的引用,而策略模式里面持有的是同一类行为接口的引用.传入的时候是传入接口的实现类.

2,类设计应该对扩展开放,对修改关闭.

什么情况下要用装饰者模式.

要添增加一个类的功能的时候,不能改变这个类的代码.

javaIO典型的装饰者模式理解.

超类输入流:InputStream

两个分支:

  1个是主体的分支.FileInputStrean,StringBufferInputString,ByteArrayInputStrean.

  2,装饰者中间层,FilterInpuStrean

         BufferInputStrean DataInputStream LineNumberInputStrean

现在我们要自己的扩展一个装饰者模式,大所有小写自动转成大写的流UpperCaseInputStream.

package com.java.jikexueyuan.myiodecorator;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
//直接继承分支的中间层.
//因为分支的中间层已为我们设计好超类的引用
public class UpperCaseInputStream extends FilterInputStream{

//构造方法里面传入
protected UpperCaseInputStream(InputStream in) {
//可以用super是因了,FilterInputStream是一个分支的中间层
super(in);
}

//写自己的方法
public int read() throws IOException
{
int c=super.read();
return c==-1?c:Character.toUpperCase((char)(c));
}
public int read(byte[] b,int offset,int len) throws IOException
{
int result=super.read(b,offset,len);
for(int i=0;i<result;i++)
{
b[i]=(byte)Character.toUpperCase((char)(b[i]));
}

return result;
}
}


 

 

 

记住一点,每一个分支都要有中间成.用在作为装饰者类里面的引用

 

装饰者模式怎么设计

1,有一个抽象的超类,里面有抽象的方法,和一些共有属性字段信息.

2,然后就是主体部分,主体部分可以理解成抽象超类的子类.主体类可以有一个中间层.

//这是那个超类
public abstract class Animal {
//这是共有属性
public String language;

//get/set
//共有的方法
public abstract String  Speak();

}

//这个类就是那个中间层(这一层也可以省略)
public class Human extends Animal {

@Override
public String Speak() {
return super.language;
}

}
//这是主体分支,就是超类的子类.当然还可以扩展出很子类出来.只举一个例子.
public class Chinese extends Human {

public Chinese(){
super.language="汉语";
}

//这里是可以直接继承了Human类的Speak方法的.就要以不用在写了
}


下面才是真正的装饰者的部分:

1,同样要有一个中间层,(重点),主要就是这个中间层的设计.

2,直接分支--直接改写方法,或添加方法.

3,中间层这个类里面有一个超类的引用,通过构造方法传入(重点).

中间层类直接 继承超类,里面有一个超类的引用从构造方法传入.

然后就是一些自己的方法.

要装饰的类直接继承这个中间者类.

//功夫就是这个中间成.
public class Gongfu extends Animal{

Animal animal;
Gongfu(Animal animal) {
this.animal=animal;
}

public void gongfu(){
System.out.println("这个人会功夫");
}

是间层里面不用改变的方法直接调用父类来返回
@Override
public String Speak() {
return animal.Speak();
}
}

//用功夫来装饰一个人
public class Taiji extends Gongfu {

//这个会自动生成,因为Gongfu没有无参的构造方法
Taiji(Animal animal) {
super(animal);
}
public void taiji(){
System.out.println("这个人会taiji");
}
}


这个代码有一点问题,没有时间去思考了.但是装饰者的大体思想这样.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: