码迷,mamicode.com
首页 > 移动开发 > 详细

策略模式在android中使用

时间:2015-04-25 15:11:11      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:android   设计模式   

策略模式(Strategy)

策略模式是对象的行为模式。它的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换。策略模式使得算法可以在不修改或影响到调用端的情况下发生变化。

下面来讨论下策略模式的结构类图,具体如下:

技术分享

从上面的结构图中,我们可以看出策略模式涉及到了三个角色,具体角色如下所示:

A、抽象策略角色:这是个抽象角色,通常是由一个接口或是抽象类来实现。它为所有的具体策略类提供了需要的接口。

B、具体策略角色:这个角色包装了相关的算法和行为,用来执行对应的策略事件。

C、环境角色:这个角色中含有一个对抽象策略类的引用,也是供外部调用直接接触的角色。

下面具体举个例子来使用策略模式。例子是这样的:现在要做一个上网使用得app,接入的网络类型有三种,分别为CMCC、ChinaNet及普通的Wifi类型,所以针对这几种类型的网络,我们需要定义一个抽象的策略角色,然后再定义三个具体角色,每个具体的角色中实现具体的功能细节,最后,我们在前端放置三个按钮,点击对应的按钮调用对应的具体角色逻辑(通过调用抽象角色)。下面为我的代码逻辑实现以及部分说明文字:

抽象策略角色(WifiConnectStrategy):

/**

 *  抽象策略角色

 */

public abstract class WifiConnectStrategy implements Callback{

   private WifiConnectStrategyListener listener = null;

   protected WifiState wifiState = null;

  

   protected Handler handler = null;

   protected static final long CONN_WIFI_TIME = 2000;  // 连接wifi的时间(模拟)

  

   public WifiConnectStrategy() {

      handler = new Handler(WifiConnectStrategy.this);

   }

  

   public voidsetWifiConnectStrategyListener(WifiConnectStrategyListener listener) {

      this.listener = listener;

   }

  

   /**

    * 创建一个策略,根据wifitype

    */

   public static WifiConnectStrategycreateWithWifiType(WifiType wifiType) {

      WifiConnectStrategy result = null;

      switch (wifiType) {

      case CMCC:

         result = new CMCCWifiConnectStrategy();

         break;

      case CHINANET:

         result = new ChinaNetWifiConnectStrategy();

         break;

      case COMMON:

         result = new CommonWifiConnectStrategy();

         break;

      default:

         break;

      }

      return result;

   }

  

   public voidconfigWifiState(WifiState wifiState) {

      this.wifiState = wifiState;

   }

  

   /**

    * 连接到网络的方法

    */

   public abstract void executeConnectNetRun();

  

   /**

    * 模拟链接后返回的结果

    */

   public abstract void connectResult();

  

   // 模拟网络链接延迟

   protected void simulateConnect() {

      this.handler.removeMessages(1);

      this.handler.sendEmptyMessageDelayed(1,CONN_WIFI_TIME);

   }

  

   @Override

   public booleanhandleMessage(Message msg) {

      connectResult();

      return true;

   }

  

   public WifiConnectStrategyListener getListener() {

      return listener;

   }

 

   public voidsetListener(WifiConnectStrategyListener listener) {

      this.listener = listener;

   }

  

   public void log(String log) {

      Log.d("WifiConnectStrategy", log);

   }

 

}

 

具体策略角色(CMCC):

/**

 * 具体策略角色

 */

public class CMCCWifiConnectStrategy extends WifiConnectStrategy {

  

   public CMCCWifiConnectStrategy() {

      super();

   }

  

   @Override

   public voidexecuteConnectNetRun() {

      log("cmcc connect ...");

     

      // 链接网络核心代码(异步)

      // TODO

     

      // 模拟网络链接延迟

      simulateConnect();

   }

 

   @Override

   public void connectResult(){

      getListener().cmccConnResult(this.wifiState.getWifiLabel() +"连接成功!");

   }

}

 

具体策略角色(ChinaNet):

public classChinaNetWifiConnectStrategy extendsWifiConnectStrategy {

  

   public ChinaNetWifiConnectStrategy() {

      super();

   }

 

   @Override

   public voidexecuteConnectNetRun() {

      log("chinanet connect ...");

     

      // 链接网络核心代码

      // TODO

     

      // 模拟网络链接延迟

      simulateConnect();

   }

 

   @Override

   public void connectResult(){

      getListener().cmccConnResult(this.wifiState.getWifiLabel() +"连接成功!");

   }

}

 

具体策略角色(Common wifi):

public classCommonWifiConnectStrategy extendsWifiConnectStrategy {

  

   public CommonWifiConnectStrategy() {

      super();

   }

  

   @Override

   public void executeConnectNetRun(){

      log("common connect ...");

     

      // 链接网络核心代码

      // TODO

     

      // 模拟网络链接延迟

      simulateConnect();

   }

 

   @Override

   public void connectResult(){

      getListener().cmccConnResult(this.wifiState.getWifiLabel() +"连接成功!");

   }

 

}

 

下面为我们具体的环境角色,主要就是引用一个抽象策略角色,以及根据不同网络类型创建对应的具体策略角色,具体如下:

public class MainActivity extends Activity implements OnClickListener {

   private Button btnCmcc = null;

   private Button btnChinanet = null;

   private Button btnCommon = null;

  

   private WifiConnectStrategy wifiConnectStrategy;

  

   private WifiState selectedState = new WifiState();

  

   private WifiConnectStrategyListener listener = new WifiConnectStrategyListener() {

      @Override

      public voidcmccConnResult(String state) {

         log(state);

      }

 

      @Override

      public void chinanetConnResult(Stringstate) {

         log(state);

      }

 

      @Override

      public voidcommonConnResult(String state) {

         log(state);

      }

     

   };

  

