装饰者模式可以在不改变一个对象本身的基础上给对象增加额外的新行为,通过继承机制可以实现这种功能,但是这种方法是静态的,用户不能够控制增加行为的实现和时机。其实按照设计模式的原则也不该使用继机制,而是使用关联机制。
装饰者模式组成:抽象构件,具体构件,抽象装饰类,具体装饰类。
通过装饰类中包含构件对象,再通过递归,就能够实现对构建类行为的增加。
//抽象构件类
public abstract class Beverage {
String description = "unknown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
//抽象装饰者类
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
//具体构件类
public class DarkRoast extends Beverage {
public DarkRoast(){
description = "Dark Roast";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.99;
}
}
public class Decat extends Beverage {
public Decat(){
description = "Decat";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 1.05;
}
}
public class Espresso extends Beverage{
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 1.99;
}
}
public class HouseBlend extends Beverage {
public HouseBlend(){
description = "House Blend";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.89;
}
}
//具体装饰类
public class Soy extends CondimentDecorator {
Beverage bevarage;
public Soy(Beverage bevarage){
this.bevarage = bevarage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return bevarage.getDescription() + ", Soy";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.1 + bevarage.cost();
}
}
public class Whip extends CondimentDecorator {
Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription() + ", Whip";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.2 + beverage.cost();
}
}
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription() + ",Mocha";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.20 + beverage.cost();
}
}
//客户端调用
public class StarbuzzCoffee {
public static void main(String[] args){
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
}
}
加密方法的改进
//抽象构件类
public interface Cipher {
public String encrypt(String plainText);
}
//抽象装饰类
public class CipherDecorator implements Cipher {
private Cipher cipher;
public CipherDecorator(Cipher cipher){
this.cipher = cipher;
}
@Override
public String encrypt(String plainText) {
// TODO Auto-generated method stub
return cipher.encrypt(plainText);
}
}
//具体构件类
public class SimpleCipher implements Cipher {
@Override
public String encrypt(String plainText) {
// TODO Auto-generated method stub
String str = "";
for(int i = 0; i < plainText.length(); i ++){
char c = plainText.charAt(i);
if(c >= 'a' && c <= 'z'){
c += 6;
if(c > 'z') c-= 26;
if(c < 'a') c += 26;
}
if(c >= 'A' && c <= 'Z'){
c += 6;
if(c > 'Z') c -= 26;
if(c < 'A') c += 26;
}
str += c;
}
return str;
}
}
//具体装饰者类
public class ComplexCipher extends CipherDecorator {
public ComplexCipher(Cipher cipher) {
super(cipher);
}
public String encrypt(String plainText){
String result = super.encrypt(plainText);
result = reverse(result);
return result;
}
private String reverse(String result) {
String str = "";
for(int i = result.length(); i > 0; i --){
str += result.substring(i - 1, i);
}
return str;
}
}
public class AdvancedCipher extends CipherDecorator {
public AdvancedCipher(Cipher cipher) {
super(cipher);
}
public String encrypt(String plainText){
String result = super.encrypt(plainText);
result = mod(result);
return result;
}
private String mod(String result) {
String str = "";
for(int i = 0; i < result.length(); i++){
String c = String.valueOf(result.charAt(i)%6);
str += c;
}
return str;
}
}
装饰者模式优点:
(1)可以通过动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰类,从而实现不同的行为。
(2)通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,可以通过使用多个具体装饰类来装饰同一对象,得到更为强大的对象。
装饰者模式的缺点:
(1)出错更难排查。