策略模式



“策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于算法的客户”

场景:
一个基类有很多个子类,现在他们需要实现一个共同的函数,凡是各个子类的实现可能各有不同,这时候应该怎么办?

思路1:把这个函数写在基类里,然后子类去根据自己的需要重写这个函数
好处:代码可以复用,对应了设计原则“找出应用中可能变化之处,把它独立出来,不要和那些不变的代码混在一起”
坏处:可能会有子类不小心忘了写了,就直接继承了基类的实现,这样的错误比较难查

思路2:直接把这个方法做成接口放到基类里,然后子类去实现
好处:代码的灵活性很好,各个子类修改自己的方法不会影响别人,对应了设计原则“多用组合 少用继承”
坏处:代码无法复用

所以,这两者扬长避短,形成了一个这样的解决思路:
1. 先一个新的接口,用来解决问题,然后做出它的实现一系列。
2. 在父类里实例化一个这个接口。然后在那个函数里调用这个接口的方法解决问题
3.子类为这个接口选择实现

这就等于把这个函数的实现委托给了另一个类,两个类组合起来解决问题,“多用组合 少用继承”

 

标准实现

基类:

 

Java代码 复制代码  收藏代码
  1. public abstract class Base {  
  2.   
  3.      protect Behavior beh;  
  4.   
  5.      public Base() {  
  6.      }  
  7.   
  8.      protect void setBehavior(Behavior beh) {  
  9.           this.beh = ben;  
  10.      }  
  11.   
  12.      public void performBehavior() {  
  13.           if (beh != null) {  
  14.                beh.doIt();  
  15.           }  
  16.      }  
  17. }  
public abstract class Base {

     protect Behavior beh;

     public Base() {
     }

     protect void setBehavior(Behavior beh) {
          this.beh = ben;
     }

     public void performBehavior() {
          if (beh != null) {
               beh.doIt();
          }
     }
}

 

子类

 

Java代码 复制代码  收藏代码
  1. public class Child extends Base {  
  2.        
  3.      public Child() {  
  4.           Behavior beh = new Behavior1();  
  5.           setBehavior(h);  
  6.      }  
  7. }  
public class Child extends Base {
     
     public Child() {
          Behavior beh = new Behavior1();
          setBehavior(h);
     }
}

 

委托接口:

 

Java代码 复制代码  收藏代码
  1. public interface Behavior {  
  2.      public void doIt();  
  3. }  
public interface Behavior {
     public void doIt();
}

 

委托接口实现1

 

Java代码 复制代码  收藏代码
  1. public class Behavior1 implements Behavior {  
  2.      public void doIt() {  
  3.           //具体实现  
  4.      }  
  5. }  
public class Behavior1 implements Behavior {
     public void doIt() {
          //具体实现
     }
}

 

 

android应用实例
google Volley
Volley中的每个网络请求被封装成了一个类,他们共同继承自基类Request,Request的子类有JsonObjectRequest, ImageRequest等。他们都需要一个网络重连的算法。
所以google写了一个这个算法的接口

Java代码 复制代码  收藏代码
  1. /** 
  2.  * Retry policy for a request. 
  3.  */  
  4. public interface RetryPolicy {  
  5.   
  6.     /** 
  7.      * Returns the current timeout (used for logging). 
  8.      */  
  9.     public int getCurrentTimeout();  
  10.   
  11.     /** 
  12.      * Returns the current retry count (used for logging). 
  13.      */  
  14.     public int getCurrentRetryCount();  
  15.   
  16.     /** 
  17.      * Prepares for the next retry by applying a backoff to the timeout. 
  18.      * @param error The error code of the last attempt. 
  19.      * @throws VolleyError In the event that the retry could not be performed (for example if we 
  20.      * ran out of attempts), the passed in error is thrown. 
  21.      */  
  22.     public void retry(VolleyError error) throws VolleyError;  
  23. }  
/**
 * Retry policy for a request.
 */
public interface RetryPolicy {

    /**
     * Returns the current timeout (used for logging).
     */
    public int getCurrentTimeout();

    /**
     * Returns the current retry count (used for logging).
     */
    public int getCurrentRetryCount();

    /**
     * Prepares for the next retry by applying a backoff to the timeout.
     * @param error The error code of the last attempt.
     * @throws VolleyError In the event that the retry could not be performed (for example if we
     * ran out of attempts), the passed in error is thrown.
     */
    public void retry(VolleyError error) throws VolleyError;
}

 它的实现有DefaultRetryPolicy等


这里是个十分标准的策略模式
在Request基类中有一个成员变量
  

Java代码 复制代码  收藏代码
  1. private RetryPolicy mRetryPolicy;  
  private RetryPolicy mRetryPolicy;

 
同时也有一个set方法

 

Java代码 复制代码  收藏代码
  1. /** 
  2.  * Sets the retry policy for this request. 
  3.  * 
  4.  * @return This Request object to allow for chaining. 
  5.  */  
  6. public Request<?> setRetryPolicy(RetryPolicy retryPolicy) {  
  7.     mRetryPolicy = retryPolicy;  
  8.     return this;  
  9. }  
    /**
     * Sets the retry policy for this request.
     *
     * @return This Request object to allow for chaining.
     */
    public Request<?> setRetryPolicy(RetryPolicy retryPolicy) {
        mRetryPolicy = retryPolicy;
        return this;
    }

  然后在初始化Request的时候调用了这个set方法,把适当的重联算法装配进去

Java代码 复制代码  收藏代码
  1. public Request(int method, String url, Response.ErrorListener listener) {  
  2.     mMethod = method;  
  3.     mUrl = url;  
  4.     mErrorListener = listener;  
  5.     setRetryPolicy(new DefaultRetryPolicy());  //这个是基类,因此放了一个默认的方法进去  
  6.   
  7.     mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();  
  8. }  
  9.          
  10.   
  11. public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,  
  12.         Config decodeConfig, Response.ErrorListener errorListener) {  
  13.     super(Method.GET, url, errorListener);  
  14.     setRetryPolicy(  
  15.             new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT)); //这个是子类,为其选择了特殊的重联算法  
  16.     mListener = listener;  
  17.     mDecodeConfig = decodeConfig;  
  18.     mMaxWidth = maxWidth;  
  19.     mMaxHeight = maxHeight;  
  20. }  
    public Request(int method, String url, Response.ErrorListener listener) {
        mMethod = method;
        mUrl = url;
        mErrorListener = listener;
        setRetryPolicy(new DefaultRetryPolicy());  //这个是基类,因此放了一个默认的方法进去

        mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();
    }
           

    public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,
            Config decodeConfig, Response.ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        setRetryPolicy(
                new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT)); //这个是子类,为其选择了特殊的重联算法
        mListener = listener;
        mDecodeConfig = decodeConfig;
        mMaxWidth = maxWidth;
        mMaxHeight = maxHeight;
    }

 

width="468" height="60" src="http://iam42.iteye.com/iframe_ggbd/187" frameborder="0" scrolling="no">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值