装饰模式 (Decorator) (包装模式Wrapper)
定义:
动态的给对象添加一些额外的功能(比继承更加灵活)
人靠衣装,佛靠金装
透明的给对象增加功能
功能组合
为什么装饰类需要继承被装饰类,因为装饰类还可以再一次被装饰
角色
Component 抽象组件,被装饰的原始对象
ConcreteComponent 组件的具体实现,被装饰的具体对象
Decorator 抽象装饰者(1.继承于Component 2.持有被装饰对象的引用)
ConcreteDecorator 具体的装饰实现
装修墙
奖金计算简化
每个人当月业务奖金 = 当月销售额 * 3%
每个人累计奖金 = 总的回款额 * 0.1%
团队奖金 = 团队总销售额 * 1%
计算方式要经常变动
给计算奖金对象,灵活的增加功能,动态的组合功能
IO
//IO
//读文本一个字符字符读取,读视频数据一个字节读取
//字符流,字节流
//通过字节流读取一个一个的字符?让字节流具备读取字符的功能
try {
File file = new File("a.txt");
FileInputStream in = new FileInputStream(file);
//读取字符,装饰对象增加读取字符的功能
//reader 装饰对象
InputStreamReader reader = new InputStreamReader(in);
//char ch = (char)reader.read();
//继续增加功能,一行行读取
BufferedReader br = new BufferedReader(reader);
br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
本质:动态组合
优点:
比继承灵活(原则:尽量使用对象组合而不是继承)
简化高层定义
缺点:会产生很多细粒度的对象
场景:动态透明的给对象添加功能(功能组合),不适合通过继承添加功能
相关代码:
被装饰者接口类:
/**
* 人,抽象的组件类
* @date 2016年2月20日
*/
public abstract class Person {
/**
* 抽象的穿衣方法
*/
public abstract void dressed();
}
/**
* 男孩,具体的被装饰的类
* @date 2016年2月20日
*/
public class Boy extends Person{
@Override
public void dressed() {
System.out.println("穿了内衣内裤");
}
}
装饰者接口类:
/**
* 衣服,抽象的装饰类
* @date 2016年2月20日
*/
public abstract class Cloth extends Person {
private Person p;
public Cloth(Person p) {
super();
this.p = p;
}
@Override
public void dressed() {
p.dressed();
}
}
/**
* 便宜衣服
* @date 2016年2月20日
*/
public class CheapCloth extends Cloth {
public CheapCloth(Person p) {
super(p);
}
@Override
public void dressed() {
super.dressed();
dressShorts();
}
private void dressShorts(){
System.out.println("穿条短裤");
}
}
/**
* 贵的衣服,具体的装饰类
* @date 2016年2月20日
*/
public class ExpensiveCloth extends Cloth {
public ExpensiveCloth(Person p) {
super(p);
}
@Override
public void dressed() {
super.dressed();
dressShirt();
dressJean();
}
private void dressShirt(){
System.out.println("穿件短袖");
}
private void dressJean(){
System.out.println("穿件牛仔裤");
}
}
代码调用:
public class Client {
public static void main(String[] args) {
//被装饰对象,男孩
Boy boy = new Boy();
//装饰对象,贵的衣服
ExpensiveCloth c2 = new ExpensiveCloth(boy);
//装饰对象,便宜的衣服
CheapCloth c1 = new CheapCloth(c2);
//c1.dressed();
c1.dressed();
}
}
调用结果:
穿了内衣内裤
穿件短袖
穿件牛仔裤
穿条短裤
整理自教程