设计模式之复合模式

设计模式之复合模式

1. 什么是复合模式

在形式上,复合模式确实是多个模式的组合,但满足了这一条并不一定是复合模式,注意它的定义:将多个模式结合起来形成一个“框架”,以解决一般性问题。一提到“框架”,可能最容易联想到的就是MVC吧,不过MVC确实是一个经典的复合模式。

2. 具体实例

项目的类图:
设计模式之复合模式_第1张图片

首先要创建一群呱呱叫的鸭子类,让他们实现接口Quackable:

public interface Quackable {
    public void quack();
}

这是一个鸭子类:

public class RedheadDuck implements Quackable {
	@Override
	public void quack() {
    System.out.println("Quack");
}

这时候水里还有鹅,也会叫:

public class Goose {

    public void hoke(){
        System.out.println("Honk");
    }
}

想让鹅也实现Quackable接口统一管理,可以用适配器模式:

public class GooseAdapter implements Quackable {
    Goose goose;

    public GooseAdapter(Goose goose){
        this.goose = goose;
        observable = new Observable(this);
    }	

    @Override
    public void quack() {
        goose.hoke();
        notifyObservers();
}

这时,想要统计他们叫的次数,就可以使用装饰者模式把它们装饰城=成QuackCounter:

public class QuackCounter implements Quackable {
    Quackable duck;
    static int numberOfQuacks;
    public QuackCounter(Quackable duck){
        this.duck = duck;
    }

    @Override
    public void quack() {
        duck.quack();
        numberOfQuacks++;
    }

    public static int getQuacks(){
        return numberOfQuacks;
    }
}

每次创建鸭子都要new很麻烦,就可以用工厂模式,要鸭子就直接跟工厂要:

public class CountingDuckFactory extends AbstrctDuckFactory {
    @Override
    public Quackable createMallardDuck() {
        return new QuackCounter(new MallardDuck());
    }

    @Override
    public Quackable createRedheadDuck() {
        return new QuackCounter(new RedheadDuck());
    }

    @Override
    public Quackable createDuckCall() {
        return new QuackCounter(new DuckCall());
    }

    @Override
    public Quackable createRubberDuck() {
        return new QuackCounter(new RubberDuck());
    }
}

因为鸭子太多了,可以用组合模式统一管理,用迭代器模式查看内部对象:

public class Flock implements Quackable {
    ArrayList quackers = new ArrayList();   
    public void add(Quackable quacker){
            quackers.add(quacker);
    }

    @Override
    public void quack() {
        Iterator iterator = quackers.iterator();
        while (iterator.hasNext()){
            Quackable quacker = (Quackable) iterator.next();
            quacker.quack();
        }
    }
}

现在,生物学家想每次呱呱叫都被通知到,就可以使用观察者模式:

public class Flock implements Quackable {
    ArrayList quackers = new ArrayList();
    public void add(Quackable quacker){
        quackers.add(quacker);
    }

    @Override
    public void quack() {
        Iterator iterator = quackers.iterator();
        while (iterator.hasNext()){
            Quackable quacker = (Quackable) iterator.next();
            quacker.quack();
        }
    }

    @Override
    public void registerObserver(Observer observer) {
        Iterator iterator = quackers.iterator();
        while (iterator.hasNext()) {
            Quackable duck = (Quackable) iterator.next();
            duck.registerObserver(observer);
        }
    }

    @Override
    public void notifyObservers() {

    }
}

测试类

public class DuckSimulator {

    public static void main(String[] args) {
        DuckSimulator simulator = new DuckSimulator();
        AbstrctDuckFactory duckFactory = new CountingDuckFactory();

        simulator.simulate(duckFactory);
    }

    void simulate(AbstrctDuckFactory duckFactory){
        Quackable redheadDuck = duckFactory.createRedheadDuck();
        Quackable duckCall = duckFactory.createDuckCall();
        Quackable rubberDuck = duckFactory.createRubberDuck();
        Quackable gooseDuck = new QuackCounter(new GooseAdapter(new Goose()));

        System.out.println("\nDuck Simulator: With Composite - Flocks");

        Flock flock = new Flock();

        flock.add(redheadDuck);
        flock.add(rubberDuck);
        flock.add(duckCall);
        flock.add(gooseDuck);

        Flock flock1 = new Flock();

        Quackable mallardDuck1 = duckFactory.createMallardDuck();
        Quackable mallardDuck2 = duckFactory.createMallardDuck();
        Quackable mallardDuck3 = duckFactory.createMallardDuck();
        Quackable mallardDuck4 = duckFactory.createMallardDuck();

        flock1.add(mallardDuck1);
        flock1.add(mallardDuck2);
        flock1.add(mallardDuck3);
        flock1.add(mallardDuck4);

        flock.add(flock1);

        System.out.println("\nDuck Simulator: Whole Flock Simulation");
        simulate(flock);

        System.out.println("\nDuck Simulator: Mallard Flock Simulation");
        simulate(flock1);

        Quackologist quackologist = new Quackologist();
        flock.registerObserver(quackologist);

        simulate(flock);

        System.out.println("The duck quacked "+QuackCounter.getQuacks()+" times");
    }

    void simulate(Quackable duck){
        duck.quack();
    }
}

3. MVC与复合模式

结构

  • 模型:模型持有所有的数据、状态和程序逻辑,模型没有注意到视图和控制器,虽然它提供了操纵和检索状态的接口,并发送状态改变通知给观察者。是程序主体,代表了业务数据和业务逻辑。

  • 视图:用来呈现模型,视图通常直接从模型中取得它需要显示的状态与数据。是与用户交互的界面,显示数据、接收输入,但不参与实际业务逻辑

  • 控制器:取得用户的输入并解读其对模型的意思。接收用户输入,并解析反馈给Model。

设计模式之复合模式_第2张图片

MVC的最大优点就是把表现层View与模型Model分离,实现了设计上的松耦合(应对变化)以及代码的复用(View可以随便换,只需要改改新View里面那一丁点儿控制逻辑就好了)

前面说过了MVC是一种复合模式,那它到底复合了哪些模式,一起看看:

  1. 策略模式

视图和控制器实现了策略模式:视图是一个对象,可以被调整使用不同的策略,而控制提供了策略。视图只关心系统中可视的部分,对与任何界面行为,都委托给控制器处理。使用策略模式也可以让视图和模型之间关系解耦,因为控制器负责和模型交互来传递用户的请求。对与工作是怎么完成的,视图豪不知情。

  1. 观察者模式

模型实现了观察者模式,当状态改变时,相关对象将持续更新。使用观察者模式,可以让模型完全独立于视图和控制器。同一个模型可以使用不同的视图,甚至可以同时使用多个视图。

  1. 组合模式

显示包括了窗口、面板、按钮、文本标签等。每个显示组件如果不是组合节点(例如窗口),就是叶节点(例如按钮)。当控制器告诉视图更新时,只需告诉视图最顶层的组件即可,组合会处理其余的事。

MVC应用了多个模式,并能够较好的解决设计上的一般性问题,所以被称为复合模式。

你可能感兴趣的:(设计模式,设计模式,设计模式,复合模式)