通过一个例子将他们连接起来
例子
一群鸭子想学叫
叫的行为声明一个接口,让想叫的鸭子实现它就可以了。
/*** @description: 行为接口化* @date: 2020-06-21 07:59* @author: 十一*/public interface Quackable {void quack();}public class MallardDuack implements Quackable {@Overridepublic void quack() {System.out.println("MallardDuack");}}public class RedHeadDuack implements Quackable {@Overridepublic void quack() {System.out.println("RedHeadDuack");}}// 模拟鸭子叫public class DuckSimulator {public static void main(String[] args) {DuckSimulator duckSimulator = new DuckSimulator();duckSimulator.simulator1();}public void simulator1() {Quackable mallardDuack = new MallardDuack();Quackable redHeadDuack = new RedHeadDuack();quack(mallardDuack);quack(redHeadDuack);}public void quack(Quackable quackable) {quackable.quack();}}
天鹅也想学鸭子叫——适配器模式
【天鹅也想学鸭子叫】,如何满足要求,但不违反开闭原则呢?适配器模式
/*** @description: 适配器模式谁需要什么功能,谁就创建个新的适配器类* @date: 2020-06-21 08:13* @author: 十一*/public class GooseAdapter implements Quackable {private Goose goose;@Overridepublic void quack() {goose.hook();}public GooseAdapter(Goose goose) {this.goose = goose;}}/*** @description: 鹅也想呱呱叫,所以可以加入适配器模式* @date: 2020-06-21 08:11* @author: 十一*/public class Goose {public void hook() {System.out.println("hook");}}// 天鹅也能quack了public void simulator2() {Quackable mallardDuack = new MallardDuack();Quackable redHeadDuack = new RedHeadDuack();Goose goose = new Goose();Quackable gooseAdapter = new GooseAdapter(goose);quack(mallardDuack);quack(redHeadDuack);quack(gooseAdapter);}
统计呱呱叫的次数——装饰者模式
给鸭子加入【统计呱呱叫次数的行为】,如何满足要求,但不违反开闭原则呢?装饰者模式
/*** @description: 鸭子新的行为,给鸭子叫行为添加了计数的功能* @date: 2020-06-21 08:24* @author: 十一*/public class QuackCounter implements Quackable {Quackable quackable;static int numberOfQuackables;@Overridepublic void quack() {quackable.quack();numberOfQuackables++;}public static int getNumberOfQuackables() {return numberOfQuackables;}}public void simulator3() {Quackable mallardDuack = new QuackCounter(new MallardDuack());Quackable redHeadDuack = new QuackCounter(new RedHeadDuack());Goose goose = new Goose();Quackable gooseAdapter = new QuackCounter(new GooseAdapter(goose));quack(mallardDuack);quack(redHeadDuack);quack(gooseAdapter);System.out.println("鸭子叫的次数:"+QuackCounter.getNumberOfQuackables());}
困境!
如果一只鸭子忘记被 QuackCounter 包装了,那么它的叫声就不能被统计了。我们需要强制让鸭子包装,以免出现这样的问题。
化解——抽象工厂模式
抽象工厂模式,用来生成各种不同类型的鸭子产品家族。
public abstract class AbstractDuckFactory {public abstract Quackable createMallardDuack();public abstract Quackable createRedHeadDuack();public abstract Quackable createGooseAdapter();}public class CountingDuckFactory extends AbstractDuckFactory {@Overridepublic Quackable createMallardDuack() {return new QuackCounter(new MallardDuack());}@Overridepublic Quackable createRedHeadDuack() {return new QuackCounter(new RedHeadDuack());}@Overridepublic Quackable createGooseAdapter() {return new QuackCounter(new GooseAdapter(new Goose()));}}public void simulator4(AbstractDuckFactory duckFactory) {Quackable mallardDuack = duckFactory.createMallardDuack();Quackable redHeadDuack = duckFactory.createMallardDuack();Quackable gooseAdapter = duckFactory.createGooseAdapter();quack(mallardDuack);quack(redHeadDuack);quack(gooseAdapter);System.out.println("鸭子叫的次数:"+QuackCounter.getNumberOfQuackables());}public static void main(String[] args) {DuckSimulator duckSimulator = new DuckSimulator();// duckSimulator.simulator1();// duckSimulator.simulator2();// duckSimulator.simulator3();AbstractDuckFactory duckFactory = new CountingDuckFactory();duckSimulator.simulator4(duckFactory);}
中央集权制度——组合模式
这种方式管理鸭子还是不太方便,如果以后扩大规模成败上千的呢?很容易出问题!
Quackable mallardDuack = duckFactory.createMallardDuack();Quackable redHeadDuack = duckFactory.createMallardDuack();Quackable gooseAdapter = duckFactory.createGooseAdapter();...// 每个都要去quack下,太麻烦了quack(mallardDuack);quack(redHeadDuack);quack(gooseAdapter);quack(gooseAdapter);quack(gooseAdapter);...
使用组合模式,组合模式需要和叶子节点一样实现接口,这里的叶子节点是Quackable的实现类
/*** @description: 组合模式需要和叶子节点一样实现接口,这里的叶子节点是Quackable的实现类* @date: 2020-06-21 09:21* @author: 十一*/public class Flock implements Quackable {List<Quackable> quackers = new ArrayList();@Overridepublic void quack() {for (Quackable quacker : quackers) {quacker.quack();}}public void add(Quackable quackable) {quackers.add(quackable);}}public static void main(String[] args) {DuckSimulator duckSimulator = new DuckSimulator();// duckSimulator.simulator1();// duckSimulator.simulator2();// duckSimulator.simulator3();// AbstractDuckFactory duckFactory = new CountingDuckFactory();// duckSimulator.simulator4(duckFactory);Flock flock = new Flock();AbstractDuckFactory duckFactory = new CountingDuckFactory();flock.add(duckFactory.createMallardDuack());flock.add(duckFactory.createMallardDuack());flock.add(duckFactory.createGooseAdapter());duckSimulator.quack(flock);}
鸭子的背叛——观察者模式
一切都很顺利,天下鸭子尽在掌握之中,鸭子们都会学会了呱呱叫,但是最近有个别鸭子用呱呱叫搞起了歪心思,似乎有叛变的冲动,需要对他们进行24小时的全方位无死角监控!
