装饰器模式
- 概述 : 动态的给一个对象添加一些额外的职责,就增加功能来说,装饰器模式相比生成子类更加灵活
- 维基百科解释 : 通过使用修饰模式,可以在运行时扩充一个类的功能.原理是 :增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数.装饰类实现新的功能,但是,在不需要用到新功能的地方,他可以直接调用原来的类中的方法.修饰类必须和原来的类有相同的接口.
- 使用场景
- 想要向一个现有的对象添加新的功能,同是又不改变其结构.这样可以在不增加子类的情况下扩展类
- 动态增加功能,动态撤销.
- 优点
- 装饰类和被装饰类可以独立发展,不会相互耦合.
- 装饰模式是继承的一个替代模式,但是他提供了比继承更多的灵活性.
- 装饰模式可以动态的方式扩展一个实现类的功能.在运行时选择不同的装饰器,从而实现不同的行为.
- 缺点
- 多层装饰比较复杂
例子
现在有
一幅画,想要加上
玻璃和
画框裱起来.用
装饰器模式来实现.不能改变画的结构.
java实现
- 做法 : 在装饰器类中添加一个被装饰类的实例,然后增加需要的功能并调用被装饰的类的方法.
- 类图
改错,上面的类图右边的地方不是接口,而是装饰类,画图的时候没有添加上.读者请注意,那是装饰类.
代码
画(Painting接口)
package Decorator;
/**
* Created by looper on 2017/8/16.
*/
public interface Painting {
public void show();
}
蒙娜丽莎(MonaLisa类 )
package Decorator;
/**
* Created by looper on 2017/8/16.
*/
public class MonaLisa implements Painting {
@Override
public void show() {
System.out.println("这是一副蒙娜丽莎的微笑");
}
}
装饰器类
package Decorator;
/**
* Created by looper on 2017/8/16.
*/
public class Decorator implements Painting {
private Painting painting;
public Decorator(Painting monaLisa){
this.painting = monaLisa;
}
@Override
public void show() {
System.out.println("先加上相框");
painting.show();
System.out.println("再扣上玻璃");
}
}
测试类
package Decorator;
/**
* Created by looper on 2017/8/16.
*/
public class DecoratorTest {
public static void main(String[] args) {
Painting painting = new MonaLisa();
Painting monaLisa = new Decorator(painting);
monaLisa.show();
}
}
代理器模式
- 概念:为其它对象提供一种代理以控制对这个对象的访问.
- 组成
- 抽象角色:通过接口或抽象类声明真实角色实现的业务方法.
- 代理角色:实现抽象角色,是真实角色的代理.通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作.
- 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用.
- 优点
- 职责清晰,真实角色就是实现实际的业务逻辑,不用担心其它非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简介清晰.
- 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用.
- 高扩展性
- 缺点
- 犹豫在客户端和真实角色之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢.
- 实现代理模式需要额外的工作,有些代理模式的实现非常复杂.
代码实现
示例:客户想要找房子,但是自己对周围的房价或者房源不怎么了解,所以想要通过中介来代理.使用代理模式完成这个场景.
共同的接口
package Proxy;
/**
* Created by looper on 2017/8/16.
*/
public interface Home {
public void selectHome();
}
客户类
package Proxy;
/**
* Created by looper on 2017/8/16.
*/
public class Custom implements Home {
@Override
public void selectHome() {
System.out.println("选择房子!!!");
}
}
中介类
package Proxy;
/**
* Created by looper on 2017/8/16.
*/
public class Intermediary implements Home {
private Custom custom;
public Intermediary(){
this.custom = new Custom();
}
@Override
public void selectHome() {
before();
custom.selectHome();
after();
}
private void before(){
System.out.println("中介找房源");
}
private void after(){
System.out.println("签合同");
}
}
测试类
package Proxy;
/**
* Created by looper on 2017/8/16.
*/
public class ProxyTest {
public static void main(String[] args) {
Home home = new Intermediary();
home.selectHome();
}
}
看了装饰器模式和代理模式会感觉两种模式几乎是一样的.
现在列出他们之间的区别:
装饰器模式
- 装饰器类和被装饰类实现同一个接口.
- 装饰器类关注于在一个对象上动态的添加方法.
- 强调:增强方法
代理模式
- 代理类和真实处理类实现同一个接口.
- 代理模式关注于控制对对象的访问,代理类通过代理模式向访问他的客户隐藏了真实调用的对象.
- 强调:增强
借用某个大佬博主的一句话来总结代理模式和装饰器模式
使用代理模式,代理和真实对象之间的关系在编译时就已经确定了,而装饰器者能够在运行时递归的被构造.(代理模式会在代理类中创建
真实处理类的一个实例,所以可以确定代理和真实对象的关系,而装饰器模式是将原始对象作为一个参数传给
装饰器类
)
我将23种设计模式的全部代码上传到CSDN,有用得到的同学 可以去下载.
下载地址 : 点我