这里没有对装饰模式的讲解,只有自己的理解和一些代码示例。下图是我对各个组件的命名。
1、动态的为一个对象增加新的功能
2、装饰模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能(这样就比卖你了因为继承导致的同类型体系的快速膨胀 )。使用对象的关联关系代替继承关系,更加灵活。
3、设计原则:类应该对扩展开放,对修改关闭。在不修改先有代码的情况下,而已搭配新的行为,这样使设计具有了弹性,可以应对改变,可以接收新的功能来应对改变的需求。
4、利用继承设计子类的行为,是在编译时静态决定的,而装饰模式可以在任何时候被装饰,所以可以在运行时动态地,不限量的用自己喜欢的装饰者来装饰对象
5、装饰者通常是用其他类似于工厂或生成器这样的模式创建的。
6、装饰模式的缺点会产生非常多的小对象,就比如IO中的众多对象,所有就需要了解装饰者的工作原理,次啊能容易的分辨出他们的装饰者类是如何组织的。
先写一个简单的装饰模式:(车有基本在路上跑的功能,还增加了可以水里游,天上飞,自动驾驶的功能)
注:本例子的抽象组件使用的接口,在抽象装饰类中进行了对具体组件的引用。
类图:
//抽象组件
public interface ICar {
void move();
}
//具体组件(真实对象)
class Car implements ICar{
@Override
public void move() {
System.out.println("陆上跑");
}
}
//抽象装饰类
class SupperCar implements ICar{
ICar iCar; //对真实对象的应用放置在了抽象装饰类中
public SupperCar(ICar iCar) {
this.iCar = iCar;
}
@Override
public void move() {
iCar.move();
}
}
//具体装饰者 1
class FlyCar extends SupperCar{
public FlyCar(ICar icar) {
super(icar);
}
public void fly(){
System.out.println("可以飞");
}
@Override
public void move() {
super.move();
fly();
}
}
//具体装饰者 2
class WaterCar extends SupperCar{
public WaterCar(ICar icar) {
super(icar);
}
public void water(){
System.out.println("水里游");
}
@Override
public void move() {
super.move();
water();
}
}
//具体装饰者 3
class AutoCar extends SupperCar{
public AutoCar(ICar icar) {
super(icar);
}
public void auto(){
System.out.println("自动驾驶");
}
@Override
public void move() {
super.move();
auto();
}
}
public class Test {
public static void main(String[] args) {
//先定义一个真实的角色
Car car = new Car();
car.move();
System.out.println("新增飞行的功能-------");
FlyCar flyCar = new FlyCar(car); //直接引用对象
flyCar.move();
System.out.println("新增飞行的功能-------");
WaterCar waterCar = new WaterCar(new FlyCar(new Car())); //通过new的方式封装对象
waterCar.move(); //这里最里面的new Car()是真实的对象,装饰了一层FlyCar的功能,然后又装饰了一层WaterCar的功能
}
}
结果:
陆上跑
新增飞行的功能-------
陆上跑
天上飞
新增飞行的功能-------
陆上跑
天上飞
水里游
写一个复杂的装饰者模式:(为多种咖啡增加多种调料,计算总价格)
注:本例子中的抽象组件使用的抽象类,对具体组件的引用放置在了具体装饰类中。
类图:
//抽象组件
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost(); //计算价格,增加了调料后会增加咖啡价格
}
//具体组件 1
public class Espresso extends Beverage {
public Espresso() {
description = "Espresso coffee";
}
@Override
public double cost() {
return 1.99;
}
}
//具体组件 2
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "DarkRoast coffee";
}
@Override
public double cost() {
return .99;
}
}
//具体组件 3
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public double cost() {
return .89;
}
}
//具体组件 4
public class Decat extends Beverage{
public Decat() {
description = "Decat coffee";
}
@Override
public double cost() {
return 1.05;
}
}
//抽象装饰类
public class CondimentDecorator extends Beverage {
@Override
public String getDescription() {
return super.getDescription();
}
@Override
public double cost() {
return 0;
}
}
//具体装饰类 1
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription()+", Mocha";
}
@Override
public double cost() {
return .20 + beverage.cost();
}
}
//具体装饰类 2
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+", Soy";
}
@Override
public double cost() {
return .15+ beverage.cost();
}
}
//具体装饰类 3
public class Whip extends CondimentDecorator {
Beverage beverage;
public Whip(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Whip";
}
@Override
public double cost() {
return .10 + beverage.cost();
}
}
//开始订咖啡
public class StarbuzsCoffee {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
Beverage beverage1 = new DarkRoast();
beverage1 = new Mocha(beverage1);
beverage1 = new Mocha(beverage1);
beverage1 = new Whip(beverage1);
System.out.println(beverage1.getDescription() + " $" + beverage1.cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
}
}
结果:
Espresso coffee $1.99
DarkRoast coffee, Mocha, Mocha, Whip $1.49
House Blend Coffee, Mocha, Whip $1.1900000000000002