设计模式之装饰者模式
2015-12-10 13:18
323 查看
模式定义:
在不改变原来类文件和使用继承的情况下,动态扩展一些功能。通过一个包装对象来包裹真实的对象。
注意点:(1)装饰对象和真实对象具备相同的接口。客户可以像与真实对象的交互一样来与包装对象交互。
(2)装饰对象包含一个真实对象的引用。
(3)包装对象接收来自客户的请求,并将之转发给真实对象。
(4)包装对象在转发这些请求的时候,附加一些功能。
遵循原则:
面向抽象编程,而不是面向实现编程;
优先使用对象组合而不是继承;
开闭原则;
封装变化部分。
适用场合:
(1)当我们需要动态地为对象增加功能;
(2)当对象的功能经常发生变化或者经常需要动态地增加功能时,避免为了适应这样的而变化而造成的类膨胀。
知识扩展:
JDK中的BufferedReader、BufferedWriter就是完美的实践者。
模式中的角色:
(1)被装饰者抽象【IBread】,是一个抽象类或者接口,是最基本的、原始的被装饰的对象。
(2)被装饰者具体实现类【NormalBread】,可以使一般实现类,也可以是装饰后的类。
(3)装饰者【AbstractBread】,一般是一个抽象类,里面必然含有被装饰者的引用。
(4)装饰者实现类【CornDecorator、SweetDecorator】,实现装饰效果。
烘烤面包的几个步骤
public interface IBread {
public void prepare();
public void kneadFlour();
public void stream();
public void process();
}
public class NormalBread implements IBread {
@Override
public void kneadFlour() {
System.out.println("和面");
}
@Override
public void prepare() {
System.out.println("准备蒸馒头");
}
@Override
public void stream() {
System.out.println("开始蒸");
}
@Override
public void process() {
this.prepare();
this.kneadFlour();
this.stream();
}
}
public abstract class AbstractBread implements IBread{
private final IBread bread;
public AbstractBread(IBread bread) {
this.bread = bread;
}
@Override
public void kneadFlour() {
bread.kneadFlour();
}
@Override
public void prepare() {
bread.prepare();
}
@Override
public void stream() {
bread.stream();
}
@Override
public void process() {
this.prepare();
this.kneadFlour();
this.stream();
}
}
装饰者增强功能
public class CornDecorator extends AbstractBread {
public CornDecorator(IBread bread) {
super(bread);
}
public void paint(){
System.out.println("黑心的商贩开始染色");
}
@Override
public void kneadFlour() {
//和面之前染色
this.paint();
super.kneadFlour();
}
}
public class SweetDecorator extends AbstractBread {
public SweetDecorator(IBread bread) {
super(bread);
}
public void paint(){
System.out.println("黑心的商贩开始加入甜蜜素");
}
@Override
public void kneadFlour() {
this.paint();
super.kneadFlour();
}
}
测试
public class Client {
public static void main(String[] args) {
IBread normalBread = new NormalBread();
new SweetDecorator(new CornDecorator(normalBread)).process();
}
}
在不改变原来类文件和使用继承的情况下,动态扩展一些功能。通过一个包装对象来包裹真实的对象。
注意点:(1)装饰对象和真实对象具备相同的接口。客户可以像与真实对象的交互一样来与包装对象交互。
(2)装饰对象包含一个真实对象的引用。
(3)包装对象接收来自客户的请求,并将之转发给真实对象。
(4)包装对象在转发这些请求的时候,附加一些功能。
遵循原则:
面向抽象编程,而不是面向实现编程;
优先使用对象组合而不是继承;
开闭原则;
封装变化部分。
适用场合:
(1)当我们需要动态地为对象增加功能;
(2)当对象的功能经常发生变化或者经常需要动态地增加功能时,避免为了适应这样的而变化而造成的类膨胀。
知识扩展:
JDK中的BufferedReader、BufferedWriter就是完美的实践者。
模式中的角色:
(1)被装饰者抽象【IBread】,是一个抽象类或者接口,是最基本的、原始的被装饰的对象。
(2)被装饰者具体实现类【NormalBread】,可以使一般实现类,也可以是装饰后的类。
(3)装饰者【AbstractBread】,一般是一个抽象类,里面必然含有被装饰者的引用。
(4)装饰者实现类【CornDecorator、SweetDecorator】,实现装饰效果。
烘烤面包的几个步骤
public interface IBread {
public void prepare();
public void kneadFlour();
public void stream();
public void process();
}
public class NormalBread implements IBread {
@Override
public void kneadFlour() {
System.out.println("和面");
}
@Override
public void prepare() {
System.out.println("准备蒸馒头");
}
@Override
public void stream() {
System.out.println("开始蒸");
}
@Override
public void process() {
this.prepare();
this.kneadFlour();
this.stream();
}
}
public abstract class AbstractBread implements IBread{
private final IBread bread;
public AbstractBread(IBread bread) {
this.bread = bread;
}
@Override
public void kneadFlour() {
bread.kneadFlour();
}
@Override
public void prepare() {
bread.prepare();
}
@Override
public void stream() {
bread.stream();
}
@Override
public void process() {
this.prepare();
this.kneadFlour();
this.stream();
}
}
装饰者增强功能
public class CornDecorator extends AbstractBread {
public CornDecorator(IBread bread) {
super(bread);
}
public void paint(){
System.out.println("黑心的商贩开始染色");
}
@Override
public void kneadFlour() {
//和面之前染色
this.paint();
super.kneadFlour();
}
}
public class SweetDecorator extends AbstractBread {
public SweetDecorator(IBread bread) {
super(bread);
}
public void paint(){
System.out.println("黑心的商贩开始加入甜蜜素");
}
@Override
public void kneadFlour() {
this.paint();
super.kneadFlour();
}
}
测试
public class Client {
public static void main(String[] args) {
IBread normalBread = new NormalBread();
new SweetDecorator(new CornDecorator(normalBread)).process();
}
}
相关文章推荐
- 最小生成树——[HAOI2006]聪明的猴子
- MVC
- php数组函数-array_keys()
- Leetcode--easy系列1
- 奇才三级分销系统简介
- 用shell批量修改文件名
- 正则表达式-理论基础篇
- 国信办主任回应中国删帖、屏蔽国外网站
- 正则表达式-理论基础篇
- 正则表达式-理论基础篇
- 【转】opencv+vs2013+cmake生成源码
- 正则表达式-理论基础篇
- Integer to English Words
- leetcode -- Reverse Words in a String -- 太简单,忽略
- zookeeper的Will not attempt to authenticate using SASL (无法定位登录配置)
- View的事件分发机制
- UDP punch(打洞|穿透)
- 从问题域出发认识Hadoop生态系统
- Intent android基础二
- windows系统版本号