前言
本文来自《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