設(shè)計(jì)模式———裝飾模式
例子:成績(jī)單報(bào)告
在面向?qū)ο蟮脑O(shè)計(jì)中伞辛,如果超過(guò)兩層繼承烂翰,可能就出設(shè)計(jì)問(wèn)題了。這是經(jīng)驗(yàn)總結(jié)蚤氏,并非定論甘耿。繼承層次越多,維護(hù)成本越多竿滨。
成績(jī)裝飾模型
增加一個(gè)抽象類(lèi)和兩個(gè)實(shí)現(xiàn)類(lèi)佳恬,其中Decorator的作用是封裝SchoolReort類(lèi)
抽象成績(jī)單
//抽象成績(jī)單
public abstract class SchoolReport{
public abstract void report();
public abstract void sign(String name);
}
具體的四年級(jí)成績(jī)
public abstract FourthGradeSchoolReport extends SchoolReport{
public void report(){
System.out.println("尊敬的XX家長(zhǎng)");
System.out.println("成績(jī)?nèi)缦?);
System.out.println("語(yǔ)文xx");
// ...
}
public void sign(String name){
System.out.println("家長(zhǎng)簽名為:"+name);
}
}
修飾的抽象類(lèi)
// 修飾的抽象類(lèi)
public abstract class Decorator extends SchoolReport{
private SchoolReport sr;
public Decorator(SchoolReport sr){
this.sr = sr;
}
// 報(bào)告成績(jī)
public void report(){
this.sr.report();
}
//家長(zhǎng)簽名
public void sign(String name){
this.sr.sign(name);
}
}
最高成績(jī)修飾
public class HighScoreDecorator extends Decorator {
public HighScoreDecorator(SchoolReport sr){
super(sr);
}
private void reportHighScore(){
System.out.println("最高成績(jī)是:XX");
}
public void report(){
this.reportHighScore();
super.report();
}
}
排名情況修飾
public class SortDecorator extends Decorator {
public SortDecorator(SchoolReport sr){
super(sr);
}
public void reportSort(){
System.out.println("排名情況是xx");
}
@Override
public void report(){
this.reportSort();
super.report();
}
}
查看成績(jī)單
public class Father{
public static void main(String[] args) {
//把成績(jī)單拿過(guò)來(lái)
SchoolReport sr;
//原裝的成績(jī)單
sr = new FourthGradeSchoolReport();
//加了最高分說(shuō)明的成績(jī)單
sr = new HighScoreDecorator(sr);
// 加了排名的說(shuō)明
sr = new SortDecorator(sr);
//看成績(jī)單
sr.report();
sr.sign("name");
}
}
裝飾模式的定義
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說(shuō)姐呐,裝飾模式相比生成子類(lèi)更為靈活殿怜。
裝飾模式
四個(gè)角色說(shuō)明
- component抽象構(gòu)件
- component是一個(gè)接口或者是抽象類(lèi),就是定義我們最核心的對(duì)象,也就是最原始的對(duì)象
- 在裝飾模式中,必然有一個(gè)最基本,最核心,也就是最原始的對(duì)象
- concreteComponent具體構(gòu)建
- concreteComponent是最核心,最原始,最基本的接口或抽象類(lèi)的實(shí)現(xiàn),要裝飾的就是它
- Decorator裝飾角色
- 一般是一個(gè)抽象類(lèi),實(shí)現(xiàn)接口或者抽象方法
- 它的屬性里必定有一個(gè)private變量指向Component抽象構(gòu)建
- ConcreteDecorator具體裝飾角色
- ConcreteDecoratorA和ConcreteDecoratorB是兩個(gè)具體的裝飾類(lèi),要把最原始,最基本,最核心的進(jìn)行裝飾
抽象構(gòu)件
public abstract class Component{
//抽象的方法
public abstract void operate();
}
具體構(gòu)件
public class ConcreteComponent extends Component {
// 具體實(shí)現(xiàn)
public void operate(){
// code to do something
System.out.println("doSomethin");
}
}
抽象裝飾者
public abstract class Decorator extends Component{
//必然有一個(gè)變量是抽象構(gòu)件
private Component component = null;
//通過(guò)構(gòu)造函數(shù)傳遞被修飾者
public Decorator(Component component){
this.component = component;
}
//委托給被修飾者執(zhí)行
@Override
public void operate(){
this.component.operate();
}
}
具體的裝飾類(lèi)
public class ConcreteDecorator1 extends Decorator{
public ConcreteDecorator1(Component component){
super(component);
}
//定義自己的修飾方法
public void method(){
//code to do something
}
public void operate(){
this.method();
super.operate();
}
}
public class ConcreteDecorator2 extends Decorator{
public ConcreteDecorator2(Component component){
super(component);
}
//定義自己的修飾方法
public void method(){
//code to do something
}
public void operate(){
this.method();
super.operate();
}
}
場(chǎng)景類(lèi)
public class Client{
public static void main(String[] args) {
Component component = new ConcreteComponent();
// 第一次修飾
component = new ConcreteDecorator1(component);
// 第二次修飾
component = new ConcreteDecorator2(component);
//運(yùn)行結(jié)果
component.operate();
}
}
裝飾模式的優(yōu)缺點(diǎn)
裝飾模式的優(yōu)點(diǎn)
- 裝飾類(lèi)和被裝飾類(lèi)可以獨(dú)立發(fā)展,不會(huì)相互耦合曙砂。
- Component類(lèi)無(wú)需知道Decorator類(lèi)头谜,Decorator類(lèi)是從外部來(lái)擴(kuò)展Component類(lèi)的功能,Decorator也不用知道具體的構(gòu)件
- 裝飾模式是繼承關(guān)系的一個(gè)替代方案
- 裝飾類(lèi)Decorator不管裝飾多少層鸠澈,返回的對(duì)象還是Component柱告,實(shí)現(xiàn)的還是is-a關(guān)系
- 裝飾模式可以動(dòng)態(tài)地?cái)U(kuò)展一個(gè)實(shí)現(xiàn)類(lèi)的功能截驮,這不需要多說(shuō),裝飾模式的定義就是如此
裝飾模式的缺點(diǎn)
- 多層的裝飾是比較復(fù)雜的
- 盡量減少裝飾類(lèi)的數(shù)量际度,一遍降低系統(tǒng)的復(fù)雜度
裝飾模式的使用場(chǎng)景
- 需要擴(kuò)展一個(gè)類(lèi)的功能葵袭,或給出一個(gè)類(lèi)增加附加功能
- 需要?jiǎng)討B(tài)地給一個(gè)對(duì)象增加功能,這些功能可以再動(dòng)態(tài)地撤銷(xiāo)
- 需要為一批的兄弟類(lèi)進(jìn)行改裝或加裝功能乖菱,當(dāng)然是首選裝飾模式