设计模式之复合模式

使用模式最棒的方式,就是把他们从家里找出来同其他模式展开交互。这就是复合模式。

我们将重访SimUDuck鸭子模拟器中那些鸭子。

我们将从头重建我们的鸭子模拟器。

首先,创建一个Quackable接口:

public interface Quackable {
	public void quack();

}

某些鸭子实现此接口:

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

}

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

}

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

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

}


好了,有了鸭子,还需要一个模拟器:

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();
	}

}

结果:

Duck Simulator
Quack
Quack
Kwak
Squeak


当鸭子出现在这里,鹅应该在附近:

public class Goose {
	public void honk(){
		System.out.println("Honk");
	}

}

把鸭子和鹅掺合在一起,需要鹅适配器:

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

}

现在在模拟器中可以使用鹅了:

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();
		Quackable gooseDuck=new GooseAdapter(new Goose());//把goose包装成GooseAdapter
		
		System.out.println("\nDuck Simulator");
		
		simulate(mallardDuck);
		simulate(redHeadDUck);
		simulate(duckCall);
		simulate(rubberDuck);
		simulate(gooseDuck);
	}
	
	void simulate(Quackable duck){
		duck.quack();
	}

}

结果:

Duck Simulator
Quack
Quack
Kwak
Squeak
Honk

呱呱叫学家想要不变化鸭子类的情况下,计算呱呱叫的次数,我们可以创建一个装饰者,通过把鸭子包装进装饰者对象,给鸭子一些新行为:

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 class DuckSimulator {
	public static void main(String[]args){
		DuckSimulator simulator=new DuckSimulator();
		simulator.simulate();
	}
	
	void simulate(){
		Quackable mallardDuck=new QuackCounter(new MallardDuck());
		Quackable redHeadDUck=new QuackCounter( new RedHeadDuck());
		Quackable duckCall=new QuackCounter(new DuckCall());
		Quackable rubberDuck=new QuackCounter(new RubberDuck());
		Quackable gooseDuck=new GooseAdapter(new Goose());//我们不装饰鹅
		
		System.out.println("\nDuck Simulator:with decorator");
		
		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();
	}

}

结果:

Duck Simulator:with decorator
Quack
Quack
Kwak
Squeak
Honk
The ducks quacked 4 times

包装对象才有效果,没包装就没效果,我们可以将创建和装饰的部分包装起来,工厂模式:

public abstract class AbstractDuckFactory {
	public abstract Quackable createMallardDuck();
	public abstract Quackable createRedHeadDuck();
	public abstract Quackable createDuckCall();
	public abstract Quackable createRubberDuck();

}

创建一个没有装饰者的工厂:

public class DuckFactory extends AbstractDuckFactory{

	@Override
	public Quackable createMallardDuck() {
		// TODO Auto-generated method stub
		return new MallardDuck();
	}

	@Override
	public Quackable createRedHeadDuck() {
		// TODO Auto-generated method stub
		return new RedHeadDuck();
	}

	@Override
	public Quackable createDuckCall() {
		// TODO Auto-generated method stub
		return new DuckCall();
	}

	@Override
	public Quackable createRubberDuck() {
		// TODO Auto-generated method stub
		return new RubberDuck();
	}
	
//模拟器并不知道实际产品是什么,只知道实现了Quackable接口
}

创建我们想要的工厂:

public class CountingDuckFactory extends AbstractDuckFactory{

	@Override
	public Quackable createMallardDuck() {
		// TODO Auto-generated method stub
		return new QuackCounter(new MallardDuck());
	}

	@Override
	public Quackable createRedHeadDuck() {
		// TODO Auto-generated method stub
		return new QuackCounter(new RedHeadDuck());
	}

	@Override
	public Quackable createDuckCall() {
		// TODO Auto-generated method stub
		return new QuackCounter(new DuckCall());
	}

	@Override
	public Quackable createRubberDuck() {
		// TODO Auto-generated method stub
		return new QuackCounter(new RubberDuck());
	}

}

设置模拟器:

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();
	}

}

结果:

Duck Simulator:with abstract factory
Quack
Quack
Kwak
Squeak
Honk
The ducks quacked 4 times

现在管理员想管理一群鸭子,而不是个别,我们可以用到组合模式:

public class Flock implements Quackable{
	ArrayList quackers=new ArrayList<>();
	
	public void add(Quackable quacker){
		quackers.add(quacker);
	}
	
	public void quack(){
		Iterator iterator=quackers.iterator();//迭代器模式
		while(iterator.hasNext()){
			Quackable quacker=(Quackable)iterator.next();
			quacker.quack();
		}
	}
	

}

修改模拟器:

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 composite-flocks");
		
		Flock flockOfDucks=new Flock();
		
		flockOfDucks.add(redHeadDUck);
		flockOfDucks.add(rubberDuck);
		flockOfDucks.add(duckCall);
		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("The ducks quacked "+QuackCounter.getQuacks()+" times");
	}
	
	void simulate(Quackable duck){
		duck.quack();
	}

}

结果:

Duck Simulator:with composite-flocks

