Java设计模式——装饰器模式、适配器模式、外观模式

什么是装饰器模式

装饰器模式,动态的将责任附加到对象上,若要扩展功能,装饰器提供了比继承更有弹性的替代方案。java

举例说明

咱们定义一种饮料,它有描述信息,还有价格,以下web

public abstract class Drink {

    String desc = "nothing";

    public String getDesc() {
        return desc;
    }

    public abstract double cost();
}

而后定义咖啡,是一种饮料,它有本身的描述和价格app

public class Coffee extends Drink {

    public Coffee() {
        this.desc = "Coffee";
    }

    public double cost() {
        return 1.2;
    }
}

咖啡能够有不一样的口味,并且不一样的口味所须要的额外价格不一样,这时能够用装饰器方法来实现口味对饮料的装饰,以下:ide

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";
    }
}

下面咱们建立一个测试类,要演示如何动态的装饰。以下:svg

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

适配器模式

将一个类的接口,转换成客户指望的另外一个接口。适配器让本来接口不兼容的类能够合做无间。
好比咱们鸭子类,鹅类,他们有本身的叫的方法和飞行的方法以下:this

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");
    }
}

鹅类spa

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");
    }
}

为了让鹅类能适配成鸭子类,咱们制做一个适配器code

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();
    }
}

咱们建立一个测试类来讲明适配的结果:xml

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(){}
}