模式通常被一起使用,并被组合在同一个解决方案中。
复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题。
首先重新构建鸭子模拟器:
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");
	}
}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,有鸭子的地方大概率就会有鹅,怎样在模拟器使用鹅呢?适配器
package headfirst.designpatterns.combining.adapter;
public class Goose {
	public void honk() {
		System.out.println("Honk");
	}
}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,如果在不变化鸭子类的情况下,计算呱呱叫的次数呢?装饰者
将鸭子包装进装饰者对象,赋予鸭子一些新行为。
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();
	}
}// 更新模拟器
Quackable mallardDuck = new QuackCounter(new MallardDuck());需求3,有时候我们在代码中可能搞忘装饰对象,所以我们希望在最开始创建的时候就确保鸭子是被装饰过的:工厂模式
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();
}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());
	}
}抽象工厂通过传入不同的工厂到创建方法中,得到不同的产品家族。
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,同时管理一群鸭子:组合模式
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";
	}
}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,持续追踪个别鸭子的实时呱呱叫:观察者模式
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类中封装注册和通知的代码,然后将其和具体类组合在一起。
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();
	}
}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";
	}
}
------------------------------------------------------------------------------------



















