设计模式之装饰器模式
装饰器模式
所有书本都有共性,把他们的共性提到一个父类中Book
public class AppTest{
public static void main(String[] args) {
Book book = new C();
System.out.println(book.getDescription());
}
}
abstract class Book{
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Book(String description) {
this.description = description;
}
//花费金额
public abstract double cost();
}
class C extends Book{
public C() {
super("c语言");
}
@Override
public double cost() {
return 98;
}
}书本是否升级了电子版和纸质版配套 以及等等功能
应对这种变化
代码可以这也写
是否为C语言类型的电子版纸质版配套创建一个类
class CWithElectronic extends Book{}
是否为C语言类型的配套其他纸质版课本
class CWithOther extends Book{}这样会使类的数量爆炸
- 针对上面的问题 我们可以添加对应的boolean值来代表是否加了对应的业务
boolean addElectronic; boolean addOther; if(addElectronic)... if(addOther).... 如果以后修改了新的需求 就要加入boolean 新需求 if(是否加了新需求).... 扩展性差
- 类没有爆炸,没有出现各种各样的类
- 新加新的饮料并不会带来什么影响,符合开闭原则
- 但是 添加新调料也就是新需求 就要破坏开闭原则
继装饰器讲解
abstract class Beverage{//饮料
protected String description;
public Beverage(String description){
System.out.println(description);
this.description = description;
}
public abstract double getCost();
//调用是这个getDescription 而不是子类中的
public String getDescription() {
System.out.println();
return description;
}
}
class Cecaf extends Beverage{//饮料
public Cecaf() {
super("无咖啡因的咖啡");
}
@Override
public double getCost() {
return 1;
}
}
//装饰器的核心思想 继承 搭配 组合
// 装饰器的继承并不是“is a”关系
abstract class Condiment extends Beverage{//调料
protected Beverage beverage;//调料关联饮料
public Condiment(Beverage beverage) {
super("调料");
this.beverage = beverage;//传入这个 特别关键
}
}
class Milk extends Condiment{//牛奶调料
public Milk(Beverage beverage) {
super(beverage);
}
@Override
public double getCost() {
return beverage.getCost() +0.2;
}
public String getDescription() {
return beverage.getDescription()+" 牛奶"; //添加关键
}
}
class Oil extends Condiment{//油调料
public Oil(Beverage beverage) {
super(beverage);
}
@Override
public double getCost() {
return beverage.getCost()+0.3;
}
public String getDescription() {
return beverage.getDescription() + " 油";
}
}
//============================
class Water extends Condiment{
public Water(Beverage beverage) {
super(beverage);
}
@Override
public double getCost() {
return beverage.getCost()+0.05;
}
@Override
public String getDescription() {
return beverage.getDescription()+" 水";
}
}
public class AppTest{
public static void main(String[] args) {
Beverage b = new Cecaf();
//作用是将Milk的参数 b的信息带入Milk 并不会去添加 "料理" 而字符串拼接仅在Milk中
Beverage b1 = new Milk(b);
Beverage b2 = new Milk(b1);
Beverage b3 = new Water(b2);
System.out.println(b3.getCost());
System.out.println(b3.getDescription());
}
}
装饰器的UML类图 继承+关联 来实现嵌套迭代效果
装饰器最典型代表 JDK 流 【字节流 字符流z】
自己写一个BufferedReader
- extends Reader : 以后能被包装 传到别的装饰器里
- private Reader in : 用Reader以前的方法 如read 利用读字符的功能来制作其他功能
public class AppTest{ public static void main(String[] args) throws IOException { Reader reader = new FileReader("F:\\a.txt"); MyBufferedReader mbr = new MyBufferedReader(reader); System.out.println(mbr.readLine()); System.out.println(mbr.readLine()); System.out.println(mbr.readLine()); System.out.println(mbr.readLine()); } } class MyBufferedReader extends Reader { private Reader in; public MyBufferedReader(Reader in) { this.in = in; } @Override public int read(char[] chars, int i, int i1) throws IOException { return 0; } @Override public void close() throws IOException { in.close(); } public String readLine() throws IOException { StringBuffer sb = new StringBuffer(); int i; while(true) { i = in.read(); if(i=='\r')//txt换行用\r\n continue; if(i=='\n' || i==-1) break; sb.append((char)i); } if(sb.toString().length()==0){ if(i=='\n') return ""; return null; } else return sb.toString(); } }
可以撤销装饰
https://blog.csdn.net/yqj2065/article/details/73551183
凡岛公司福利 528人发布