Duck Simulator:Whole Flock Simulation
Quack
Squeak
Kwak
Honk
Quack
Quack
Quack
Quack

Duck Simulator:Mallard Flock Simulation
Quack
Quack
Quack
Quack
The ducks quacked 11 times

管理员又有新的要求了,需要跟踪个别的鸭子,我们可以用观察者模式:

首先需要一个Observable接口;(这里的Observable就是被观察者)

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

}

需要确定所有的quackable都实现此接口:

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

}
确定所有实现Quackable的具体类都扮演QuackObservable的角色:

我们需要在每一个类中实现注册和通知,这次我们要用稍微不一样的做法:

我们要在另一个被称为Observable的类中封装注册和通知的代码,然后将它和QuackObservable组合在一起。

Observer辅助类:

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


public class Observable implements QuackObservable{
	ArrayList observers=new ArrayList<>();
	QuackObservable duck;
	
	public Observable(QuackObservable duck){
		this.duck=duck;
	}
	
	public void registerObserver(Observer observer){
		observers.add(observer);
	}
	
	public void notifyObservers(){
		Iterator iterator=observers.iterator();
		while(iterator.hasNext()){
			Observer observer=(Observer)iterator.next();
			observer.update(duck);
		}
 	}


}

整合Observable辅助类和Quackable类:

下面是MallardDuck实现,其他一样

public class MallardDuck implements Quackable{
	Observable observable;
	
	public MallardDuck(){
		observable=new Observable(this);
	}
	
	public void quack(){
		System.out.println("Quack");
		notifyObservers();
	}

	@Override
	public void registerObserver(Observer observer) {
		// TODO Auto-generated method stub
		observable.registerObserver(observer);
	}

	@Override
	public void notifyObservers() {
		// TODO Auto-generated method stub
		observable.notifyObservers();
	}

}


QuackCOunter装饰者

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;
	}

	@Override
	public void registerObserver(Observer observer) {
		// TODO Auto-generated method stub
		duck.registerObserver(observer);
	}

	@Override
	public void notifyObservers() {
		// TODO Auto-generated method stub
		duck.notifyObservers();
	}

}

Observer端:

public interface Observer {
	public void update(QuackObservable duck);

}

public class Quackologist implements Observer{
	public void update(QuackObservable duck){
		System.out.println("Quackologist: "+duck+" just quacked.");
	}

}

如果要观察整个群的话:

public class Flock implements Quackable{
	ArrayList quackers=new ArrayList<>();
	
	public void add(Quackable quacker){
		quackers.add(quacker);
	}
	
	public void quack(){
		Iterator iterator=quackers.iterator();
		while(iterator.hasNext()){
			Quackable quacker=(Quackable)iterator.next();
			quacker.quack();
		}
	}

	@Override
	public void registerObserver(Observer observer) {
		// TODO Auto-generated method stub
		Iterator iterator=quackers.iterator();
		while(iterator.hasNext()){
			Quackable duck=(Quackable)iterator.next();
			duck.registerObserver(observer);
		}
	}

	@Override
	public void notifyObservers() {
		// TODO Auto-generated method stub
		
	}

	
	

}

更新模拟器:

public class DuckSimulator {
	public static void main(String[]args){
		DuckSimulator simulator=new DuckSimulator();
		AbstractDuckFactory duckFactory=new CountingDuckFactory();
		simulator.simulate(duckFactory);
	}
	
	void simulate(AbstractDuckFactory duckFactory){	
		
		System.out.println("\nDuck Simulator:with observer");
		
		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);
		
		
		Quackologist quackologist=new Quackologist();
		flockOfMallards.registerObserver(quackologist);
		simulate(flockOfMallards);
		
		System.out.println("The ducks quacked "+QuackCounter.getQuacks()+" times");
	}
	
	void simulate(Quackable duck){
		duck.quack();
	}

}

结果:

Duck Simulator:with observer
Quack
Quackologist: duck.MallardDuck@4aa0b07b just quacked.
Quack
Quackologist: duck.MallardDuck@7ba28183 just quacked.
Quack
Quackologist: duck.MallardDuck@69e4fede just quacked.
Quack
Quackologist: duck.MallardDuck@3918d722 just quacked.
The ducks quacked 4 times




这个例子主要的目的是展示许多模式可以合作,真实的设计过程中,不会想要这么做,不然有点杀鸡用牛刀的赶脚。


MVC模式是一个典型的复合模式。

MVC,即model-view-controller,比如一个MP3播放器底层就是MVC模式。

1、你是用户,你和视图交互。视图是模型的窗口。

2、控制器要求模型状态改变。

3、控制器也有可能要求视图做改变。

4、模型状态改变时,模型会通知视图。

5、视图向模型询问状态。

最典型的MVC就是JSP + servlet + javabean的模式.

从设计模式看,模型利用观察者让控制器和视图可以随最新的状态改变而更新。另一方面,视图和控制器则实现了策略模式。控制器是视图的行为,如果你希望不同的行为,可以直接换一个控制器。视图内部使用组合模式来管理窗口、按钮以及其他显示组件。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值