策略模式的简单使用

21 篇文章 0 订阅
19 篇文章 0 订阅

前言

最近上班基本都没写java(Android)代码了,这段时间被系统研发部借去开发PHP网站,下班回家抽点时间可以整理一下关于java的设计模式,当然这也适用于Android。今天要整理的事策略模式。在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能;很常见的就是排序算法,我们完成一个排序可以通过很多算法,但是到头来都是完成一项工作,因为考虑到算法的效率,所以使用的时候就得按需使用,当然完全可以写一个排序的管理类,然后统一的在这个类里面书写出所以得排序算法,但是这样做导致的问题是维护成本增加,当你更改一个算法的时候,难免会遇到多个算法公用代码块的情况,这样的改动势必影响到别的算法,产生不必要的麻烦。策略模式要解决的问题是将算法和对象分开。

策略模式的角色扮演

Context: 用一个ConcreteStrategy对象来配置,维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据,换一句话就是用来操作策略的上下文环境。
Strategy: 定义所有支持的算法的公共接口,也就是策略的抽象类。
ConcreteStrategy:具体的策略实现类。

适用环境

1,适用于仅仅是行为有异的相关类。
2,隐藏算法的数据和具体实现,只让你知道算法的结果。
3,一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

Demo

策略模式通俗来说就是我要干一件事,但是完成这个结果有多种途径,我们要这个事情抽象出来,形成Strategy抽象接口,而具体有多少途径,就对应多少实现这个接口的ConcreteStrategy类,那么Context就是具体的用户想要怎么来实现了。
距离春节回家也快了,就举一个简单的回家的例子,抽象模型是这样的:我们今年要回家,回家有三种方式可选,汽车、火车和飞机,我们优先选择火车,如果没有火车票那就飞机,如果再不行我们就汽车回家。

抽象接口

package com.demo.stragety;

/**
 * Created by italkbb on 2017/12/17.
 */

public interface IGoHomeStragety {
    void trafficTool();
}

接口定义了一个回家的接口,那么我们的三种途径对应三个实现类:

package com.demo.stragety;

import android.util.Log;

/**
 * Created by italkbb on 2017/12/17.
 */

public class TrainGoHomeStragety implements IGoHomeStragety {
    // 类名,用于日志区分
    public final static String CLASSNAME = TrainGoHomeStragety.class.getSimpleName();
    @Override
    public void trafficTool() {
        Log.e(CLASSNAME,"今年我坐火车回家");
    }
}
package com.demo.stragety;

import android.util.Log;

/**
 * Created by italkbb on 2017/12/17.
 */

public class AirGoHomeStragety implements IGoHomeStragety {
    // 类名,用于日志区分
    public final static String CLASSNAME = AirGoHomeStragety.class.getSimpleName();
    @Override
    public void trafficTool() {
        Log.e(CLASSNAME,"今年我坐飞机回家");
    }
}
package com.demo.stragety;

import android.util.Log;

/**
 * Created by italkbb on 2017/12/17.
 */

public class BusGoHomeStragety implements IGoHomeStragety {
    // 类名,用于日志区分
    public final static String CLASSNAME = BusGoHomeStragety.class.getSimpleName();
    @Override
    public void trafficTool() {
        Log.e(CLASSNAME,"今年我坐汽车回家");
    }
}

这就是ConcreteStrategy类,下面Context来决定要怎么回去,相当于我们的路子都明确了,要做决策了:

package com.demo.stragety;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.example.daybreak.helloword.R;


public class StragetyActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_stragety);
        StragetySelectManager mStragetySelectManager = new StragetySelectManager();
        // 这里省略具体获取方法的步骤,其实就是去查有没有票,返回一下什么途径有票罢了
        String goHomeMethon = "";
        switch (goHomeMethon){
            case "train":
                // 小明今年想坐火车回家
                mStragetySelectManager.setGoHomeStragety(new TrainGoHomeStragety());
                break;

            case "bus":
                // 小明坐汽车
                mStragetySelectManager.setGoHomeStragety(new BusGoHomeStragety());
                break;

            case "air":
                // 小明今年想坐飞机回家
                mStragetySelectManager.setGoHomeStragety(new AirGoHomeStragety());
                break;

            default:
                // 小明今年想坐飞机回家
                mStragetySelectManager.setGoHomeStragety(new AirGoHomeStragety());
                break;
        }
        // 回家咯
        mStragetySelectManager.getGoHomeStragety();

    }
}

后记

Android源码里也不乏策略模式的身影,我笔记里就记录一下简单的使用,如果有需要可以多看看源码。策略模式的使用场景大多就是实现一个功能可以有很多途径,我们应该按需使用,达到最优使用相关算法。好处当然是减少了if-else语句,提炼出了公用的方法,有益于按需继承,或者说是减低了耦合度。缺点就是类的数量难免会有所增加,而且使用的时候的知道有些什么策略类,再按需使用,再者无论各个ConcreteStrategy实现的算法是简单还是复杂, 它们都共享Strategy定义的接口。因此很可能某些ConcreteStrategy不会都用到所有通过这个接口传递给它们的信息,导致了数据传输的多余开销。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值