设计模式之十二:复合模式

模式通常被一起使用,并被组合在同一个解决方案中。

复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题。

首先重新构建鸭子模拟器:

java 复制代码
package headfirst.designpatterns.combining.ducks;

public interface Quackable {
	public void quack();
}


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


public class RubberDuck implements Quackable {
	public void quack() {
		System.out.println("Squeak");
	}
}
java 复制代码
package headfirst.designpatterns.combining.ducks;

public class DuckSimulator {
	public static void main(String[] args) {
		DuckSimulator simulator = new DuckSimulator();
		simulator.simulate();
	}
  
	void simulate() {
		Quackable mallardDuck = new MallardDuck();
		Quackable redheadDuck = new RedheadDuck();
		Quackable duckCall = new DuckCall();
		Quackable rubberDuck = new RubberDuck();
 
		System.out.println("\nDuck Simulator");
 
		simulate(mallardDuck);
		simulate(redheadDuck);
		simulate(duckCall);
		simulate(rubberDuck);
	}
   
	void simulate(Quackable duck) {
		duck.quack();
	}
}

需求1,有鸭子的地方大概率就会有鹅,怎样在模拟器使用鹅呢?适配器

java 复制代码
package headfirst.designpatterns.combining.adapter;

public class Goose {
	public void honk() {
		System.out.println("Honk");
	}
}
java 复制代码
package headfirst.designpatterns.combining.adapter;

public class GooseAdapter implements Quackable {
	Goose goose;
 
	public GooseAdapter(Goose goose) {
		this.goose = goose;
	}
 
	public void quack() {
		goose.honk();
	}

	public String toString() {
		return "Goose pretending to be a Duck";
	}
}

需求2,如果在不变化鸭子类的情况下,计算呱呱叫的次数呢?装饰者

将鸭子包装进装饰者对象,赋予鸭子一些新行为。

java 复制代码
package headfirst.designpatterns.combining.decorator;

public class QuackCounter implements Quackable {
	Quackable duck;
	static int numberOfQuacks;
  
	public QuackCounter (Quackable duck) {
		this.duck = duck;
	}
  
	public void quack() {
		duck.quack();
		numberOfQuacks++;
	}
 
	public static int getQuacks() {
		return numberOfQuacks;
	}
	public String toString() {
		return duck.toString();
	}
}
java 复制代码
// 更新模拟器

Quackable mallardDuck = new QuackCounter(new MallardDuck());

需求3,有时候我们在代码中可能搞忘装饰对象,所以我们希望在最开始创建的时候就确保鸭子是被装饰过的:工厂模式

java 复制代码
package headfirst.designpatterns.combining.factory;

public abstract class AbstractDuckFactory {
 
	public abstract Quackable createMallardDuck();
	public abstract Quackable createRedheadDuck();
	public abstract Quackable createDuckCall();
	public abstract Quackable createRubberDuck();
}
java 复制代码
package headfirst.designpatterns.combining.factory;

public class CountingDuckFactory extends AbstractDuckFactory {
  
	public Quackable createMallardDuck() {
		return new QuackCounter(new MallardDuck());
	}
  
	public Quackable createRedheadDuck() {
		return new QuackCounter(new RedheadDuck());
	}
  
	public Quackable createDuckCall() {
		return new QuackCounter(new DuckCall());
	}
   
	public Quackable createRubberDuck() {
		return new QuackCounter(new RubberDuck());
	}
}

抽象工厂通过传入不同的工厂到创建方法中,得到不同的产品家族。

java 复制代码
package headfirst.designpatterns.combining.factory;

public class DuckSimulator {
	public static void main(String[] args) {
		DuckSimulator simulator = new DuckSimulator();
		AbstractDuckFactory duckFactory = new CountingDuckFactory();
 
		simulator.simulate(duckFactory);
	}
 
	void simulate(AbstractDuckFactory duckFactory) {
		Quackable mallardDuck = duckFactory.createMallardDuck();
		Quackable redheadDuck = duckFactory.createRedheadDuck();
		Quackable duckCall = duckFactory.createDuckCall();
		Quackable rubberDuck = duckFactory.createRubberDuck();
		Quackable gooseDuck = new GooseAdapter(new Goose());
 
		System.out.println("\nDuck Simulator: With Abstract Factory");
 
		simulate(mallardDuck);
		simulate(redheadDuck);
		simulate(duckCall);
		simulate(rubberDuck);
		simulate(gooseDuck);
 
		System.out.println("The ducks quacked " + 
		                   QuackCounter.getQuacks() + 
		                   " times");
	}
 
	void simulate(Quackable duck) {
		duck.quack();
	}
}

需求4,同时管理一群鸭子:组合模式

