【学习笔记】设计模式-复合模式(Compound_pattern)

前言

本文来自《Head Fist 设计模式》一书的实例,这里仅仅是个人笔记记录

复合模式

各种设计模式混合使用

1. 面向接口编程

接口嘛,定义的目的就是用来使用

1.1 定义一个叫声接口

/**
 * 叫声接口
 */
public interface Quckable {

    // 呱呱叫
    public void quack();

}

1.2 不同鸭子实现不叫叫声,实现接口

/**
 * 绿头鸭实现接口-(因为接口就是用来实现的)
 */
public class MallardDuck implements Quckable {

    /**
     * 呱呱叫
     */
    @Override
    public void quack() {
        System.out.println(MallardDuck.class.getSimpleName() + " quack!");
    }
}


/**
 * 人造鸭鸣器
 */
public class DuckCall implements Quckable {

    /**
     * 山寨的呱呱叫声
     */
    @Override
    public void quack() {
        System.out.println(DuckCall.class.getSimpleName() + " kwak !");
    }
}

/**
 * 橡皮鸭
 */
public class RubberDuck implements Quckable {

    // 吱吱叫
    @Override
    public void quack() {
        System.out.println(RubberDuck.class.getSimpleName() + " squeak !");
    }
}

1.3 测试运行接口

不同鸭叫声模拟器

public class DuckSimulator {

    public static void main(String[] args) {
        DuckSimulator duckSimulator = new DuckSimulator();
        duckSimulator.simulate();
    }

    public void simulate() {
        MallardDuck mMallardDuck = new MallardDuck();
        DuckCall mDuckCall = new DuckCall();
        RubberDuck mRubberDuck = new RubberDuck();

        mMallardDuck.quack();
        mDuckCall.quack();
        mRubberDuck.quack();
    }
}

运行结果

MallardDuck quack!
DuckCall kwak !
RubberDuck squeak !

2.适配器模式

装饰对象,提供不同的接口

2.1 适配器 “大白鹅转鸭子的接口”

大白鹅也想用用quack()接口,但是大白鹅是不是鸭子类的,所以我们这里给大白鹅做了一个“大白鹅转鸭子的接口”

/**
 * 适配器模式,让鹅也使用quack()接口,但是出来的声音是鹅自己的咯咯叫
 */
public class GooseDuckAdapter implements Quckable{

    private Goose mGoose;

    public GooseDuckAdapter(Goose mGoose) {
        this.mGoose = mGoose;
    }

    @Override
    public void quack() {
        this.mGoose.honk();
    }
}

上述的honk()是大白鹅自己特有的咯咯叫方法

/**
 * 大白鹅是咯咯叫的
 */
public class Goose {


    /**
     * 咯咯叫
     */
    public void honk() {
        System.out.println(Goose.class.getSimpleName() + " honk!");
    }

}

适配器就这样做好了

2.2 运行实例和结果

    public static void main(String[] args) {
        DuckSimulator duckSimulator = new DuckSimulator();
        duckSimulator.simulate();
    }

    public void simulate() {
        MallardDuck mMallardDuck = new MallardDuck();
        DuckCall mDuckCall = new DuckCall();
        RubberDuck mRubberDuck = new RubberDuck();

        mMallardDuck.quack();
        mDuckCall.quack();
        mRubberDuck.quack();

        // 适配器模式
        GooseDuckAdapter mGooseDuckAdapter = new GooseDuckAdapter(new Goose());
        mGooseDuckAdapter.quack();
    }
}

运行结果

MallardDuck quack!
DuckCall kwak !
RubberDuck squeak !
Goose honk!

3.装饰者模式

3.1 定义

包装一个对象,提供一些新的行为

3.2 新增统计叫声的行为

/**
 * 装饰者模式
 * <p/>
 * 在原来Quckable的接口基础上新增统计叫声的功能,即装饰一个统计功能
 */
public class QuckableCounter implements Quckable {

    private Quckable mQuckable;
    private static int count = 0;

    public QuckableCounter(Quckable mQuckable) {
        this.mQuckable = mQuckable;
    }

    @Override
    public void quack() {
        mQuckable.quack();
        count++;
    }

    // 统计叫声
    public int getQuacksCounter() {
        return count;
    }
}

3.3 测试用例和运行结果

修改如下测试用例

    public void simulate() {
        Quckable mQuckable = new MallardDuck();
        QuckableCounter mQuckableCounter = new QuckableCounter(mQuckable);
        mQuckableCounter.quack();

        mQuckable = new DuckCall();
        mQuckableCounter = new QuckableCounter(mQuckable);
        mQuckableCounter.quack();

        mQuckable = new RubberDuck();
        mQuckableCounter = new QuckableCounter(mQuckable);
        mQuckableCounter.quack();


        mQuckable = new GooseDuckAdapter(new Goose());
        mQuckableCounter = new QuckableCounter(mQuckable);
        mQuckableCounter.quack();

        System.out.println("getQuacksCounter = " + mQuckableCounter.getQuacksCounter());
    }
}

运行结果如下

MallardDuck quack!
DuckCall kwak !
RubberDuck squeak !
Goose honk!
getQuacksCounter = 4

4 工厂模式

允许对象创建他们对象家族,无需指定他们的具体类

上述的鸭子类,我们打算改装成工厂的模式生成出来,因为他们本来就适合工厂方式创建

4.1 建立一个抽象接口

/**
 * 允许对象创建他们对象家族,无需指定他们的具体类
 */
