1、定义:
The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from
clients that use it.
定义了一系列的算法(这些算法实现了同样的工作。仅仅是实现不同),它能够已同样的方式调用全部的算法。降低算法类与算法之间的耦合。
2、目的:
将详细的算法抽象出来,把每一个算法独立出来,形成一系列的算法组,这个算法组里面的算法能够依据实际情况进行相互替换。
3、中心:
策略模式的中心,不在于怎样实现算法,而在于怎样组织和调用这些算法,即:解耦合。形成独立模块。增强程序拓展性。
写了一个简单的策略使用
首先,编写一个统一的算法接口
/** * 策略模式 * 统一的算法接口 * @author qubian * @data 2015年6月3日 * @email naibbian@163.com * */ public interface StrategyPattern { /** * 计算注数 */ public int calcLottery(int num); }
其次,编写每一个详细的实现
package com.example.demo; /** * 策略模式 * 详细的方法实现; * 比方说双色球 * @author qubian * @data 2015年6月3日 * @email naibbian@163.com * */ public class StrategyPatternImp_SSQ implements StrategyPattern { @Override public int calcLottery(int num) { return 0; } }
package com.example.demo; /** * 策略模式 * 详细的方法实现; * 比方说大乐透 * @author qubian * @data 2015年6月3日 * @email naibbian@163.com * */ public class StrategyPatternImp_DLT implements StrategyPattern{ @Override public int calcLottery(int num) { return 0; } }
最后是策略的不同调用
package com.example.demo; /** * 详细的使用 * @author qubian * @data 2015年6月3日 * @email naibbian@163.com * */ public class LotteryCount { private StrategyPattern strategyPattern; public enum LotteryEnum { SSQ, DLT, QLC; } public int getLotteryCount(LotteryEnum e,int num) { switch (e) { case SSQ: strategyPattern = new StrategyPatternImp_SSQ(); break; case DLT: strategyPattern = new StrategyPatternImp_DLT(); break; default: break; } return strategyPattern.calcLottery(num); } }
策略模式 在Android Framework 中运用广泛。
比方说,我们常常使用的 BaseAdapter 实际也是策略模式;
我们编写的适配器继承自BaseAdapter,通过getview中实现不同的算法。实现不同的view的返回,
外部使用时也能够依据数据源。切换Adapter,这种使用事实上就是一种策略模式;
Adapter 就是一个最顶层的策略接口
public interface Adapter { /** * How many items are in the data set represented by this Adapter. * * @return Count of items. */ int getCount(); /** * Get the data item associated with the specified position in the data set. * * @param position Position of the item whose data we want within the adapter's * data set. * @return The data at the specified position. */ Object getItem(int position);
/** * Get a View that displays the data at the specified position in the data set. You can either * create a View manually or inflate it from an XML layout file. When the View is inflated, the * parent View (GridView, ListView...) will apply default layout parameters unless you use * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)} * to specify a root view and to prevent attachment to the root. * * @param position The position of the item within the adapter's data set of the item whose view * we want. * @param convertView The old view to reuse, if possible. Note: You should check that this view * is non-null and of an appropriate type before using. If it is not possible to convert * this view to display the correct data, this method can create a new view. * Heterogeneous lists can specify their number of view types, so that this View is * always of the right type (see {@link #getViewTypeCount()} and * {@link #getItemViewType(int)}). * @param parent The parent that this view will eventually be attached to * @return A View corresponding to the data at the specified position. */ View getView(int position, View convertView, ViewGroup parent); static final int IGNORE_ITEM_VIEW_TYPE = AdapterView.ITEM_VIEW_TYPE_IGNORE; int getItemViewType(int position); int getViewTypeCount(); static final int NO_SELECTION = Integer.MIN_VALUE; boolean isEmpty(); }
再到BaseAdapter的抽象
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter { private final DataSetObservable mDataSetObservable = new DataSetObservable(); public boolean hasStableIds() { return false; } /** * Notifies the attached observers that the underlying data has been changed * and any View reflecting the data set should refresh itself. */ public void notifyDataSetChanged() { mDataSetObservable.notifyChanged(); } public View getDropDownView(int position, View convertView, ViewGroup parent) { return getView(position, convertView, parent); } public int getItemViewType(int position) { return 0; } public int getViewTypeCount() { return 1; } public boolean isEmpty() { return getCount() == 0; } }