java 复制代码
package headfirst.designpatterns.combining.composite;

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

public class Flock implements Quackable {
	ArrayList<Quackable> quackers = new ArrayList<Quackable>();
 
	public void add(Quackable quacker) {
		quackers.add(quacker);
	}
 
	public void quack() {
		Iterator<Quackable> iterator = quackers.iterator();
		while (iterator.hasNext()) {
			Quackable quacker = iterator.next();
			quacker.quack();
		}
	}
 
	public String toString() {
		return "Flock of Quackers";
	}
}
java 复制代码
package headfirst.designpatterns.combining.composite;

public class DuckSimulator {

	public static void main(String[] args) {
		DuckSimulator simulator = new DuckSimulator();
		AbstractDuckFactory duckFactory = new CountingDuckFactory();
 
		simulator.simulate(duckFactory);
	}
 
	void simulate(AbstractDuckFactory duckFactory) {
		Quackable redheadDuck = duckFactory.createRedheadDuck();
		Quackable duckCall = duckFactory.createDuckCall();
		Quackable rubberDuck = duckFactory.createRubberDuck();
		Quackable gooseDuck = new GooseAdapter(new Goose());

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

		Flock flockOfDucks = new Flock();

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

		Flock flockOfMallards = new Flock();

		Quackable mallardOne = duckFactory.createMallardDuck();
		Quackable mallardTwo = duckFactory.createMallardDuck();
		Quackable mallardThree = duckFactory.createMallardDuck();
		Quackable mallardFour = duckFactory.createMallardDuck();

		flockOfMallards.add(mallardOne);
		flockOfMallards.add(mallardTwo);
		flockOfMallards.add(mallardThree);
		flockOfMallards.add(mallardFour);

		flockOfDucks.add(flockOfMallards);

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

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

		System.out.println("\nThe ducks quacked " + 
		                   QuackCounter.getQuacks() + 
		                   " times");
	}

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

需求5,持续追踪个别鸭子的实时呱呱叫:观察者模式

java 复制代码
package headfirst.designpatterns.combining.observer;

public interface QuackObservable {
	public void registerObserver(Observer observer);
	public void notifyObservers();
}


public interface Quackable extends QuackObservable {
	public void quack();
}

现在需要保证Quackable的具体类都能扮演QuackObservable角色(在具体类中添加一个arraylist变量,然后实现接口方法)。但这里用的不同的做法(不知道为什么),在Observable类中封装注册和通知的代码,然后将其和具体类组合在一起。

java 复制代码
package headfirst.designpatterns.combining.observer;

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

public class Observable implements QuackObservable {
	List<Observer> observers = new ArrayList<Observer>();
	QuackObservable duck;
 
	public Observable(QuackObservable duck) {
		this.duck = duck;
	}
  
	public void registerObserver(Observer observer) {
		observers.add(observer);
	}
  
	public void notifyObservers() {
		Iterator<Observer> iterator = observers.iterator();
		while (iterator.hasNext()) {
			Observer observer = iterator.next();
			observer.update(duck);
		}
	}
 
	public Iterator<Observer> getObservers() {
		return observers.iterator();
	}
}
java 复制代码
package headfirst.designpatterns.combining.observer;

public class MallardDuck implements Quackable {
	Observable observable;
 
	public MallardDuck() {
		observable = new Observable(this);
	}
 
	public void quack() {
		System.out.println("Quack");
		notifyObservers();
	}
 
	public void registerObserver(Observer observer) {
		observable.registerObserver(observer);
	}
 
	public void notifyObservers() {
		observable.notifyObservers();
	}
 
	public String toString() {
		return "Mallard Duck";
	}
}

相关推荐
Leo来编程11 小时前
设计模式1-单例模式
单例模式·设计模式
危险库11 小时前
单例模式:确保一个类只有一个实例【设计模式】
javascript·单例模式·设计模式
已读不回14314 小时前
设计模式-策略模式
前端·算法·设计模式
饕餮争锋19 小时前
设计模式笔记_行为型_访问者模式
笔记·设计模式·访问者模式
写bug写bug1 天前
你真的会用枚举吗
java·后端·设计模式
哆啦code梦1 天前
趣谈设计模式之策略模式-比特咖啡给你一杯满满的情绪价值,让您在数字世界里”畅饮“
设计模式·策略模式
华仔啊1 天前
别学23种了!Java项目中最常用的6个设计模式,附案例
java·后端·设计模式
Keya2 天前
MacOS端口被占用的解决方法
前端·后端·设计模式
已读不回1432 天前
设计模式-单例模式
前端·设计模式
long3162 天前
构建者设计模式 Builder
java·后端·学习·设计模式