本文共 5559 字,大约阅读时间需要 18 分钟。
工厂模式很简单,也很好上手,那么接下来学习策略模式,我们就以商场的收银系统作为需求,使用策略模式完成。达到学习了解策略模式的目的。
策略模式(strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
先看看策略模式的结构图:
通过Context的实例去调用不同具体实例的方法。那么根据策略模式的结构图,商场收银系统的UML
商场的收银算法多种多样,并且可能随时更改,那么在设计该系统时,模式选择上就应该注重系统的可扩展性,可维护性。那么我们就以商场有现金全额收费算法,打折算法,满返现算法。当然上诉分层结构时,在具体策略层可以加个工厂,这样可以提高代码的可复用性。
先从上到下,抽象算法
/** *抽象策略,一个算法 *@author Shuwen *created at 2016/8/25 15:54 */public abstract class CashSuper { public abstract double CashMoney(double money); public abstract String getType();}接着是具体策略
/** * Created by Shuwen on 2016/8/25. */public class CashDebate extends CashSuper { private double debate = 1; public CashDebate(double debate){ this.debate = debate; } @Override public double CashMoney(double money) { return money*debate; } @Override public String getType() { return "打"+debate+"折"; }}接着就是业务逻辑,整个银行系统,把它抽出来设计为一个自定义的View,这样可以增强代码的复用性,在其他地方要用,直接就可以用这个控件,而不用再去重复写业务逻辑。
package com.abings.strategymodel;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.Spinner;import android.widget.TextView;import com.abings.strategymodel.Strategy.CashContext;import com.abings.strategymodel.StrategyFactory.CashFactory;/** * Created by Shuwen on 2016/8/25. */public class BankSysView extends LinearLayout { private EditText singlemoney; private EditText number; private Button sure; private Button reset; private TextView history; private TextView total; private StringBuilder stringBuilder; private Context context; private Spinner spinner; private ArrayAdapter最后根据需求,写个工厂类adapter; private CashContext cashContext; private double totalMoney; private double allMoney; private String[]types = {"全额付款","打8折","打5折","满300返50"}; public BankSysView(Context context) { this(context,null); } public BankSysView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public BankSysView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context =context; LayoutInflater.from(context).inflate(R.layout.cashmoneysys, this); initView(); setEvents(); } private void setEvents() { spinner.setAdapter(adapter); spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { cashContext = CashFactory.createCashSuper(position); } @Override public void onNothingSelected(AdapterView parent) { } }); sure.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { double singleMoney = Double.parseDouble(singlemoney.getText().toString().trim()); double numBer = Double.parseDouble(number.getText().toString().trim()); totalMoney = cashContext.getResult(singleMoney * numBer); allMoney += totalMoney; stringBuilder.append("单价:"+singleMoney+"元,"+"数量:"+(int)numBer+","+cashContext.getType()+",合计:"+totalMoney+"元\n"); total.setText("总计:" + allMoney + "元"); history.setText(stringBuilder); } }); reset.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { singlemoney.setText(""); number.setText(""); allMoney = 0; stringBuilder.delete(0, stringBuilder.length()); history.setText(""); total.setText("总计:"); } }); } private void initView() { singlemoney = (EditText) findViewById(R.id.singlemoney); number = (EditText) findViewById(R.id.num); sure = (Button) findViewById(R.id.sure); reset = (Button) findViewById(R.id.reset); history = (TextView) findViewById(R.id.history); total = (TextView) findViewById(R.id.total); spinner = (Spinner) findViewById(R.id.spinner); adapter = new ArrayAdapter<>(context,R.layout.text,types); stringBuilder = new StringBuilder(); }}
package com.abings.strategymodel.StrategyFactory;import com.abings.strategymodel.Strategy.CashContext;import com.abings.strategymodel.Strategy.CashDebate;import com.abings.strategymodel.Strategy.CashNormal;import com.abings.strategymodel.Strategy.CashReturn;/** * Created by Shuwen on 2016/8/26. */public class CashFactory { public static CashContext createCashSuper(int position){ CashContext cashContext = null; switch (position) { case 0: cashContext = new CashContext(new CashNormal()); break; case 1: cashContext = new CashContext(new CashDebate(0.8)); break; case 2: cashContext = new CashContext(new CashDebate(0.5)); break; case 3: cashContext = new CashContext(new CashReturn(300, 50)); break; } return cashContext; }}这就是策略模式,一个抽象策略,多个具体策略,一个Context统一算法的调用,那么以后再添加算法,或是修改算法,只需要在具体算法层做改动,客户端和抽象策略不需要修改,这样代码的可维护性,可扩张性也提高了不少。很不错的设计模式。
附上git源码:
(若跳转失败,在新开个页面,复制上面链接)