通过一个例子将他们连接起来
例子
一群鸭子想学叫
叫的行为声明一个接口,让想叫的鸭子实现它就可以了。
/**
* @description: 行为接口化
* @date: 2020-06-21 07:59
* @author: 十一
*/
public interface Quackable {
void quack();
}
public class MallardDuack implements Quackable {
@Override
public void quack() {
System.out.println("MallardDuack");
}
}
public class RedHeadDuack implements Quackable {
@Override
public 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;
@Override
public 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;
@Override
public 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 {
@Override
public Quackable createMallardDuack() {
return new QuackCounter(new MallardDuack());
}
@Override
public Quackable createRedHeadDuack() {
return new QuackCounter(new RedHeadDuack());
}
@Override
public 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();
@Override
public 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小时的全方位无死角监控!