关于设计模式:设计模式之装饰者模式

52次阅读

共计 2875 个字符,预计需要花费 8 分钟才能阅读完成。

装璜者模式

结构型模式

装璜者模式(Decorator Pattern)容许向一个现有的对象增加新的性能,同时又不扭转其构造。它是作为现有的类的一个包装。

这种模式创立了一个装璜类,用来包装原有的类,并在放弃类办法签名完整性的前提下,提供了额定的性能。

介绍

用意: 动静地给一个对象增加一些额定的职责。就减少性能来说,装璜者模式相比生成子类更为灵便。

次要解决: 个别的,咱们为了扩大一个类常常应用继承形式实现,因为继承为类引入动态特色,并且随着扩大性能的增多,子类会很收缩。

何时应用: 在不想减少很多子类的状况下扩大类。

如何解决: 将具体性能职责划分,同时继承装璜者模式。

要害代码: 1、Component 类充当形象角色,不应该具体实现。2、润饰类援用和继承 Component 类,具体扩大类重写父类办法。

利用实例: 1、孙悟空有 72 变,当他变成 ” 庙宇 ” 后,他的基本还是一只猴子,然而他又有了庙宇的性能。2、不管一幅画有没有画框都能够挂在墙上,然而通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画能够被蒙上玻璃,装到框子里;这时画、玻璃和画框造成了一个物体。

具体实现

依据一个咖啡厅卖饮料和调味品的问题来解决。

第一步:创立形象 Drink 类

public abstract class Drink {
    /**
     * 形容
     */
    private String des;
    /**
     * 价格
     */
    private float price = 0.0f;

    public String getDes() {return des;}

    public void setDes(String des) {this.des = des;}

    public float getPrice() {return price;}

    public void setPrice(float price) {this.price = price;}

    // 计算费用的形象办法
    public abstract float cost();}

第二步:创立 Coffee 类

public class Coffee extends Drink {

    @Override
    public float cost() {return super.getPrice();
    }
}

第三步:创立不同单品咖啡

public class Espresso extends Coffee {public Espresso() {setDes("意大利咖啡");
        setPrice(6.0f);
    }
}
public class LongBlack extends Coffee {public LongBlack() {setDes("LongBlack");
        setPrice(5.0f);
    }
}
public class ShortBlack extends Coffee {public ShortBlack() {setDes("ShortBack");
        setPrice(4.0f);
    }
}

第四步:创立装璜者

public class Decorator extends Drink {

    private Drink obj;

    public Decorator(Drink obj) {this.obj = obj;}

    @Override
    public float cost() {return getPrice() + obj.cost();}


    @Override
    public String getDes() {return super.getDes() + "" + getPrice() +" && " + obj.getDes();
    }
}

第五步:创立不同的调味品

public class Chocolate extends Decorator {public Chocolate(Drink obj) {super(obj);
        setDes("巧克力");
        /**
         * 调味品的价格
         */
        setPrice(3.5f);
    }
}
public class Milk extends Decorator {public Milk(Drink obj) {super(obj);
        setDes("牛奶");
        setPrice(2.0f);
    }
}
public class Soy extends Decorator{public Soy(Drink obj) {super(obj);
        setDes("豆浆");
        setPrice(1.5f);
    }
}

第五步:创立测试类

public class CoffeeBar {public static void main(String[] args) {
        // 装璜着模式下的订单:2 份巧克力 + 1 份牛奶的 LongBlack

        //1. 点一份 LongBlack
        Drink order = new LongBlack();
        System.out.println("费用 =" + order.cost());
        System.out.println("形容 =" + order.getDes());
        //2. 退出一份牛奶
        order = new Milk(order);
        System.out.println("order 退出一份牛奶 费用 =" + order.cost());
        System.out.println("order 退出一份牛奶 形容 =" + order.getDes());

        //3. 退出一份巧克力
        order = new Chocolate(order);
        System.out.println("order 退出一份牛奶 又退出一份巧克力 费用 =" + order.cost());
        System.out.println("order 退出一份牛奶 又退出一份巧克力 形容 =" + order.getDes());

        //4. 再退出一份巧克力
        order = new Chocolate(order);
        System.out.println("order 退出一份牛奶 又退出一份巧克力 又退出一份巧克力 费用 =" + order.cost());
        System.out.println("order 退出一份牛奶 又退出一份巧克力 又退出一份巧克力 形容 =" + order.getDes());

    }
}

运行后果如下:

 费用 =5.0
形容 =LongBlack
order 退出一份牛奶 费用 =7.0
order 退出一份牛奶 形容 = 牛奶 2.0 && LongBlack
order 退出一份牛奶 又退出一份巧克力 费用 =10.5
order 退出一份牛奶 又退出一份巧克力 形容 = 巧克力 3.5 && 牛奶 2.0 && LongBlack
order 退出一份牛奶 又退出一份巧克力 又退出一份巧克力 费用 =14.0
order 退出一份牛奶 又退出一份巧克力 又退出一份巧克力 形容 = 巧克力 3.5 && 巧克力 3.5 && 牛奶 2.0 && LongBlack

阐明:

1、Milk 蕴含了 LongBlack

2、一份 Chocolate 蕴含了(Milk+LongBlack)3、一份 Chocolate 蕴含了(Chocolate+Milk+LongBlack)4、这样不论是什么模式的单品咖啡 + 调料组合,通过递归的形式不便组合和保护。

长处:

1、在该案例中,如果咱们想再增加一种咖啡只须要继承 Coffee 即可,2、装璜类和被装璜类能够独立倒退,不会互相耦合,装璜模式是继承的一个代替模式,装璜模式能够动静扩大一个实现类的性能。

毛病:

 多层装璜比较复杂。

正文完
 0