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

什么是装饰者模式?

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

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

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

装饰者与继承的不同点.

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");
    }
}

这个代码有一点问题,没有时间去思考了.但是装饰者的大体思想这样.

原文地址:https://www.cnblogs.com/yinyu/p/5276694.html