Android設計模式(二)--策略模式

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 [email protected]
 *
 */
public interface StrategyPattern {
	
	/**
	 * 計算注數
	 */
	public int calcLottery(int num);

}

其次,編寫每個具體的實現


package com.example.demo;
/**
 * 策略模式
 * 具體的方法實現;
 * 比如說雙色球
 * @author qubian
 * @data 2015年6月3日
 * @email [email protected]
 *
 */
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 [email protected]
 *
 */
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 [email protected]
 *
 */
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;
    }
}








發佈了108 篇原創文章 · 獲贊 22 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章