1 什么是策略模式的核心
策略(strategy)模式属于对象的行为模式。其用途是针对一组算法,将每个不同算法封装到具有共同接口的独立类中,从而使他们可以相互替换。即使 算法和对象分开来,使得算法可以独立于使用它的客户而变化。
2 策略模式的使用场景
举几个例子
(1)诸葛亮给赵云的三个精囊妙计,在需要的时候分别使用这三条妙计
(2)出行选择交通工具的问题,汽车、自行车、火车、飞机不同方式所需的费用、时间都不同
(3)某个市场人员接到单后的报价策略。报价策略很复杂,可以简单作如下分类:
普通客户小批量,不打折
普通客户大 批量,打9折
老 客户小批量,打8.5折
老 客户大批量,打8折
诸如此类的问题都是策略模式的应用场景!简而言之,就是要做的事情是一样的,只是方法和方式不同从而得到不同的结果!这就是策略模式
3 策略模式的优缺点
(1)优点
a 可以减少if-else的使用频率
b 提供了相关算法的管理办法,使得客户端切换算法极为方便
(2)缺点
a 产生了很多的策略类
b 客户端必须要知道算法之间的区别
4 uml
策略模式的三个元素:
环境:Context也就是真正使用策略模式的地方,或者直接说客户端
抽象角色:这是一个抽象的角色通常是一个借口或者一个抽象类来担任,定义一个方法尤其实现类或子类(统称为具体策略类)具体实现
具体策略类:实现或者继承抽象类,包装相关的具体行为算法
5 简单实现
(1)抽象角色
这里使用的是接口,使用抽象类也是可以的
/**
* Created by hoomsun on 2017/9/11.
*/
public interface Strategy {
String way();
}
(2)具体策略类
这里只写出来了一个,其他的都是一样的
/**
* Created by hoomsun on 2017/9/11.
*/
public class StrategyBike implements Strategy {
@Override
public String way() {
return "自行车";
}
}
(3)客户端
这个就更简单了
public class MainActivity extends AppCompatActivity {
TextView tv;
Strategy strategy;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
strategy = new StrategyBike();
tv = (TextView) findViewById(R.id.tv);
tv.setText("我通过"+strategy.way()+"的方式出行");
}
}
6 实践应用
BannerView给用户提供多种多样的Page切换动画,下面我给出几个核心类的代码
BannerPageTransformer.java相当于抽象角色,但是真正抽象角色是该类内部的接口transformersInterface
/**
* 这是一个总的Transformer
* Created by hoomsun on 2017/9/6.
*/
public class BannerPageTransformer implements ViewPager.PageTransformer {
transformersInterface anInterface;
@Override
public void transformPage(View page, float position) {
//ViewPager页面的切换效果
if (position < -1.0f) {
anInterface.handleInvisiblePage(page, position);
} else if (position < 0f) {
anInterface.handleLeftPage(page, position);
} else if (position < 1.0f) {
anInterface.handleRightPage(page, position);
} else {
anInterface.handleInvisiblePage(page, position);
}
}
interface transformersInterface {
void handleInvisiblePage(View view, float position);
void handleLeftPage(View view, float position);
void handleRightPage(View view, float position);
}
public void setAnInterface(transformersInterface anInterface) {
this.anInterface = anInterface;
}
}
ScalePageTransformer实现了transformersInterface并通过setAnInterface和BannerPageTransformer进行通信,其他的类写法也是一样的
/**
* Created by hoomsun on 2017/9/7.
*/
public class ScalePageTransformer extends BannerPageTransformer implements BannerPageTransformer.transformersInterface {
// 缩放和透明比例,需要自己修改想要的比例
private float scaleMin = 0.8f;
public ScalePageTransformer() {
initListener();
}
private void initListener() {
setAnInterface(this);
}
@Override
public void handleInvisiblePage(View view, float position) {
}
@Override
public void handleLeftPage(View view, float position) {
ViewCompat.setScaleX(view, (1 - scaleMin) * position + 1);
ViewCompat.setScaleY(view, (1 - scaleMin) * position + 1);
}
@Override
public void handleRightPage(View view, float position) {
ViewCompat.setScaleX(view, (scaleMin - 1) * position + 1);
ViewCompat.setScaleY(view, (scaleMin - 1) * position + 1);
}
}
怎么用切换策略?如何设置Page的切换模式呢?
mViewPager.setPageTransformer(false, TransformerSwitch.bannerPageTransformer(transitionEffect));
TransformerSwitch.java代码如下:
/**
* Created by hoomsun on 2017/9/7.
*/
public class TransformerSwitch {
public static BannerPageTransformer bannerPageTransformer(TransformerType type) {
switch (type) {
default:
return new DefaultPageTransformer();
case Alpha: {
return new AlphaPageTranformer();
}
case Default: {
return new DefaultPageTransformer();
}
case Scale: {
return new ScalePageTransformer();
}
}
}
}
demo
https://github.com/grr1314/ViewPagerDemo
7 认清策略模式
(1)策略模式的重点是什么?
策略模式有两个大块,一个是算法实现另外就是算法的组织协调,看似算法的实现很重要但是组织协调才是策略模式的真正的重点
(2)算法的平等性
这点最好理解了,策略模式中所有的算法都是平等的,也正因如此策略模式才可以随意切换算法
(3)运行时策略的唯一性
在运行时只能使用一个算法
(4)公有的行为
经常见到的是,所有的具体策略类都有一些公有的行为。这时候,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。当然
这时候抽象策略角色必须要用Java抽象类实现,而不能使用接口。这其实也是典型的将代码向继承等级结构的上方集中的标准做法。
8 参考文章
http://blog.csdn.net/hguisu/article/details/7558249/
http://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html