装饰模式实战

x33g5p2x  于2022-05-16 转载在 其他  
字(2.9k)|赞(0)|评价(0)|浏览(249)

一 点睛

装饰模式是指在不影响原有对象的情况下,动态地、无侵入地给一个对象添加一些额外的功能,如下这条 I/O 语句。
InpurStreamReader iReader = new InputStreamReader(new FileInputStream(new File("D:\abc.txt")));

如果把 D:\abc.txt 看作被装饰的对象,以上语句就依次对该对象进行了以下3步的包装。

new File("D:\abc.txt") 将字符串对象包装成了一个 File 对象,此时 File 对象包含了原字符串的内容。

new FileInputStream(...) 将 File 对象包装成了一个 FileinputStream 对象,此时 FileInputStream 包含了原 File 对象和原字符串的内容。

new InputStreamReader(...) 将 FileinputStream 对象包装成了一个 InputStreamReader 对象,此时 InputStreamReader  包含了原 FileInputStream 对象、原 File 对象和原字符串的内容。

可以发现,装饰模式可以让原对象经过一次次的包装,逐步拥有更强大的功能。因此在开发时,可以通过装饰模式对各个功能进行模块化封装。例如,如果要给对象 A 依次增加 X、Y 两个功能,就只需要对 A 进行两次包装即可。在 I/O 的设计中就大量使用到了这种装饰模式。

装饰模式包含了以下两个角色

1 被装饰的对象

1)抽象构建角色(Component)

被装饰对象的抽象接口。后续可以通过装饰者对该对象进行动态装饰。

2)具体构件角色(ConcreteComponent)

具体的对象,即抽象构建的一个实现类。

2 装饰者

1)装饰角色(Decorator)

装饰抽象类,需要继承自 Component,用于装饰(扩展)Component 中定义的方法。语法上,装饰对象包含了一个对真实对象的引用。

2)具体装饰(ConcreteDecorator)角色:具体的装饰者,即装饰角色的一个实现类。

二 实战

1 说明

Phone 接口用于定义手机的基本功能是打电话call(),BasePhone 类是 Phone 的一个实现类,实现了 call() 定义的方法。SmallPhone 是 Phone 的一个装饰者,用于扩展 Phone 的功能。第一种装饰方式为 AISmartPhone,即给电话增加“人工智能”的功能;第二种装饰方式为 AutoSizeSmartPhone,即给电话增加“自动伸缩”的功能。

2 代码

a 抽象构建角色(Component)

package decorator;

// 抽象构件角色(Component)
public interface Phone {
    void call();
}

b 具体构建角色(ConcreteComponent)

package decorator;

// 具体构件角色(ConcreteComponent)
public class BasePhone implements Phone {
    @Override
    public void call() {
        System.out.println("打电话");
    }
}

c 装饰角色(Decorator)

package decorator;

// 装饰角色(Decorator)
public abstract class SmartPhone implements Phone {
    private Phone phone;

    public SmartPhone(Phone phone) {
        super();
        this.phone = phone;
    }

    @Override
    public void call() {
        phone.call();
    }
}

d 第一个具体装饰角色(ConcreteDecorator)

package decorator;

public class AISmartPhone extends SmartPhone {
    public AISmartPhone(Phone phone) {
        super(phone);
    }

    // 给电话增加新的功能:人工智能
    public void aiFunction() {
        System.out.println("电话拥有人工智能的强大功能");
    }

    public void call() {
        super.call();
        aiFunction();
    }
}

e 第一个具体装饰角色(ConcreteDecorator)

package decorator;

public class AutoSizeSmartPhone extends SmartPhone {
    public AutoSizeSmartPhone(Phone phone) {
        super(phone);
    }

    // 给电话增加新的功能:手机尺寸自动伸缩
    public void autoSize() {
        System.out.println("手机的尺寸可以自动伸缩");
    }

    public void call() {
        super.call();
        autoSize();
    }
}

f 测试类

package decorator;

public class Test {
    public static void main(String[] args) {
        // 基础的电话功能
        System.out.println("--基础的电话功能--");
        BasePhone basePhone = new BasePhone();
        basePhone.call();

        // 进行 AISmartPhone 装饰后的电话
        System.out.println("\n--智能手机:增加了AI的功能--");
        AISmartPhone AISmartPhone = new AISmartPhone(basePhone);
        AISmartPhone.call();

        // 进行AutoSizeSmartPhone装饰后的电话
        System.out.println("\n--智能手机:增加了自动伸缩的功能--");
        AutoSizeSmartPhone autoSizeSmartPhone = new AutoSizeSmartPhone(basePhone);
        autoSizeSmartPhone.call();

        //进行AISmartPhone及AutoSizeSmartPhone两次装饰后的电话
        System.out.println("\n--智能手机:增加了AI和自动伸缩的功能--");
        SmartPhone smartPhone = new AutoSizeSmartPhone(new AISmartPhone(basePhone));
        smartPhone.call();
    }
}

3 测试结果

--基础的电话功能--
打电话

--智能手机:增加了AI的功能--
打电话
电话拥有人工智能的强大功能

--智能手机:增加了自动伸缩的功能--
打电话
手机的尺寸可以自动伸缩

--智能手机:增加了AI和自动伸缩的功能--
打电话
电话拥有人工智能的强大功能
手机的尺寸可以自动伸缩

Process finished with exit code 0

相关文章