   @Override

   protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_main);

     

      btnCmcc = (Button) findViewById(R.id.btnCmcc);

      btnChinanet = (Button) findViewById(R.id.btnChinanet);

      btnCommon = (Button) findViewById(R.id.btnCommon);

     

      btnCmcc.setOnClickListener(this);

      btnChinanet.setOnClickListener(this);

      btnCommon.setOnClickListener(this);

   }

 

   @Override

   public void onClick(View v) {

      if (null != wifiConnectStrategy) {

         wifiConnectStrategy = null;

      }

     

      if(v.getId() == R.id.btnCmcc) {

         selectedState.setCardNo("cmcc+1167278922");

         selectedState.setIpAddress(192168013);

         selectedState.setPassword("123456");

         selectedState.setWifiLabel("CMCC");

         selectedState.setSsid("dafadfdadada");

         selectedState.setWifiType(WifiType.CMCC);

         wifiConnSpecial(selectedState);

      }

      else if (v.getId() == R.id.btnChinanet) {

         selectedState.setCardNo("cmcc+1167272222");

         selectedState.setIpAddress(192168433);

         selectedState.setPassword("123456777");

         selectedState.setWifiLabel("ChinaNet");

         selectedState.setSsid("dafadeeeedada");

         selectedState.setWifiType(WifiType.CHINANET);

         wifiConnSpecial(selectedState);

      }

      else {

         selectedState.setIpAddress(192168111);

         selectedState.setPassword("123456789");

         selectedState.setWifiLabel("COMMON");

         selectedState.setSsid("dafadeeeSSDASF");

         selectedState.setWifiType(WifiType.COMMON);

         wifiConnCommon(selectedState);

      }

   }

  

   private voidwifiConnSpecial(WifiState wifiState) {

      wifiConnectStrategy = WifiConnectStrategy.createWithWifiType(selectedState.getWifiType());

      wifiConnectStrategy.configWifiState(wifiState);

      wifiConnectStrategy.setWifiConnectStrategyListener(listener);

      wifiConnectStrategy.executeConnectNetRun();

   }

  

   private voidwifiConnCommon(WifiState wifiState) {

      wifiConnectStrategy = WifiConnectStrategy.createWithWifiType(selectedState.getWifiType());

      wifiConnectStrategy.configWifiState(wifiState);

      wifiConnectStrategy.setWifiConnectStrategyListener(listener);

      wifiConnectStrategy.executeConnectNetRun();

   }

  

   private void log(String log) {

      Log.d("WifiConnectStrategy",log);

   }

}

 

注意:这里的WifiState类为wifi的封装类,WifiConnectStrategyListener为监听网络链接的接口。接下来,我会在下面罗列出他们的代码构成。

WifiState:

public class WifiState {

   // wifi name

   private String wifiLabel;

   // wifi ip

   private int ipAddress;

   // wifi ssid

   private String ssid;

   // wifi password

   private String password;

   // card no

   private String cardNo;

   // 类型

   private WifiType wifiType;

  

   // wifi 类型

   public enum WifiType {

      CMCC(1),

      CHINANET(2),

      COMMON(3);

     

      private final int type;

 

      private WifiType(int type) {

         this.type = type;

      }

     

      public int getType() {

         return type;

      }

     

      public static WifiTypegetType(int wifiType) {

         WifiTypetype = null;

         if(WifiType.CMCC.getType() == wifiType) {

            type = WifiType.CMCC;

         }

         else if(WifiType.CHINANET.getType() == wifiType) {

            type = WifiType.CHINANET;

         }

         else if(WifiType.COMMON.getType() == wifiType) {

            type = WifiType.COMMON;

         }

         return type;

      }

   }

 

   public int getIpAddress() {

      return ipAddress;

   }

 

   public void setIpAddress(int ipAddress) {

      this.ipAddress = ipAddress;

   }

 

   public String getSsid() {

      return ssid;

   }

 

   public void setSsid(String ssid) {

      this.ssid = ssid;

   }

 

   public String getPassword() {

      return password;

   }

 

   public voidsetPassword(String password) {

      this.password = password;

   }

 

   public String getCardNo() {

      return cardNo;

   }

 

   public void setCardNo(StringcardNo) {

      this.cardNo = cardNo;

   }

 

   public String getWifiLabel() {

      return wifiLabel;

   }

 

   public voidsetWifiLabel(String wifiLabel) {

      this.wifiLabel = wifiLabel;

   }

 

   public WifiType getWifiType() {

      return wifiType;

   }

 

   public voidsetWifiType(WifiType wifiType) {

      this.wifiType = wifiType;

   }

}

 

WifiConnectStrategyListener:

/**

 * wifi链接的监听

 */

public interfaceWifiConnectStrategyListener {

  

   public voidcmccConnResult(String state);

  

   public voidchinanetConnResult(String state);

  

   public voidcommonConnResult(String state);

  

}

 

好了,运行下代码,页面效果如下:

技术分享

当我们点击对应的按钮链接网络时,会在输出日志打印对应的wifi链接以及链接成功,当然,这是只是模拟实现,实际上整个过程没这么简单,比如需要先获得卡号,然后异步链接,获得返回的信息,链接是否成功等。

日志如下:

 技术分享

 

好了,到这里,策略模式的介绍就完成了,稍后会把项目代码上传,希望对大家有帮助。

代码点击这里下载,下载

 

技术交流群:179914858

 

 

策略模式在android中使用

标签:android   设计模式   

原文地址:http://blog.csdn.net/why_2012_gogo/article/details/45270101

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