什么是装饰器模式
装饰器模式,动态的将责任附加到对象上,若要扩展功能,装饰器提供了比继承更有弹性的替代方案。
举例说明
我们定义一种饮料,它有描述信息,还有价格,如下
public abstract class Drink {
String desc = "nothing";
public String getDesc() {
return desc;
}
public abstract double cost();
}
然后定义咖啡,是一种饮料,它有自己的描述和价格
public class Coffee extends Drink {
public Coffee() {
this.desc = "Coffee";
}
public double cost() {
return 1.2;
}
}
咖啡可以有不同的口味,而且不同的口味所需要的额外价格不同,这时可以用装饰器方法来实现口味对饮料的装饰,如下:
public class Milk extends Drink {
private Drink drink;
public Milk(Drink water) {
this.drink = water;
}
public double cost() {
return drink.cost() + 1;
}
@Override
public String getDesc() {
return drink.getDesc() + ", Milk";
}
}
下面我们创建一个测试类,要演示如何动态的装饰。如下:
class Test {
public static void main(String[] args){
Drink drink = new Coffee();
System.out.println(drink.getDesc() + ", cost " + drink.cost());
drink = new Milk(drink);
System.out.println(drink.getDesc() + ", cost " + drink.cost());
drink = new Milk(drink);
System.out.println(drink.getDesc() + ", cost " + drink.cost());
}
}
输出结果为:
Coffee, cost 1.2
Coffee, Milk, cost 2.2
Coffee, Milk, Milk, cost 3.2
适配器模式
将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
比如我们鸭子类,鹅类,他们有自己的叫的方法和飞行的方法如下:
public interface Duck {
void quack();
void fly();
}
public class AKindDuck implements Duck {
public void quack() {
System.out.println("A kind duck quack");
}
public void fly() {
System.out.println("A kind duck fly");
}
}
鹅类
public interface Turkey {
void gobble();
void fly();
}
public class WildTurkey implements Turkey {
public void gobble() {
System.out.println("wild gobble");
}
public void fly() {
System.out.println("wild run");
}
}
为了让鹅类能适配成鸭子类,我们制作一个适配器
public class TurkeyAdapter implements Duck {
private Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
public void quack() {
turkey.gobble();
}
public void fly() {
turkey.fly();
turkey.fly();
}
}
我们创建一个测试类来说明适配的结果:
class Test { public static void main(String[] args){ Duck duck = new AKindDuck(); Turkey turkey = new WildTurkey(); Duck duckAdapter = new TurkeyAdapter(turkey); duck.quack(); duck.fly(); System.out.println(); turkey.gobble(); turkey.fly(); System.out.println(); duckAdapter.quack(); duckAdapter.fly(); } }
输出结果为:
A kind duck quack
A kind duck fly
wild gobble
wild run
wild gobble
wild run
wild run
外观模式
提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
比如看电影需要很多步骤,而我们可以把这很多种步骤封装在一个接口中叫做watchMovie()提供给外界。结束电影封装为endMovie()提供给外界。如下所示:
public class Movie {
public void watchMovie() {
ActionA();
ActionC();
}
public void endMovie() {
ActionB();
ActionD();
}
private void ActionA(){}
private void ActionB(){}
private void ActionC(){}
private void ActionD(){}
}