Java 设计模式Android知识程序员

Java设计模式 - 装饰模式

2016-10-10  本文已影响128人  a57ecf3aaaf2

装饰模式

装饰模式重在“装饰”二字,这也是与代理模式的最大区别,很多人分不清两者的区别,甚至不假思索地就相信了网上以讹传讹的不正确的区别描述。

来看一个简单的装饰模式写法:

public abstract class Phone {
    /**
     * 加上保护套
     */
    public void attachJacket() {
        System.out.println("给手机加上保护套");
    }
}
public class IPhone extends Phone {

    /**
     * 贴膜
     */
    public void attachFilm() {
        System.out.println("给手机贴膜");
    }

    @Override
    public void attachJacket() {
        attachFilm();
        super.attachJacket();
    }
}

一个手机基类,一台iPhone手机是一台手机的属类,除了继承了基类“可添加保护套”的功能,也实现了自己的装饰:给手机贴膜。

装饰模式的核心就是在既有功能的前提下添加新的扩展功能。

以上例子是通过新增方法扩展功能的,下面介绍另一个列子,将每一个功能作为一个类,该类持有需要装饰者的实例:

public abstract class Phone {

    /**
     * 加上其他装饰
     */
    public void attach() {

    }
}
public class DecoratorPhone extends Phone {
    protected Phone phone;

    public DecoratorPhone(Phone phone) {
        this.phone = phone;
    }

    @Override
    public void attach() {
        phone.attach();
    }
}
public class FilmPhone extends DecoratorPhone {

    public FilmPhone(Phone phone) {
        super(phone);
    }

    @Override
    public void attach() {
        phone.attach();
        System.out.println("给手机贴膜");
    }
}
public class JacketPhone extends DecoratorPhone{
    public JacketPhone(Phone phone) {
        super(phone);
    }

    @Override
    public void attach() {
        phone.attach();
        System.out.println("给手机附上保护套");
    }
}
public class Client {
    public static final void main(String[] args) {
        Phone phone = new IPhone(); //待装饰对象
        FilmPhone fp = new FilmPhone(phone); //贴膜
        JacketPhone jp = new JacketPhone(fp); //添加手机套
        jp.attach();
    }
}

print:

给手机贴膜
给手机附上保护套

IPhone有其默认的装饰,通过FilmPhone持有IPhone实例,为IPhone添加贴膜装饰,JacketPhone再为其添加保护套。

JDK中的装饰模式

JDK中的输入、输出流就是典型的装饰模式,且大量使用了装饰模式与适配器模式。

FileInputStream fis = new FileInputStream("");
ObjectInputStream ois = new ObjectInputStream(fis);
ois.read();
public class ObjectInputStream
    extends InputStream implements ObjectInput, ObjectStreamConstants {
    
    public int read(byte[] buf, int off, int len) throws IOException {
        if (buf == null) {
            throw new NullPointerException();
        }
        int endoff = off + len;
        if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
            throw new IndexOutOfBoundsException();
        }
        return bin.read(buf, off, len, false);
    }
}

装饰模式和代理模式的区别

装饰模式和代理模式的区别,并非网上所说的装饰模式对外暴露被装饰者,而代理模式隐藏了被代理者,两者都可以通过构造函数传入被装饰或被代理对象。

装饰模式其实是代理模式中的一种特殊情况,其共同点是都具有相同的接口;不同的是,装饰模式重在对功能的增强或减弱,而代理模式注重控制代理者的权限,强制代理就是一个明显的区别。

本文由Fynn_原创,未经许可,不得转载!
上一篇 下一篇

猜你喜欢

热点阅读