public abstract class AbstractDuckFactory {

    // 绿头鸭
    public abstract Quckable createMallardDuck();

    // 橡皮鸭
    public abstract Quckable createRubberDuck();

    // 人造蜂鸣器
    public abstract Quckable createDuckCallDuck();
}

4.2 子类继承

实现对应鸭子方法

/**
 * 鸭子工厂
 * <p/>
 * 允许对象创建他们对象家族,无需指定他们的具体类
 */
public class CountDuckFactory extends AbstractDuckFactory {

    // 绿头鸭
    @Override
    public Quckable createMallardDuck() {
        return new QuckableCounter(new MallardDuck());
    }

    // 橡皮鸭
    @Override
    public Quckable createRubberDuck() {
        return new QuckableCounter(new RubberDuck());
    }

    // 人造鸭鸣器
    @Override
    public Quckable createDuckCallDuck() {
        return new QuckableCounter(new DuckCallDuck());
    }
}

测试用例和结果

用例如下

        AbstractDuckFactory mAbstractDuckFactory = new CountDuckFactory();
        // 绿头鸭
        Quckable mQuckable = mAbstractDuckFactory.createMallardDuck();
        mQuckable.quack();

        // 人造鸭鸣器
        mQuckable = mAbstractDuckFactory.createDuckCallDuck();
        mQuckable.quack();

        // 橡皮鸭
        mQuckable = mAbstractDuckFactory.createRubberDuck();
        mQuckable.quack();

结果

MallardDuck quack!
DuckCallDuck kwak !
RubberDuck squeak !

上述表明鸭子可以批量工厂出来了

5.迭代器模式

在对象集合中游走,而又不暴露对象的实现

上述的鸭子类叫声,我们希望统一管理。这里我们引进了迭代器

5.1 Flock羊群类

/**
 * 加个迭代器,便于统一调用quack()的方法
 *
 * 在对象集合中游走,而又不暴露对象的实现
 */
public class Flock implements Quckable {

    ArrayList<Quckable> list = new ArrayList<>();

    public void setFlock(Quckable quckable) {
        list.add(quckable);
    }

    @Override
    public void quack() {
        // 迭代器来了
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Quckable quckable = (Quckable) iterator.next();
            quckable.quack();
        }
    }
}

测试实例与结果

实例

        AbstractDuckFactory mAbstractDuckFactory = new CountDuckFactory();

        Flock mFlock = new Flock();
        // 绿头鸭
        mFlock.setFlock(mAbstractDuckFactory.createMallardDuck());
        // 人造鸭鸣器
        mFlock.setFlock(mAbstractDuckFactory.createDuckCallDuck());
        // 橡皮鸭
        mFlock.setFlock(mAbstractDuckFactory.createRubberDuck());
        // 迭代器模式进行统一管理叫声
        mFlock.quack();

运行结果

MallardDuck quack!
DuckCallDuck kwak !
RubberDuck squeak !
Goose honk!

6.观察者模式

假如我想观察一个鸭子的叫声

6.1 建立一个观察者接口

该接口保护注册和通知接口

/**
 * 观察者接口
 */
public interface IQuackObservable {

    public void registerObserver(IDuckUpdateOberver iDuckUpdateOberver);

    public void notifyObserver();

}

=======================================================
原来的叫声接口继承观察者接口
/**
 * 叫声接口
 */
public interface IQuckable extends IQuackObservable {

    // 呱呱叫
    public void quack();

}

=======================================================

6.2 基于上述被观察者修改如下

/**
 * 绿头鸭实现接口-(因为接口就是用来实现的)
 */
public class MallardDuck implements IQuckable {

    // 连通观察者与被观察者的类
    private DuckObservable mDuckObservable;

    public MallardDuck() {
        mDuckObservable = new DuckObservable(this);
    }

    /**
     * 呱呱叫
     */
    @Override
    public void quack() {
        System.out.println(MallardDuck.class.getSimpleName() + " quack!");
        // 叫声触发,通知观察者时间
        notifyObserver();
    }

    @Override
    public void registerObserver(IDuckUpdateOberver iDuckUpdateOberver) {
        mDuckObservable.registerObserver(iDuckUpdateOberver);
    }

    @Override
    public void notifyObserver() {
        mDuckObservable.notifyObserver();
    }
}

6.3观察者接口

public interface IDuckUpdateOberver {

    public void update(IQuackObservable qucack);
}

6.4观察者实现对应接口

// 我是一个观察者
public class SuFadiObserver implements IDuckUpdateOberver {

    @Override
    public void update(IQuackObservable qucack) {
        System.out.println("I obserber  " + qucack.getClass().getSimpleName());
    }
}

6.5连通观察者与被观察者

import java.util.ArrayList;
import java.util.Iterator;

public class DuckObservable implements IQuackObservable {

    private IQuackObservable mIQuack;
    ArrayList<IDuckUpdateOberver> list = new ArrayList<>();

    public DuckObservable(IQuackObservable mIQuack) {
        this.mIQuack = mIQuack;
    }

    @Override
    public void registerObserver(IDuckUpdateOberver iDuckUpdateOberver) {
        list.add(iDuckUpdateOberver);
    }

    @Override
    public void notifyObserver() {
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            IDuckUpdateOberver observable = (IDuckUpdateOberver) iterator.next();
            // 通知观察者
            observable.update(mIQuack);
        }
    }
}

6.5 运行结果

MallardDuck quack!
I obserber  MallardDuck

结语

本例中主要是复习设计模式的demo

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值