设计模式剖析系列之装饰模式

By heiry on 2019-08-16 [ in 技术 ]

装饰模式的核心实现:

1.抽象组件(Component):具体类和装饰类基本功能规范,通过二者的实现,可以通过多态方式互为引用。

2.具体组件(Concrete    Component):抽象组件的具体实现类。

3.抽象装饰(Decorator):继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。

4.具体装饰(ConcreteDecorator):实现抽象装饰的相关方法,并给具体构件对象添加附加的功能。

装饰模式类关系图

下面以实例说明实现过程:

智能手机除了基本功能外,还可以给手机加个保护壳、增加红外线遥控空调的功能、投影仪功能,还可以三者任意组合兼有之,我们用装饰模式实现。

UML类图:

详细代码:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.Decoration;
/**
* Component
* 抽象组件:“智能手机”接口
* @author Heiry
*
*/
public interface SmartPhone {
public void weChat();//智能手机基本功能:发微信
}
package com.mosang.Decoration; /** * Component * 抽象组件:“智能手机”接口 * @author Heiry * */ public interface SmartPhone { public void weChat();//智能手机基本功能:发微信 }
package com.mosang.Decoration;
/**
 * Component
 * 抽象组件:“智能手机”接口
 * @author Heiry
 *
 */
public interface SmartPhone {
  public void weChat();//智能手机基本功能:发微信
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.Decoration;
/**
* ConcreteComponent
* 具体组件类:具体一款手机:“陌桑超级智能手机”,实现“智能手机”接口
* @author Heiry
*
*/
public class MosangSuperPhone implements SmartPhone {
//重写weChat方法
@Override
public void weChat() {
System.out.println("愉快聊微信中。。。。");
}
}
package com.mosang.Decoration; /** * ConcreteComponent * 具体组件类:具体一款手机:“陌桑超级智能手机”,实现“智能手机”接口 * @author Heiry * */ public class MosangSuperPhone implements SmartPhone { //重写weChat方法 @Override public void weChat() { System.out.println("愉快聊微信中。。。。"); } }
package com.mosang.Decoration;
/**
 * ConcreteComponent
 * 具体组件类:具体一款手机:“陌桑超级智能手机”,实现“智能手机”接口
 * @author Heiry
 *
 */
public class MosangSuperPhone implements SmartPhone {
  //重写weChat方法
  @Override
  public void weChat() {
    System.out.println("愉快聊微信中。。。。");
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.Decoration;
/**
* ConcreteDecorator
* 具体装饰类:实现投影功能
* @author Heiry
*
*/
public class Projector extends Decorator {
//构造方法
public Projector(SmartPhone phone) {
super(phone);
}
//重写父类方法
@Override
public void weChat() {
super.weChat(); // 具体组件的功能
this.projection(); //增加投影功能
}
private void projection() {
System.out.println("我有了投影功能,手机也能看大幕电影了。。。。");
}
}
package com.mosang.Decoration; /** * ConcreteDecorator * 具体装饰类:实现投影功能 * @author Heiry * */ public class Projector extends Decorator { //构造方法 public Projector(SmartPhone phone) { super(phone); } //重写父类方法 @Override public void weChat() { super.weChat(); // 具体组件的功能 this.projection(); //增加投影功能 } private void projection() { System.out.println("我有了投影功能,手机也能看大幕电影了。。。。"); } }
package com.mosang.Decoration;
/**
 * ConcreteDecorator
 * 具体装饰类:实现投影功能
 * @author Heiry
 *
 */
public class Projector extends Decorator {
  //构造方法
  public Projector(SmartPhone phone) {
    super(phone); 
  }
  //重写父类方法
  @Override
  public void weChat() {
    super.weChat(); // 具体组件的功能
    this.projection(); //增加投影功能
  }
  private void projection() {
    System.out.println("我有了投影功能,手机也能看大幕电影了。。。。");

  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.Decoration;
/**
* ConcreteDecorator
* 具体装饰类:实现使用前给手机加个保护壳功能
* @author Heiry
*
*/
public class ProtectShell extends Decorator {
public ProtectShell(SmartPhone phone) {
super(phone);
}
@Override
public void weChat() {
this.protectPhone();
super.weChat();
}
private void protectPhone() {
System.out.println("使用前给手机加了个保护壳,美美哒。。。");
}
}
package com.mosang.Decoration; /** * ConcreteDecorator * 具体装饰类:实现使用前给手机加个保护壳功能 * @author Heiry * */ public class ProtectShell extends Decorator { public ProtectShell(SmartPhone phone) { super(phone); } @Override public void weChat() { this.protectPhone(); super.weChat(); } private void protectPhone() { System.out.println("使用前给手机加了个保护壳,美美哒。。。"); } }
package com.mosang.Decoration;
/**
 * ConcreteDecorator
 * 具体装饰类:实现使用前给手机加个保护壳功能
 * @author Heiry
 *
 */
public class ProtectShell extends Decorator {
  public ProtectShell(SmartPhone phone) {
    super(phone);
  }
  @Override
    public void weChat() {
      this.protectPhone();
      super.weChat();
    }
  private void protectPhone() {
    System.out.println("使用前给手机加了个保护壳,美美哒。。。");
  }
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.Decoration;
/**
* ConcreteDecorator
* 具体装饰组类:实现红外功能
* @author Heiry
*
*/
public class Infrared extends Decorator {
//构造方法
public Infrared(SmartPhone phone) {
super(phone);
}
@Override
public void weChat() {
super.weChat(); // 具体组件的功能实现
this.remoteControl(); //增加红外遥控功能
}
public void remoteControl(){
System.out.println("我有了红外线,遥控空调中。。。。");
}
}
package com.mosang.Decoration; /** * ConcreteDecorator * 具体装饰组类:实现红外功能 * @author Heiry * */ public class Infrared extends Decorator { //构造方法 public Infrared(SmartPhone phone) { super(phone); } @Override public void weChat() { super.weChat(); // 具体组件的功能实现 this.remoteControl(); //增加红外遥控功能 } public void remoteControl(){ System.out.println("我有了红外线,遥控空调中。。。。"); } }
package com.mosang.Decoration;
/**
 * ConcreteDecorator
 * 具体装饰组类:实现红外功能
 * @author Heiry
 *
 */
public class Infrared extends Decorator {
  //构造方法
  public Infrared(SmartPhone phone) {
    super(phone);
  }
  @Override
  public void weChat() {
    super.weChat(); // 具体组件的功能实现
    this.remoteControl(); //增加红外遥控功能
  }
  public void remoteControl(){
    System.out.println("我有了红外线,遥控空调中。。。。");
  }

}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.mosang.Decoration;
/**
* 客户端测试类
* @author Heiry
*
*/
public class Clinet {
public static void main(String[] args) {
MosangSuperPhone myphone = new MosangSuperPhone();//创建陌桑超级手机实例
ProtectShell shell = new ProtectShell(myphone); // 给手机加外壳
shell.weChat(); //使用手机(聊微信)前,先给手机加壳
System.out.println("--------------------------");
Infrared infrared = new Infrared(myphone);
infrared.weChat(); // 手机试用(聊微信)后,调出遥控空调功能
System.out.println("--------------------------");
Projector projector = new Projector(myphone);
projector.weChat();// 手机试用(聊微信)后,调出投影功能
System.out.println("--------------------------");
//使手机既加了保护壳,又能投影看电影
Projector multiPhone = new Projector(shell);
multiPhone.weChat(); // 既装了手机壳,又有了投影功能
System.out.println("--------------------------");
//使手机既加了保护壳,又能投影看电影,还能红外遥控空调
Infrared multiPhone2 = new Infrared(multiPhone);
multiPhone2.weChat();
}
}
package com.mosang.Decoration; /** * 客户端测试类 * @author Heiry * */ public class Clinet { public static void main(String[] args) { MosangSuperPhone myphone = new MosangSuperPhone();//创建陌桑超级手机实例 ProtectShell shell = new ProtectShell(myphone); // 给手机加外壳 shell.weChat(); //使用手机(聊微信)前,先给手机加壳 System.out.println("--------------------------"); Infrared infrared = new Infrared(myphone); infrared.weChat(); // 手机试用(聊微信)后,调出遥控空调功能 System.out.println("--------------------------"); Projector projector = new Projector(myphone); projector.weChat();// 手机试用(聊微信)后,调出投影功能 System.out.println("--------------------------"); //使手机既加了保护壳,又能投影看电影 Projector multiPhone = new Projector(shell); multiPhone.weChat(); // 既装了手机壳,又有了投影功能 System.out.println("--------------------------"); //使手机既加了保护壳,又能投影看电影,还能红外遥控空调 Infrared multiPhone2 = new Infrared(multiPhone); multiPhone2.weChat(); } }
package com.mosang.Decoration;
/**
 * 客户端测试类
 * @author Heiry
 *
 */
public class Clinet {
  public static void main(String[] args) {
    MosangSuperPhone myphone = new MosangSuperPhone();//创建陌桑超级手机实例
    ProtectShell shell = new ProtectShell(myphone); // 给手机加外壳
    shell.weChat(); //使用手机(聊微信)前,先给手机加壳
    System.out.println("--------------------------");
    Infrared infrared = new Infrared(myphone);
    infrared.weChat(); // 手机试用(聊微信)后,调出遥控空调功能
    System.out.println("--------------------------");
    Projector projector = new Projector(myphone);
    projector.weChat();// 手机试用(聊微信)后,调出投影功能
    
    System.out.println("--------------------------");
    //使手机既加了保护壳,又能投影看电影
    Projector multiPhone = new Projector(shell); 
    multiPhone.weChat(); // 既装了手机壳,又有了投影功能
    
    System.out.println("--------------------------");
    //使手机既加了保护壳,又能投影看电影,还能红外遥控空调
    Infrared multiPhone2 = new Infrared(multiPhone);
    multiPhone2.weChat();
  }

}

运行结果:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
使用前给手机加了个保护壳,美美哒。。。
愉快聊微信中。。。。
--------------------------
愉快聊微信中。。。。
我有了红外线,遥控空调中。。。。
--------------------------
愉快聊微信中。。。。
我有了投影功能,手机也能看大幕电影了。。。。
--------------------------
使用前给手机加了个保护壳,美美哒。。。
愉快聊微信中。。。。
我有了投影功能,手机也能看大幕电影了。。。。
--------------------------
使用前给手机加了个保护壳,美美哒。。。
愉快聊微信中。。。。
我有了投影功能,手机也能看大幕电影了。。。。
我有了红外线,遥控空调中。。。。
使用前给手机加了个保护壳,美美哒。。。 愉快聊微信中。。。。 -------------------------- 愉快聊微信中。。。。 我有了红外线,遥控空调中。。。。 -------------------------- 愉快聊微信中。。。。 我有了投影功能,手机也能看大幕电影了。。。。 -------------------------- 使用前给手机加了个保护壳,美美哒。。。 愉快聊微信中。。。。 我有了投影功能,手机也能看大幕电影了。。。。 -------------------------- 使用前给手机加了个保护壳,美美哒。。。 愉快聊微信中。。。。 我有了投影功能,手机也能看大幕电影了。。。。 我有了红外线,遥控空调中。。。。
使用前给手机加了个保护壳,美美哒。。。
愉快聊微信中。。。。
--------------------------
愉快聊微信中。。。。
我有了红外线,遥控空调中。。。。
--------------------------
愉快聊微信中。。。。
我有了投影功能,手机也能看大幕电影了。。。。
--------------------------
使用前给手机加了个保护壳,美美哒。。。
愉快聊微信中。。。。
我有了投影功能,手机也能看大幕电影了。。。。
--------------------------
使用前给手机加了个保护壳,美美哒。。。
愉快聊微信中。。。。
我有了投影功能,手机也能看大幕电影了。。。。
我有了红外线,遥控空调中。。。。

可见,比起直接继承实现新增功能,装饰模式极好实现了功能叠加,更好地提高了代码重用。

 >>



© 2009-2024 MOSANG.NET DESIGNED BY HEIRY