装饰者模式

来源:互联网 发布:孙悟空直销软件 编辑:程序博客网 时间:2024/05/16 15:31

1、概述

 装饰者模式是在不改变类和继承的情况下,动态的是给对象增加功能。是通过装饰者来包裹真实的对象。

2、装饰者的特点

 1)、装饰者和真实对象有相同的接口;

 2)、真实对象持有装饰者的引用;

 3)、装饰者将请求转给真实对象,由真实对象处理;

 4)、装饰者将请求转给真实对象之前/之后可以进行一些操作,这样,就可以在不改变真实对象的情况下,动态的为对   象增项一下功能;

3、装饰者模式的各个角色

 1)、抽象构建(component):定义一个抽象的接口,以规范接收附加功能的对象;

 2)、具体构建(concrete compoment):附加功能类;

 3)、装饰者(decorator):持有抽象构建的引用,用来指向具体的构建,同时实现抽象构建接口;

 4)、具体装饰(concrete compoment):负责给构建添加上具体的功能;

4、优缺点

 1)、装饰者模式和继承都是扩展类的功能,但装饰者模式更灵活;

 2)、通过具体的装饰类和装饰类组合,可以开发出更多的组合;

 3)、装饰者模式中小类过多,程序设计复杂;

5、设计原则

 1)、多用组合、少用继承;

 2)、对扩展开放、修改关闭;

6、适用场景

 1)、需要扩展一个类的功能

 2)、需要动态给一个类增加功能,且可以撤销;

 3)、适用排列组合产生的大量功能;

 4)、通过集成方式产生太多的子类、或者类不能集成;

7、实例

 JAVA IO流就是典型的装饰者模式;

8、代码示例

 head fisrt中的例子,就不写了。 亦庄通泰的房子最近在做装修,我发现,用装修作为装饰者模式的例子非常恰当;理由如下:

 1)、装修公司提供基础的装修方案;

 2)、在原有的施工方案基础上,可以任意选择增项(ps:增项都很贵,装修公司就靠这挣钱呢^_^ );

 3)、增项种类非常多;

 以上几点说明用装修来说明装饰者模式恰当。

 如下类:

 抽象构建:装修

 具体构建:基础装修

 装饰者:增项

 具体装饰者:壁纸、台下盆、抽屉、腰线、实木踢脚线、

 抽象构建、具体构建代码如下:

  代码如下:

public class Task {public static void main(String[] args) {Owner o = new Owner();String msg = o.add();System.out.println(msg);Wallpaper w = new Wallpaper(o);System.out.println(w.add());Drawer d = new Drawer(w);System.out.println(d.add());}}// 抽象装修类abstract class Decorate {public abstract String add();}// 业主选择装修方案class Owner extends Decorate {public String add() {return "装修方案:";}}// 抽象装饰者类abstract class Project extends Decorate {public abstract String add();}// 具体增项类:壁纸class Wallpaper extends Project {private Decorate decorate;public Wallpaper(Decorate decorate) {this.decorate = decorate;}public String add() {return this.decorate.add() + "壁纸";}}// 具体增项类:台下盆class BelowBasin extends Project {private Decorate decorate;public BelowBasin(Decorate decorate) {this.decorate = decorate;}public String add() {return this.decorate.add() + "台下盆";}}// 具体增项类:抽屉class Drawer extends Project {private Decorate decorate;public Drawer(Decorate decorate) {this.decorate = decorate;}public String add() {return this.decorate.add() + "抽屉";}}// 具体增项类:腰线class BeltLine extends Project {private Decorate decorate;public BeltLine(Decorate decorate) {this.decorate = decorate;}public String add() {return this.decorate.add() + "腰线";}}// 具体增项类:实木踢脚线class WoodLine extends Project {private Decorate decorate;public WoodLine(Decorate decorate) {this.decorate = decorate;}public String add() {return this.decorate.add() + "实木踢脚线";}}


  示例二

public class Task {public static void main(String[] args) {Decorate d202 = new Drawer(new BelowBasin((new Wallpaper(new Base()))));System.out.println(d202.getName() + "; 价格:" + d202.getPrice());Decorate d802 = new WoodLine(new BeltLine(new Drawer(new BelowBasin(new Base()))));System.out.println(d802.getName() + "; 价格:" + d802.getPrice());Decorate d1301 = new Drawer(new Base());System.out.println(d1301.getName() + ";价格" + d1301.getPrice());}}// 抽象装修类abstract class Decorate {public abstract String getName();public abstract double getPrice();}// 基础装修方案class Base extends Decorate {public String getName() {return "基础装修:";}public double getPrice() {return 4.0;}}// 抽象装饰者类abstract class Project extends Decorate {}// 具体增项类:壁纸class Wallpaper extends Project {private Decorate decorate;public Wallpaper(Decorate decorate) {this.decorate = decorate;}public String getName() {return this.decorate.getName() + "+壁纸";}public double getPrice() {return this.decorate.getPrice() + 0.5;}}// 具体增项类:台下盆class BelowBasin extends Project {private Decorate decorate;public BelowBasin(Decorate decorate) {this.decorate = decorate;}public String getName() {return this.decorate.getName() + "+台下盆";}public double getPrice() {return this.decorate.getPrice() + 0.2;}}// 具体增项类:抽屉class Drawer extends Project {private Decorate decorate;public Drawer(Decorate decorate) {this.decorate = decorate;}public String getName() {return this.decorate.getName() + "+抽屉";}public double getPrice() {return this.decorate.getPrice() + 0.1;}}// 具体增项类:腰线class BeltLine extends Project {private Decorate decorate;public BeltLine(Decorate decorate) {this.decorate = decorate;}public String getName() {return this.decorate.getName() + "+腰线";}public double getPrice() {return this.decorate.getPrice() + 0.1;}}// 具体增项类:实木踢脚线class WoodLine extends Project {private Decorate decorate;public WoodLine(Decorate decorate) {this.decorate = decorate;}public String getName() {return this.decorate.getName() + "+实木踢脚线";}public double getPrice() {return this.decorate.getPrice() + 0.3;}}



1 0