设计模式之----策略模式(ListAdapter和TimeInterpolator源码分析)
来源:互联网 发布:如何优化listing 编辑:程序博客网 时间:2024/05/16 08:06
一、定义
策略模式定义了一系列算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式让算法独立于使它的客户独立而变化。
策略模式的重点不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
二、角色
2.1 环境(Context)角色
该角色持有一个Stragtegy的引用,可以执行Stragtegy的方法
2.2 抽象策略(Stragtegy)角色
这是一个抽象角色,通常由一个接口或者抽象类实现,此角色给出所有的具体策略角色共同的接口,部分不需要子类实现的部分可在该角色中实现。
2.3 具体策略(ConcreteStragtegy)角色
包装了相关的算法或者行为。
三、需求
假设现在要一个上商店个搞活动。 对所有的高级会员打20%的促销折扣;对中级会员打10%的促销折扣;对初级会员没有折扣。
得知算法:
- 算法一:对初级会员没有折扣。
- 算法二:对中级会员提供10%的促销折扣。
- 算法三:对高级会员提供20%的促销折扣。
四、代码实现
4.1 抽象策略角色实现
/** * 抽象策略角色,定义接口 * * Created by rytong on 2017/11/2. */public interface Stragtegy { /** * 获取真实价格 * * @param price * @return */ public double getPrice(double price);}
4.2 具体策略角色实现
/** * 普通策略角色:高级会员打8折 * * Created by rytong on 2017/11/2. */public class Stragtegy3 implements Stragtegy { @Override public double getPrice(double price) { return price*0.8; }}
4.3 上下文角色实现
/** * 上下文角色,持有Stragtegy角色 * * Created by rytong on 2017/11/2. */public class StragtegyContext { //具体的策略角色 Stragtegy mStragtegy; public StragtegyContext(Stragtegy mStragtegy) { this.mStragtegy = mStragtegy; } /** * 计算实际价格 * @param price * @return */ public double calcutatePrice(double price){ return mStragtegy.getPrice(price); }}
4.4 客户端调用
//高级会员Stragtegy stragtegy3 = new Stragtegy3();StragtegyContext stragtegyContext = new StragtegyContext(stragtegy3);Log.e(TAG,"高级会员打折后的价格:"+stragtegyContext.calcutatePrice(1000));// 改为中级会员stragtegyContext = new StragtegyContext(new Stragtegy2());Log.e(TAG,"中级会员打折后的价格:"+stragtegyContext.calcutatePrice(1000));
执行结果:
11-02 15:57:12.958 1812-1812/? E/MainActivity: 高级会员打折后的价格:800.011-02 15:57:12.959 1812-1812/? E/MainActivity: 中级会员打折后的价格:900.0
五、安卓中的策略模式
5.1 ListView的Adapter
5.1.1 客户端调用
给每个listView设置adapter的时候需要继承BaseAdapter,并重写各方法来完成,这个地方可以替换为任何的
ListAdapter
接口的子类都可以。
ListView listView = new ListView(this);listView.setAdapter(new BaseAdapter() { @Override public int getCount() { return 0; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { return null; }});
5.1.2 源码查看
从调用点查看:在AbsListView中声明一个ListAdapter,在调用setAdapter的时候赋值。ListAdapter就是抽象策略角色,我们实现的Adapter就是具体策略角色。ListView就是上下文角色。
public void setAdapter(ListAdapter adapter) {if (mAdapter != null && mDataSetObserver != null) { mAdapter.unregisterDataSetObserver(mDataSetObserver);}resetList();mRecycler.clear();if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) { mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, adapter);} else { mAdapter = adapter;}...}
mAdapter的使用:有很多地方都有,找一个简单的
public boolean removeHeaderView(View v) {if (mHeaderViewInfos.size() > 0) { boolean result = false; if (mAdapter != null && ((HeaderViewListAdapter) mAdapter).removeHeader(v)) { if (mDataSetObserver != null) { mDataSetObserver.onChanged(); } result = true; } removeFixedViewInfo(v, mHeaderViewInfos); return result;}return false;}
5.2 插值器
5.2.1 客户端调用
在客户端调用的时候指定插值器的类型,来指定动画的类型。这里ObjectAnimator类就是上下文角色,LinearInterpolator是具体策略角色,TimeInterpolator是抽象策略角色。
TextView textView = new TextView(this);ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView, View.SCALE_X, 0f, 1f);objectAnimator.setDuration(2000);objectAnimator.setRepeatMode(ValueAnimator.RESTART);objectAnimator.setRepeatCount(-1);//插值器objectAnimator.setInterpolator(new LinearInterpolator());objectAnimator.start();
5.2.2 源码简单查看
public void setInterpolator(TimeInterpolator value) { if (value != null) { mInterpolator = value; } else { mInterpolator = new LinearInterpolator(); }}
六、总结
6.1 优点
- 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或者行为族。恰当的继承可以把公共的代码移到父类里面,从而避免代码重复。
- 使用策略模式可以避免使用多重if-else类语句。把每个分支封装为一种行为单独封装。
6.2 缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便选择恰当的算法使用。换言之,策略模式只适用于客户端知道算法或者行为的情况。
- 由于策略模式把每一个具体的策略封装成了类,所以类文件数量会比较可观。
6.3 特点
- 运行时策略唯一性:在运行时只能有一个生效。
- 平等性:在调用的地方可以使用任意一个具体的策略。他们之间是相互独立,没有依赖的。
6.3 使用场景
- 多个类只区别在表现行为不同,可以使用Stragtgy模式,在运行时动态选择具体要执行的行为
- 需要在不同的情况下使用不同的策略(算法、行为),或者策略还可能在未来用其他方式来实现(容易扩展)
- 对客户隐藏具体策略的算法实现细节,彼此完全独立。
阅读全文
0 0
- 设计模式之----策略模式(ListAdapter和TimeInterpolator源码分析)
- 设计模式之策略模式简要分析
- 设计模式之----建造者模式(AlertDialog源码分析)
- 【设计模式】之策略模式(Strategy)
- 设计模式之--策略模式(Strategy)
- 设计模式之策略(strategy)模式
- 设计模式之策略模式(Strategy)
- 设计模式之策略模式(java)
- 设计模式之策略模式(一)
- 设计模式之策略模式(转)
- 设计模式(一)之策略模式
- 设计模式之策略模式(笔记)
- 设计模式之策略模式(Strategy)
- 设计模式之:策略模式(strategy)
- 设计模式之策略(Strategy)模式
- 设计模式之策略模式(java)
- 设计模式之策略模式(strategy)
- 设计模式之策略模式(STRATEGY)
- Executor多线程框架
- mybatis 拦截器获取sql语句
- 约瑟夫环问题
- Dubbo简单demo
- 【LeetCode解答五】Palindrome Number问题Java解答
- 设计模式之----策略模式(ListAdapter和TimeInterpolator源码分析)
- Leetcode-Remove Duplicates from Sorted List II(二级指针)
- linux下的文件和目录的特殊权限
- Spring框架中ModelAndView、Model、ModelMap区别
- HttpClient模拟浏览器登录后发起请求(携带Cookie发请求)
- mysql 中 unix_timestamp和from_unixtime 时间戳函数
- ONVIF Server端鉴权 (无OPENSSL)
- 物联网通信方式介绍
- Rxjava Demo