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

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

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

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

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

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

图示:


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






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值