筹划模式之装饰器模式

程序员 2024-9-30 00:20:22 117 0 来自 中国
也称装饰者模式、装饰器模式、Wrapper、Decorator。
装饰模式是一种结构型筹划模式, 允许你通过将对象放入包罗活动的特殊封装对象中来为原对象绑定新的活动。


办理方案
当你须要更改一个对象的活动时, 第一个跳入脑海的想法就是扩展它所属的类。 但是, 你不能忽视继续大概引发的几个严肃题目。
继续是静态的。 你无法在运行时更改已有对象的活动, 只能使用由差别子类创建的对象来更换当前的整个对象。
子类只能有一个父类。 大部分编程语言不允许一个类同时继续多个类的活动。
其中一种方法是用聚合组合, 而不是继续。 两者的工作方式险些千篇划一: 一个对象包罗指向另一个对象的引用, 并将部分工作委派给引用对象; 继续中的对象则继续了父类的活动, 它们本身可以或许完成这些工作。
你可以使用这个新方法来轻松更换各种毗连的 “小帮手” 对象, 从而能在运行时改变容器的活动。 一个对象可以使用多个类的活动, 包罗多个指向其他对象的引用, 并将各种工作委派给引用对象。 聚合 (或组合) 组合是很多筹划模式背后的关键原则 (包括装饰在内)。 
封装器是装饰模式的别称, 这个称谓明白地表达了该模式的紧张头脑。  “封装器” 是一个能与其他 “目的” 对象毗连的对象。 封装器包罗与目的对象类似的一系列方法, 它会将全部吸收到的哀求委派给目的对象。 但是, 封装器可以在将哀求委派给目的前后对其举行处理处罚, 以是大概会改变终极效果。


 装饰模式恰当应用场景
 假如你盼望在无需修改代码的环境下即可使用对象, 且盼望在运行时为对象新增额外的活动, 可以使用装饰模式。
 装饰能将业务逻辑构造为条理结构, 你可为各层创建一个装饰, 在运行时将各种差别逻辑组合成对象。 由于这些对象都依照通用接口, 客户端代码能以类似的方式使用这些对象。
 假如用继续来扩展对象活动的方案难以实现大概根本不可行, 你可以使用该模式。
 很多编程语言使用 final终极关键字来限定对某个类的进一步扩展。 复用终极类已有活动的唯一方法是使用装饰模式: 用封装器对其举行封装。


装饰模式优缺点
有点:
 你无需创建新子类即可扩展对象的活动。
 你可以在运行时添加或删除对象的功能。
 你可以用多个装饰封装对象来组合几种活动。
 单一职责原则。 你可以将实现了很多差别活动的一个大类拆分为多个较小的类。
缺点:
 在封装器栈中删除特定封装器比较困难。
 实现活动不受装饰栈次序影响的装饰比较困难。
 各层的初始化设置代码看上去大概会很糟糕。


Java 示例代码:
public class DecoratorPattern {
    public static void main(String[] args) {
        Person zhangsan = new Student("张三");
        zhangsan = new DecoratorA(zhangsan);
        zhangsan = new DecoratorB(zhangsan);
        zhangsan.Operation();
        System.out.println("\n=====我是分割线=====");
        // 对象链
        Person lisi = new DecoratorB(new DecoratorA(new Student("李四")));
    }
}
abstract class Decorator extends Person {
    protected Person person;
}
class DecoratorA extends Decorator {
    public DecoratorA(Person person) {
        this.person = person;
    }
    @Override
    public void Operation() { // 职责
        person.Operation(); // 原本的职责
        System.out.print("写作业 ");
    }
}
class DecoratorB extends Decorator {
    public DecoratorB(Person person) {
        this.person = person;
    }
    @Override
    public void Operation() { // 职责
        person.Operation(); // 原本的职责
        System.out.print("测验 ");
    }
}
abstract class Person {
    protected String name;
    public abstract void Operation(); // 职责
}
class Student extends Person {
    public Student(String name) {
        this.name = name;
    }
    @Override
    public void Operation() {
        System.out.print(name + "的职责:学习 ");
    }
}
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-24 04:13, Processed in 0.108665 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表