简介
* 特点:
* 在不改变原有对象的基础上, 将功能附加到对象上;
* 通过将附加功能剥离成类的方式, 简化原有类逻辑, 提供了比继承更弹性的替代方案;
* 属于结构型设计模式;
* 应用场景:
* 用于扩展一个类的功能, 或给一个类添加附加职责;
* 动态给对象添加功能, 这些功能可以再动态撤离;
* 比如: 装修时, 在不改变房子架构情况下, 为房子添加装饰;
* 装饰者模式和静态代理的区别:
* 装饰者模式更注重扩展;
* 房子装饰后还是房子, 煎饼加蛋还是煎饼;
* 静态代理不一定满足is-a , 更注重功能增强;
* 姑娘被代理后是媒婆, 售票处被代理后是黄牛;
* 装饰者代码特点:
* 装饰者和被装饰者都实现相同接口;(为了保留OOP关系)
* 前置考虑设计时使用装饰者模式;
* 装饰器在JDK中的应用:
* I/O体系都使用装饰器;
* InputStream , FileInputStream, BufferedInputStream
* 优点:
* 装饰器更加灵活的扩展 , 灵活组合, 即插即用;
* 完全符合开闭原则;
* 缺点:
* 会创建更多类, 添加系统复杂度;
* 动态装饰时, 多层装饰不利于阅读;
代码
介绍
* 买煎饼果子, 采用装饰者模式, 为煎饼果子加鸡蛋加香肠;
public abstract class IJianbing {
private double price;
private String own;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getOwn() {
return own;
}
public void setOwn(String own) {
this.own = own;
}
}
public class Jianbing extends IJianbing{
private double price = 8;
private String own = "一张煎饼";
public void create(){
System.out.println("制作煎饼!");
System.out.println(own);
System.out.println("价格: " + price);
}
@Override
public void setPrice(double price) {
// TODO Auto-generated method stub
this.price = price;
}
public String getOwn() {
return own;
}
public void setOwn(String own) {
this.own = own;
}
public double getPrice() {
return price;
}
}
public class AddEggJianbing extends IJianbing{
private double price = 2;
private String own = "加一个鸡蛋";
IJianbing jb;
public AddEggJianbing(IJianbing jb) {
this.jb = jb;
}
public IJianbing create(){
System.out.println("加一个鸡蛋");
setPrice(jb.getPrice() + price);
setOwn(jb.getOwn() + own);
System.out.println("价格: " + price);
return this;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getOwn() {
return own;
}
public void setOwn(String own) {
this.own = own;
}
}
public class AddXiangChangJianbing extends IJianbing{
private double price = 3;
private String own = "加一个香肠";
IJianbing jb;
public AddXiangChangJianbing(IJianbing jb) {
// TODO Auto-generated constructor stub
this.jb = jb;
}
public IJianbing create(){
System.out.println("加一个香肠");
setPrice(jb.getPrice() + price);
setOwn(jb.getOwn() + own);
System.out.println("价格: " + price);
return this;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getOwn() {
return own;
}
public void setOwn(String own) {
this.own = own;
}
}
public class Test {
public static void main(String[] args) {
Jianbing jb = new Jianbing();
jb.create();
AddEggJianbing ajb = new AddEggJianbing(jb);
ajb.create();
AddXiangChangJianbing acjb = new AddXiangChangJianbing(ajb);
acjb.create();
System.out.println("现在煎饼的价格: " + acjb.getPrice());
System.out.println("现在的煎饼: " + acjb.getOwn());
}
}
制作煎饼!
一张煎饼
价格: 8.0
加一个鸡蛋
价格: 10.0
加一个香肠
价格: 13.0
现在煎饼的价格: 13.0
现在的煎饼: 一张煎饼加一个鸡蛋加一个香肠