码迷,mamicode.com
首页 > 编程语言 > 详细

Java 设计模式 -- 复合模式之一

时间:2015-05-12 23:05:27      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:java设计模式

关于复合模式:
在形式上,复合模式确实是多个模式的组合,但满足了这一条并不一定是复合模式,注意它的定义:将多个模式结合起来形成一个“框架”,以解决一般性问题            
一提到“框架”,可能最容易联想到的就是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模式

Java 设计模式 -- 复合模式之一

标签:java设计模式

原文地址:http://blog.csdn.net/yujin753/article/details/45675375

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!