计算器项目总结(VS , C#)——三层搭建、添加App.config、添加主函数

经过一段时间对面向对象的学习,我借用了三层的思想对我的计算器进行了重构。

搭建三层架构、添加App.config配置文件:

首先新建一个空白的解决方案

然后右键解决方案添加类库,注意命名

这是我建好的类库

类库有了,接下来就要建立他们之间的引用了。展开类库,右键点击引用,点击项目,在要引用的类库前画对勾,确定

谁引用谁呢:我这里是UI引用BLL,BLL引用DAL的一个由外向里的过程的

ok,一个简单的三层到这里就搭好了。如果用实体的话还要添加一个modle,严格来说它不属于三层里的。我这里没那样用。

扫描二维码关注公众号,回复: 8533901 查看本文章

下面就可以把需要用到的类添加到对应的层下边了,如图:

因为是新建的空白解决方案,所以用到的东西都要手动添加。

本项目用到了配置文件:App.config,导入它的方法:右击相应的类库,添加,应用程序配置文件

还要用到程序的主函数,即Program.cs类,没有它程序运行会失败

这个新建一个同名的类,添加如下代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using UI;

namespace 计算器重构
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmCount());//new后边的窗体为你项目的启动窗体名
        }
    }
}

到这里,要用的东西就算齐活儿了。下面就该看具体程序了。

UI设计:

代码部分:

DAL:

加法运算,其他类似

namespace DAL
{
    class AddOperate:Operate
    {
        public override double GetResult()
        {
            return Result += Num;
        }
    }
}

一个算式需要的成分:两个数字,一个运算符号,其中一个数字既作为本次运算的一个输出又作为下一步运算的输入,从而能实现连续运算,算符是用来处理数字的,单独拿了出来放在了上边

namespace DAL
{
    public class Operate
    {
        //参与运算的数字
        private double num;
        public double Num
        {
            get { return num; }
            set { num = value; }
        }
        //result既是这一步的结果又是参与下一步运算的数字
        private double result;
        public double Result
        {
            get { return result; }
            set { result = value; }
        }

        //计算结果
        public virtual double GetResult()
        {
            return result;
        }
    }
}

实例化算符算法的工厂

using System.Configuration;
using System.Reflection;

namespace DAL
{
    public class OperateFactory
    {
        public static Operate CreateOperate(string oper)
        {
            Operate operate = null;

            //读取算法类所在程序集
            string dalName = ConfigurationManager.ConnectionStrings["DAL"].ToString();
            //读取配置文件中的键,以获得算法类的值
            string fullName = ConfigurationManager.AppSettings[oper];
            //将程序集点儿类名拼接成字符串
            string className = dalName + "." + fullName;
            //通过反射实例化出拼接好的字符串点儿出来的类
            Assembly assembly = Assembly.Load(dalName);
            operate = (Operate)assembly.CreateInstance(className);

            return operate;
        }

        #region switch语句。已优化成配置文件加反射形式,使类符合开闭原则,算法可扩展
        //switch (oper)
        //{
        //    case "+":
        //        operate = new AddOperate();
        //        break;
        //    case "-":
        //        operate = new MinusOperate();
        //        break;
        //    case "*":
        //        operate = new MutiplyOperate();
        //        break;
        //    case "/":
        //        operate = new DivideOperate();
        //        break;
        //}
        #endregion
    }
}

BLL:

获取参与运算的数字

        //截取参与运算的数字
        //定义一个算符数组 
        char[] oper = new char[] { '+', '-', '*', '/' };
        private string[] Num()
        {
            //通过算符将字符串中的数字切割出来
            string headSign = _input.Substring(0, 1);
            if (headSign == oper[0].ToString() || headSign == oper[1].ToString())
            {
                _input = 0 + _input;
            }
            string[] num = _input.Split(oper);
            return num;
        }

输入运算元素,返回运算结果,这个方法可以再封装的,我实现了一部分,还没弄好

        //输入计算元素,返回运算结果
        private string GetResult()
        {
            //接收截取字符串的结果
            //避免对方法进行不必要的重复调用
            string[] num = Num();

            //初始化一个运算结果
            double result = Convert.ToDouble(num[0]);

            //初始化第一个数字长度
            int len = 0;

            Operate getResult;
            //进行 n+1 方式的运算
            for (int i = 0; i < num.Length - 1; i++)
            {
                //可再封装

                //获取运算符
                len = len + num[i].Length;
                string m = _input.Substring(0, len + 1 + i);
                string oper = m.Substring(m.Length - 1, 1);

                //通过运算符确定对应的算法
                getResult = OperateFactory.CreateOperate(oper);
                //运算结果赋值进入运算体系
                getResult.Result = result;
                //参与运算的第i个数字赋值进入运算体系
                getResult.Num = Convert.ToDouble(num[i + 1]);
                //得到结果
                result = getResult.GetResult();
            }
            return result.ToString();
        }

处理计算结果并输出

        //处理计算结果并输出
        public string GetResult(string output)
        {
            string result = null;
            try
            {
                if (_input == "")
                {
                    output = "";
                }
                else
                {
                    result = GetResult().ToString();
                }
            }
            catch (Exception)
            {
                result = output;
            }
            return result;
        }

UI:

将输入作为参数传入方法进行处理,并将结果显示

private void txtShow_TextChanged(object sender, EventArgs e)
        {
            lblResult.Text = new Count(txtShow.Text).GetResult(lblResult.Text);
  
        }
发布了233 篇原创文章 · 获赞 22 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41026669/article/details/103754079
今日推荐