装饰者模式(Decorate)
——给爱用继承的人一个全新的设计眼界
* 尽管继承威力强大,但是并不总是能够实现最有弹性和最好维护的设计。利用组合和委托可以在运行时具有继承行为的效果。
* 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。
* 代码应该如同晚霞中的莲花一样地关闭(免于改变),如同晨曦中的莲花一样地开发(能够扩展)。
设计原则
* 类应该对扩展开放,对修改关闭。
* 我们的目标是允许类容易扩展,在不修改现有代码的情况下,就可搭配新的行为。这样的设计具有弹性可以应对改变,可以接受新的功能来应对改变的需求。
* 在选择需要被扩展的代码部分时要小心。每个地方都采用开放-关闭原则,是一种浪费,也没必要,还会导致代码变得复杂且难以理解。
装饰者模式
* 装饰者模式动态地将责任附件到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案
* 装饰者和被装饰者对象有相同的超类型
* 可以用一个或多个装饰者包装一个对象
* 既然装饰者和被装饰者具有相同的超类型,所以在任何需要院士对象(被包装)的场合,可以用装饰过的对象代替
* 装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的
* 对象可以在任何时候被装饰,所以可以在运行时动态的、不限量地用装饰者来装饰对象
要点
* 继承属于扩展形式之一,但不见得是达到弹性设计的最佳方法
* 在我们的设计中,应该允许行为可以被扩展,而无须修改现有代码
* 组合和委托可用于在运行时动态地加上新的行为
* 除了继承,装饰者模式也可以让我们扩展行为
* 装饰者模式意味着一群装饰者类,这些类用来包装具体组件
* 装饰者反映出被装饰的组件类型
* 装饰者可以在被装饰者的行为前面或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的
* 可以用无数个装饰者包装一个组件
* 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型
* 装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂
相关推荐
策略模式: 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。 The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes ...
《Head First设计模式》是软件开发领域的一本经典著作,由Eric Freeman、Elisabeth Robson、Bert Bates和Kathy Sierra合著。这本书以独特的视觉和易理解的方式介绍了设计模式这一复杂的概念,旨在帮助初学者和有经验...
HeadFirst设计模式第01章C++,C#,Java代码实现。 其中包括了第02页,第05页,第22页的代码。 菜鸟原创。 From: http://blog.csdn.net/neicole/article/details/7994083
Django遵循模型-视图-控制器(MVC)设计模式,但稍有不同,它将其称为模型-视图-模板(MVT)。它的核心组件包括模型(Models)、视图(Views)、模板(Templates)和URL调度器(URLConf)。 2. 创建Django项目: ...
- 创建模型后,需要执行数据库迁移来更新数据库模式: ```bash $ python manage.py makemigrations $ python manage.py migrate ``` 3. **操作数据库:** - 使用Django ORM(对象关系映射)对数据库进行增删改...
Django 是一款用 Python 编写的高级 Web 开发框架,它遵循 MVC(Model-View-Controller)设计模式,旨在通过“ batteries included”(开箱即用)的方式简化 Web 开发过程。在 Django 中,表单(Form)是一个非常...
- **返回方法**: 设置$$return域值为1表示以只读模式返回。 #### 16. 刷新表单 - **刷新方法**: 通常使用客户端脚本或服务器端脚本来触发表单的重新加载。 #### 17. 怎样在文档里存照片? - **存储方法**: 可以...
- Regular Expression Matching: 给定一个输入字符串和一个模式,实现支持'.'和'*'的正则表达式匹配。 - Container With Most Water: 给定一个数组,其中每个元素代表一个宽度为1的柱子高度,要求找出两个柱子,使得...
raise IndexError('pop from empty stack') return self.stack.pop() def peek(self): return self.stack[-1] def size(self): return len(self.stack) ``` - **队列(Queue)**:队列也是一种线性数据结构...
它以其简洁的API和对MVVM(Model-View-ViewModel)设计模式的支持而受到开发者欢迎。在这个入门教程中,我们将深入探讨如何使用Taunus来开发你的第一个应用。 首先,确保你已经安装了Node.js,因为Taunus是用...
$full1 = "$first $second"; # 产生 Hello World $full2 = '$first $second';# 产生 $first $second 可以将字符和数字利用运算符号连接起来。字符被转化成数字,利用其最初位置。在PHP手册中有详细的例子。 数组与...
booter的格式可能根据LessOS的具体实现而有所不同,但通常会包括一些基本的初始化代码,比如设置堆栈指针、加载GDT和IDT、设置段寄存器、跳转到保护模式等。解析这部分代码需要理解汇编语言和x86体系结构。 在C语言...
3.4.2. 设计回顾 3.4.3. 配置选项 3.4.4. Resolvers 3.4.4.1. 文件 Resolver 3.4.5. 基本用法 4. Zend_Cache 4.1. 简介 4.2. 缓存原理 4.2.1. Zend_Cache 工厂方法 4.2.2. 标记纪录 4.2.3. 缓存清理 4.3. ...