Java 设计模式 -- 复合模式之一
时间:2015-05-12 23:05:27
收藏:0
阅读:238
关于复合模式:
在形式上,复合模式确实是多个模式的组合,但满足了这一条并不一定是复合模式,注意它的定义:将多个模式结合起来形成一个“框架”,以解决一般性问题
一提到“框架”,可能最容易联想到的就是MVC吧,不过MVC确实是一个经典的复合模式
在进去MVC模式之前 先看一个简单的例子:
例子来自Headfrist 设计模式中的经典鸭鸣:有四种鸭鸣,
绿头鸭,叫声 Quack
红头鸭,叫声 Quack
鸭鸣器,叫声 Kwak
橡皮鸭,叫声 Squeak
现在我们需要实现这四种叫声,很明显,定义一个Quack接口 然后用四种类分别实现这个接口
代码如下:
public interface Quackable
{
public void quack();
}
public class MallardDuck implements Quackable{
@Override
public void quack()
{
// TODO Auto-generated
method stub
System. out.println("Quack!" ); //绿头鸭的叫法
是Quack
}
}
public class RedheadDuck implements Quackable{
@Override
public void quack()
{
// TODO Auto-generated
method stub
System. out.println("Quack!" );//红头鸭的叫法也是Quack
}
}
public class DuckCall implements Quackable
{
@Override
public void quack()
{
// TODO Auto-generated
method stub
System. out.println("Kwak!" ); //鸭鸣器的叫法是 Kwak
}
}
public class RubberDuck implements Quackable{
@Override
public void quack()
{
// TODO Auto-generated
method stub
System. out.println("Squeak!" );//橡皮鸭的叫法是
Squeak
}
}
下面再看测试类:
public class DuckSimulatorTest
{
public static void main(String
[]args)
{
DuckSimulatorTest duckTest= new DuckSimulatorTest();
duckTest.simulatortest();
}
void simulatortest()
{
Quackable mallQuackable= new MallardDuck();//定义绿头鸭
Quackable reQuackable= new RedheadDuck();//定义红头鸭
Quackable duckcall= new DuckCall();//定义鸭鸣器
Quackable rubber= new RubberDuck();//定义橡皮鸭
System. out.println("Test
Ducksimulator" );
Duckquack(mallQuackable);
Duckquack(reQuackable);
Duckquack(duckcall);
Duckquack(rubber);
}
void Duckquack(Quackable
duck)
{
duck.quack();
}
}
上面是简单的实现,但是现实中情况可能比较复杂,如,我们制导鹅的行为跟鸭子的行为非常相似,但是鹅的叫声显然跟鸭子不同,在学习设计模式中,我们知道有一种模式能够将一个接口实现为不同的接口:适配器模式
这里我们需要将 鹅适配成鸭子
鹅的叫声: Honk
public class Goose
{
public void honk()
{
System. out.println("Honk" );
}
}
定义适配器:
public class GooseAdapter implements Quackable
{
Goose goose;
public GooseAdapter(Goose
goose)
{
this.goose =goose;
}
@Override
public void quack()
{
// TODO Auto-generated
method stub
goose.honk();
}
}
然后在测试类中加入测试
Quackable gooseDuck= new GooseAdapter(new Goose());
我们继续 ,现在我们需要为每一只鸭子增加行为。
统计每一只鸭子叫了多少次,即在Quack方法上需要进行装饰,采用学到的装饰者模式
定义装饰者如下
public class QuackCounter implements Quackable{
Quackable duckQuackable;
static int numberofQuacks;
public QuackCounter(Quackable
duck)
{
this.duckQuackable =duck;
}
@Override
public void quack()
{
// TODO Auto-generated
method stub
duckQuackable.quack();
numberofQuacks++;
}
public static int getQuacks()
{
return numberofQuacks;
}
}
统计调用了多少次quack()方法
测试类如下
Quackable mallQuackable= new QuackCounter(new MallardDuck());//定义绿头鸭
Quackable reQuackable= new QuackCounter(new
RedheadDuck());//定义红头鸭
Quackable duckcall= new
QuackCounter(new DuckCall());//定义鸭鸣器
Quackable rubber= new QuackCounter(new RubberDuck());//定义橡皮鸭
System.out.println( "The
Duck quacked " + QuackCounter.getQuacks()+"
times");
输出如下:
Quack!
Quack!
Kwak!
Squeak!
Honk
The Duck quacked 4 times
接着上面,如果需要将创建鸭子和装饰鸭子集中在一个地方呢,这就需要用到工厂模式了
首先创建一个抽象工厂父类,将四种鸭子的创建集中起来
然后根据需要定义工厂子类,如果只需要实现鸭鸣(不需要统计鸭鸣次数),则下:
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
createDuackcall() {
// TODO Auto-generated
method stub
return new DuckCall();
}
@Override
public Quackable
createRubberDuck() {
// TODO Auto-generated
method stub
return new RubberDuck ();
}
}
如果需要统计鸭鸣次数,则在工厂实现中加上已经定义的装饰者:
public class CounterDuckFactory 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
createDuackcall() {
// TODO Auto-generated
method stub
return new QuackCounter( new DuckCall());
}
@Override
public Quackable
createRubberDuck() {
// TODO Auto-generated
method stub
return new QuackCounter( new RubberDuck());
}
}
继续,上面我们实现鸭鸣,实际上是一只鸭一只鸭的叫,我们如何使得能够记录一群鸭叫
我们想起了组合模式:允许我们对待单个对象一样对待对象集合
组合中的遍历我们可能会用到迭代器模式
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Flock implements Quackable{
List quacks = new ArrayList ();
public void add(Quackable
duck)
{
quacks .add(duck);
}
@Override
public void quack()
{
// TODO Auto-generated
method stub
Iterator iterator= quacks.iterator();
while (iterator.hasNext())
{
Quackable quackable=(Quackable)iterator.next();
quackable.quack();
}
}
}
测试代码如下:
void simulatortest(AbstractDuckFactory
duckFactory)
{
/*Quackable mallQuackable=new
MallardDuck();//定义绿头鸭
Quackable reQuackable=new RedheadDuck();//定义红头鸭
Quackable duckcall =new
DuckCall();//定义鸭鸣器
Quackable rubber=new RubberDuck();//定义橡皮鸭
*/
Quackable mallQuackable=duckFactory.createMallardDuck(); //定义绿头鸭
Quackable reQuackable=duckFactory.createRedheadDuck(); //定义红头鸭
Quackable duckcall=duckFactory.createDuackcall(); //定义鸭鸣器
Quackable rubber=duckFactory.createRubberDuck(); //定义橡皮鸭
Quackable gooseDuck= new GooseAdapter( new Goose());
System. out .println("Test
Ducksimulator" );
Flock flock= new Flock(); //首先将一群鸭子加入到flock中
,这种鸭子包含了岁有的种类
flock.add(mallQuackable);
flock.add(reQuackable);
flock.add(duckcall);
flock.add(rubber);
flock.add(gooseDuck);
//定义一群绿头鸭,仅仅含有绿头鸭
Flock flockmallard= new Flock();
Quackable mallardone=duckFactory.createMallardDuck();
Quackable mallardtwo=duckFactory.createMallardDuck();
Quackable mallardthree=duckFactory.createMallardDuck();
Quackable mallardfour=duckFactory.createMallardDuck();
Quackable mallardfive=duckFactory.createMallardDuck();
flockmallard.add(mallardone);
flockmallard.add(mallardtwo);
flockmallard.add(mallardthree);
flockmallard.add(mallardfour);
flockmallard.add(mallardfive);
//将绿头鸭群 flockmallard加入到
flock中
flock.add(flockmallard);
System. out .println("整群鸭子叫:" );
Duckquack(flock);
System. out .println("绿头鸭群叫" );
Duckquack(flockmallard);
System. out .println("The
Duck quacked " + QuackCounter.getQuacks ()+"
times");
}
到这里,简单的复合模式就到这里了,下面将要进行复合模式的深入学习-MVC模式
评论(0)