HeadFirst之设计模式 策略模式

策略模式设计
本文通过鸭子行为的例子介绍了策略模式的设计思想。策略模式允许在运行时选择算法或行为,通过定义一系列可互换的行为来实现这一目标。文章展示了如何通过接口定义和实现不同行为,并讨论了继承与组合的不同应用。

    对于很多的程序而言,我们为他设计一个很好的策略,那个什么什么是策略模式呢?
    举个例子吧:对于一个超市来说,他在不同的时间段会有不同的销售策略啊,比如消费到200元的 400元的 700元的给予打折,会员的等等,这些打折什么的其实就是一个计算方法的不同罢了。
     当然了,我们的HeadFirst不是针对这个例子实现的,他是说一个鸭子的实现,鸭子的一些操作可能会变化,如鸭子有会飞的,不会飞的,会叫的不会叫的,会游泳的不会游泳,那么怎么设计呢,我们需要定义这三个接口,让我们来面向接口编程吧。

   

package com.ownwell.strategy.interfaces;
/**
 * 飞动作
 * @author ownwell
 * 
 *
 */
public interface FlyBehavior {
        void fly();
}

  

 1 package com.ownwell.strategy.interfaces;
 2 
 3 /**
 4  * 鸣叫动作
 5  * @author ownwell
 6  *
 7  */
 8 public interface QuakBehavior {
 9     void quack();
10 }
View Code

 

 

package com.ownwell.strategy.interfaces;

/**
 * 游泳动作
 * @author ownwell
 *
 */
public interface SwingBehavior {
 void swing();
}
View Code

   上面的三个接口只是定义了一些函数(未实现),  那么让我们来实现这些具体的一些操作吧:

 1 package com.ownwell.strategy.implement;
 2 
 3 import com.ownwell.strategy.interfaces.FlyBehavior;
 4 
 5 /**
 6  * 用翅膀飛
 7  * @author Administrator
 8  *
 9  */
10 public class FlyWithWings implements FlyBehavior{
11 
12  public void fly() {
13   System.out.println("I can fly with my wings");
14   
15  }
16 
17 }
View Code
 1 package com.ownwell.strategy.implement;
 2 
 3 import com.ownwell.strategy.interfaces.FlyBehavior;
 4 
 5 /**
 6  * 俺不會飛啊
 7  * @author Administrator
 8  *
 9  */
10 public class NoWayFly implements FlyBehavior {
11 
12  @Override
13  public void fly() {
14   System.out.println("I cannot fly");
15 
16  }
17 }
View Code
package com.ownwell.strategy.implement;

import com.ownwell.strategy.interfaces.SwingBehavior;

/**
 * 我是個旱鴨子不怎麼會游泳
 * @author Administrator
 *
 */
public class NoWaySwing implements SwingBehavior {

 @Override
 public void swing() {
  System.out.println("I cannot swing");
 }
}
 1 package com.ownwell.strategy.implement;
 2 
 3 import com.ownwell.strategy.interfaces.SwingBehavior;
 4 /**
 5  * 用腳蹼游泳
 6  * @author Administrator
 7  *
 8  */
 9 public class SwingWithWebbed implements SwingBehavior {
10 
11  @Override
12  public void swing() {
13   System.out.println("I can swing with my webbeds");
14   
15  }
16 
17 }
View Code

这样就可以对飞和游泳来分别處理了,當然了你也可以組合了,現在我們要先定義一個抽象的鴨子類啊.

 1 package com.ownwell.strategy;
 2 
 3 import com.ownwell.strategy.interfaces.FlyBehavior;
 4 import com.ownwell.strategy.interfaces.QuakBehavior;
 5 import com.ownwell.strategy.interfaces.SwingBehavior;
 6 
 7 public abstract class IDuck {
 8  protected FlyBehavior flyBehavior   = null;
 9  protected QuakBehavior quakBehavior = null;
10  protected SwingBehavior swingBehavior         =null;
11  public IDuck() 
12  {
13  }
14  public abstract void display();
15  
16  public void flyPerform(){ 
17   if (flyBehavior != null) {
18    
19    flyBehavior.fly();
20   }
21  }
22  public void quakPerform(){
23   if(quakBehavior != null){
24    quakBehavior.quack();
25   }
26  }
27  public void swingPerform(){
28   if(swingBehavior != null)
29   {
30    
31    swingBehavior.swing();
32   }
33  }
34  
35  public void setFlyBehavior(FlyBehavior flyBehavior) {
36   this.flyBehavior = flyBehavior;
37  }
38  
39  public void setQuakBehavior(QuakBehavior quakBehavior) {
40   this.quakBehavior = quakBehavior;
41  }
42  
43  public void setSwingBehavior(SwingBehavior swingBehavior) {
44   this.swingBehavior = swingBehavior;
45  }
46 
47 }
View Code

   然而這是最好的么?
     我們現在要定義一個會叫但不會游泳的鴨子,怎麼辦啊?    不是,是我們想定義個一個會游泳但不叫的鴨子。   怎麼辦  ????


     現在我們來提示下:在那個IDuck裏面的get和set方法我們沒用到啊,對了就是可以通過外面傳遞鴨子的行為類:

 1 package com.ownwell.juint;
 2 
 3 import static org.junit.Assert.*;
 4 
 5 import org.junit.Test;
 6 
 7 import com.ownwell.strategy.IDuck;
 8 import com.ownwell.strategy.duckImp.DuckModel;
 9 import com.ownwell.strategy.implement.FlyWithWings;
10 import com.ownwell.strategy.implement.NoWayFly;
11 import com.ownwell.strategy.implement.NoWaySwing;
12 import com.ownwell.strategy.implement.SwingWithWebbed;
13 import com.ownwell.strategy.interfaces.FlyBehavior;
14 import com.ownwell.strategy.interfaces.SwingBehavior;
15 
16 public class TestDuck {
17 
18  @Test
19  public void test() {
20   IDuck duck = new IDuck() {
21    public void display() {
22     // TODO Auto-generated method stub
23     
24    }
25   };
26   
27   FlyBehavior flyWithWings          = new FlyWithWings();
28   FlyBehavior noWayFly              = new NoWayFly();
29   SwingBehavior swingWithWebbed     = new SwingWithWebbed();
30   SwingBehavior noWaySwing          = new NoWaySwing();
31   
32   duck.setFlyBehavior(flyWithWings);
33   duck.setSwingBehavior(noWaySwing);
34   
35   
36   duck.swingPerform();
37   duck.flyPerform();
38   
39  }
40 
41 }
View Code

   這四個是可以直接組合的,而不必每次都去實現IDUCK這裡只是對IDuck接口去實現它就OK了。
   現在我們比較一下是繼承了IDuck的DuckModel好還是我們自己對接口操作好呢?
  其實我們設計的一個原則就是少用繼承,而用組合。
   繼承就是子類實現父類的一些操作,而組合則是將不同的操作通過組合得到一個好的拓展.。

 

 

 

 

     

转载于:https://www.cnblogs.com/Cyning/articles/3189272.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值