设计模式学习之路-简单工厂模式

来源:互联网 发布:电脑word文档软件 编辑:程序博客网 时间:2024/05/22 13:50

设计模式是程序员进阶的必经之路,这也是我的必经之路,也许大家当初为了面试所需都强记过一些设计模式的名字,像单例模式,工厂模式,策略模式,观察者模式,代理模式,适配器模式,命令模式等等。我当初就是知其然不知其所以然,现在决定把设计模式都认真学习一遍,没有代码量是不可能成功的,所以在学习过程中,记录下所有代码。见证成长。

那么先从最简单的工厂模式开始,工厂模式,顾名思义就是生产实例的工厂。也就是在设计层中同一层有过多的相似功能的类,就可以使用工厂类来简化实例。

举个例子(安卓的代码),很简单的一个计算器程序,很多在校大学生或者玩过代码的初高中生都能编出来。

对于该需求,先将业务逻辑和界面逻辑分层。界面逻辑在该需求中并不复杂,所以没必要在细分。

业务逻辑可以继续细分,计算器的逻辑中将可变和不可变的部分进行分层,不可变的共有的放在父类,也就是两个进行计算的参数

图示:


public abstract class Operation {    private double numA;    private double numB;    public double getNumA() {        return numA;    }    public void setNumA(double numA) {        this.numA = numA;    }    public double getNumB() {        return numB;    }    public void setNumB(double numB) {        this.numB = numB;    }    public double getResultMoney(){        return 0;    }}
然后就是对计算父类进行继承,这里分层最主要是考虑用户需求的改变,比如再添一个开方,根号的计算,分层有利于提高代码的可扩展性。

public class OperationAdd extends Operation {    @Override    public double getResultMoney() {        return getNumA()+getNumB();    }}
计算逻辑分层好了之后,就可以在计算具体实现(加减乘除)这个层加一个工厂类,根据需求提供不同实例,用父类的引用来接受,这样可以进一步简化代码。

public class OperationFactory {    public static Operation createOperation(int flag,Context context){        Operation operation = null;        switch (flag){            case 0:                operation = new OperationAdd();                break;            case 1:                operation = new OperationSub();                break;            case 2:                operation = new OperationMul();                break;            case 3:                operation = new OperationDiv(context);                break;        }        return operation;    }}
具体使用就在自定义的控件了。这里的operation使用多态,提高代码的可复用性。

 case R.id.calwait:                        numB = Double.parseDouble(textView.getText().toString());                        stringBuilder.delete(0, stringBuilder.length());                        Operation operation = OperationFactory.createOperation(flag,context);                        operation.setNumA(numA);                        operation.setNumB(numB);                        double result = operation.getResultMoney();                        textView.setText(String.valueOf(result));                        break;
自定义的计算器控件

package com.abings.factorymodel.Calcumater;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.widget.Button;import android.widget.LinearLayout;import android.widget.TextView;import com.abings.factorymodel.Operation.Operation;import com.abings.factorymodel.Operation.OperationFactory;import com.abings.factorymodel.R;/** * Created by Shuwen on 2016/8/24. */public class CalcumateView extends LinearLayout {    private TextView textView;    final StringBuilder stringBuilder = new StringBuilder();    private Context context;    private double numA;    private double numB;    private Button[]btns = new Button[18];    //尽可能的使代码简化    private int[]nums = new int[]{R.id.num0,R.id.num1,R.id.num2,R.id.num3,R.id.num4            ,R.id.num5,R.id.num6,R.id.num7,R.id.num8,R.id.num9,R.id.caladd,R.id.calsub            ,R.id.calmul,R.id.caldiv,R.id.calwait,R.id.clearall,R.id.delete,R.id.numdot};    private int flag = 0;    public CalcumateView(Context context) {        this(context,null);    }    public CalcumateView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public CalcumateView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.context = context;        LayoutInflater.from(context).inflate(R.layout.calculater, this);        initViews();        setEvents();    }    private void setEvents() {        //数字,加减乘除        for (int i = 0; i < nums.length; i++) {            setNumOnclick(btns[i]);        }    }    public void setNumOnclick(final Button button){        button.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                switch (v.getId()){                    case R.id.caladd:                        numA = Double.parseDouble(textView.getText().toString());                        stringBuilder.delete(0,stringBuilder.length());                        flag = 0;                        textView.setText(stringBuilder);                        break;                    case R.id.calsub:                        numA = Double.parseDouble(textView.getText().toString());                        stringBuilder.delete(0,stringBuilder.length());                        flag = 1;                        textView.setText(stringBuilder);                        break;                    case R.id.calmul:                        numA = Double.parseDouble(textView.getText().toString());                        stringBuilder.delete(0,stringBuilder.length());                        flag = 2;                        textView.setText(stringBuilder);                        break;                    case R.id.caldiv:                        numA = Double.parseDouble(textView.getText().toString());                        stringBuilder.delete(0,stringBuilder.length());                        flag = 3;                        textView.setText(stringBuilder);                        break;                    case R.id.calwait:                        numB = Double.parseDouble(textView.getText().toString());                        stringBuilder.delete(0, stringBuilder.length());                        Operation operation = OperationFactory.createOperation(flag,context);                        operation.setNumA(numA);                        operation.setNumB(numB);                        double result = operation.getResultMoney();                        textView.setText(String.valueOf(result));                        break;                    case R.id.clearall:                        stringBuilder.delete(0, stringBuilder.length());                        textView.setText(stringBuilder);                        break;                    case R.id.delete:                        int len = stringBuilder.length() - 1 > 0?stringBuilder.length() - 1:0;                        stringBuilder.delete(len, stringBuilder.length());                        textView.setText(stringBuilder);                        break;                    default:                        stringBuilder.append(button.getText());                        textView.setText(stringBuilder);                        break;                }            }        });    }    private void initViews() {        for (int i = 0;i < nums.length;i++){            btns[i] = (Button) findViewById(nums[i]);        }        textView = (TextView) findViewById(R.id.text);    }}
这篇博客最主要是介绍工厂模式,好了。工厂模式还是相当简单明了易上手。

最后附上项目git:(在新的网页打开)

https://github.com/SingleShu/FactoryModel






1 0
原创粉丝点击