• C# .NET 逻辑层的框架设计


      前述:在我的了解中,一个大项目的逻辑层是不可捉摸的,对于不同项目或场景都是不同的逻辑。先说明,我的想法是对逻辑层类结构,以及如何操作逻辑的方法进行抽象的封装。并且考虑将不同类,或者不同程序集中的逻辑方法,全都可以归于一个类中控制和使用,并使用链式将它完成。是不是听起来很不可思议。

      之所以这样思考封装,首先是考虑到类间解耦:像很多解耦的框架,虽然能够起到解耦作用,但我觉得它只是降低类间的调用,但是也没有真正意义上的解耦,因为操作方法还是需要UI层中。

      比如:一个支付功能。

      在我之前做的项目中它需要经过这么多步骤(细分会更多):

        1、判断有没有登录

        2、用户选择收获地址

        3、判断商品是否充足

        4、判断余额是否充足

        5、更新数据

      在我之前做项目时候,因为赶时间所以没什么讲究,毕竟在学校只要能够执行成功就行,所以如果调用类,就会在里面new一大堆的bll类。这样,就使得UI层很累赘,并且需要一个一个调用他们的方法,判断一大堆,然后并且还需要对每一个判断,如果失败,还得提示失败给用户。这样UI层显得很累赘,这就是要思考我对我框架思考的主要原因。我觉得在框架中,并没有真正的做到解耦,是因为下面还需要用到方法,这样就使得方法直接在UI中操作。

      我认为,一个逻辑层的框架,不仅要对类间解耦,更重要的应该是如何控制逻辑操作,每个方法只实现一个功能,在UI层对它进行组装,并且组装时候,使用者不需要知道每个逻辑的结果,只需要知道整体返回的结果,根据这个结果来判断操作结果;除了类似支付这样判断的方法,逻辑层大部分还在查询数据的,因此,框架类中还提供能够支撑逻辑层返回数据的方法;最后,因为现在还有部分功能是写在特性上,比如权限控制等,为了开发者的便利,写逻辑的程序员应该只需要考虑怎么实现一个逻辑功能,而逻辑功能放在哪里用,需要框架来定义。

      好了,说了自己的看法,来看下框架的使用方式:例如,支付功能。

      支付功能中,判断用户是否登录在MethodTest类中的Login方法,只是简单的判断;支付功能又在另一个类中,MethodTest,对用户的余额判断,看下框架是如何使用:

    复制代码
        public class Admin
        {
            public string ID
            {
                get;
                set;
            }
            public int Count
            {
                get;
                set;
            }
            public string Pwd
            {
                get;
                set;
            }
        }
    
    public class MethodTest
        {
            public bool Login(Admin admin)
            {
                if (admin.ID == "admin" && admin.Pwd == "123456")
                    return true;
                else
                    return false;
            }
        }
    
    public class MethodTest1
        {
            public bool Pay(Admin admin)
            {
                if (admin.Count > 100)
                    return true;
                else
                    return false;
            }
        }
    复制代码

    下面是实例方法:

    复制代码
    static void Main(string[] args)
            {
                IComMethod method = BllHelper.getMethod<TMethod>();
    
                method.setInstance<MethodTest>();
                method.setInstance<MethodTest1>();
    
                Admin admin = new Admin()
                {
                    ID = "admin",
                    Pwd = "123456",
                    Count = 200
                };
    
                Msg result = method.GMethod<MethodTest>((test, me, msg) =>
                {
                    msg.setFailMsg("登录失败");
                    msg.setSuccessMsg("登录成功");
                    return test.Login(admin);
                })
                .GMethod<MethodTest1>((test, me, msg) =>
                {
                    msg.setSuccessMsg("支付成功");
                    msg.setFailMsg("支付失败");
                    return test.Pay(admin);
                }).getResult();
                
                if(result.State)
                {
                    Console.WriteLine(result.getSuccessMsg());
                }else
                {
                    Console.WriteLine(result.getFailMsg());
                }
            }
    复制代码

    没有了new实例,原来如果一个判断应该给用户一个提示,使用链式控制,在最后获得的result里面就存放着操作是否成功的信息。

    当用户名或者密码错误时候,它运行是这样的:

    下面支付功能就不会执行。

    如果账号密码正确,而账户余额不足时候,运行结果:

    只有当账户跟余额充足下,才能执行成功,而在中间,都不要额外的判断,也没有创建实例,就能够轻松的把逻辑功能联系起来。

    当然,框架里还有别的功能,比如带参数的构造,特性过滤器,以及使用者来创建对象,都可以利用这个框架;整个框架最主要的功能还是类似上边的,链式组合,并且在框架中提供了两种不同的形式:第一种像上边支付功能,上下是有联系的,第二种是上下无关的,也就是上边操作跟下边操作没有影响。这样看我设计的框架,是不是十分的灵活,并且把所有原来在UI处理的事情,都可以放在Bll层中解决,解决了逻辑层与UI层间的耦合,而且,还可以分开的设计逻辑方法,放在Bll中,而不需要对每个方法进行考虑要如何使用组合。

    那么接下来就分析下这个框架的设计思路:

      框架最主要有创建对象类(CreateInstance)、组合功能类(IComMethod 和实现该接口的TMethod、DMethod)、过滤器特性类(FilterAttribute)、帮助类(BllHelper),额外的类就不写里面了。

    CreateInstance就是用来创建对象,比较简单。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Bll
    {
        class CreateInstance
        {
            public static TClass createInstance<TClass>()
                where TClass : class,new()
            {
                return new TClass();
            }
    
            public static TClass createInstance<TClass>(object[] args)
                where TClass : class
            {
                Type type = typeof(TClass);
                TClass c = null;
                c = Activator.CreateInstance(type, args) as TClass;
                return c;
            }
    
            public static TBaseClass createInstance<TBaseClass, TSubClass>()
                where TSubClass : class,new()
                where TBaseClass : class
            {
                return new TSubClass() as TBaseClass;
            }
    
            public static TBaseClass createInstance<TBaseClass, TSubClass>(object[] args)
                where TBaseClass : class
                where TSubClass : class
            {
                Type type = typeof(TSubClass);
                TBaseClass c = null;
                c = Activator.CreateInstance(type, args) as TBaseClass;
                return c;
            }
        }
    }
    复制代码

    最主要的是组合功能的类,在使用的时候,这里面才存放着实例后的对象,并以委托的形式,暴露给外部使用。里面包含有将要使用的类实例化到这个对象内,其实是要使用这些对象的Method方法;考虑到有些方法可能只用一次,所以下边还封装了只使用一次的对应Method方法。TMethod 和 DMethod就是实现接口,他们的区别就是一个上边跟下边执行时有联系的,另一个是无关联的。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Bll
    {
        public interface IComMethod
        {
            IComMethod setInstance<TClass>()
                where TClass : class,new();
            IComMethod setInstance<TClass>(object[] args)
                where TClass : class;
            IComMethod setInstance<TBaseClass, TSubClass>()
                where TSubClass : class,new()
                where TBaseClass : class;
            IComMethod setInstance<TBaseClass, TSubClass>(object[] args)
                where TSubClass : class
                where TBaseClass : class;
    
            IComMethod GMethod<TClass>(Func<TClass, IComMethod, IMsg, bool> fun)
                where TClass : class;
    
            TResult GMethod<TClass, TResult>(Func<TClass, IComMethod, IMsg, TResult> fun)
                where TClass : class;
    
            IComMethod Method<TClass>(Func<TClass, IComMethod, IMsg, bool> fun)
                where TClass : class,new();
            IComMethod Method<TClass>(object[] args, Func<TClass, IComMethod, IMsg, bool> fun)
                where TClass : class;
            IComMethod Method<TBaseClass, TSubClass>(Func<TBaseClass, IComMethod, IMsg, bool> fun)
                where TBaseClass : class
                where TSubClass : class,new();
            IComMethod Method<TBaseClass, TSubClass>(object[] args, Func<TBaseClass, IComMethod, IMsg, bool> fun)
                where TBaseClass : class
                where TSubClass : class;
            TResult Method<TClass, TResult>(Func<TClass, IComMethod, IMsg, TResult> fun)
                where TClass : class,new();
            TResult Method<TClass, TResult>(object[] args, Func<TClass, IComMethod, IMsg, TResult> fun)
                where TClass : class;
            TResult Method<TBaseClass, TSubClass, TResult>(Func<TBaseClass, IComMethod, IMsg, TResult> fun)
                where TBaseClass : class
                where TSubClass : class,new();
            TResult Method<TBaseClass, TSubClass, TResult>(object[] args, Func<TBaseClass, IComMethod, IMsg, TResult> fun)
                where TBaseClass : class
                where TSubClass : class;
    
            Msg getResult();
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Bll
    {
        public class DMethod:IComMethod
        {
            private Dictionary<string, object> bllmodule = new Dictionary<string, object>();
            private List<Msg> msglist = new List<Msg>();
            private int top = -1;
            public IComMethod setInstance<TClass>() where TClass : class, new()
            {
                Type t = typeof(TClass);
                TClass c = CreateInstance.createInstance<TClass>();
                bllmodule.Add(t.Name, c);
                return this;
            }
    
            public IComMethod setInstance<TClass>(object[] args) where TClass : class
            {
                Type t = typeof(TClass);
                TClass c = CreateInstance.createInstance<TClass>(args);
                bllmodule.Add(t.Name, c);
                return this;
            }
    
            public IComMethod setInstance<TBaseClass, TSubClass>()
                where TBaseClass : class
                where TSubClass : class, new()
            {
                Type t = typeof(TBaseClass);
                Type t1 = typeof(TSubClass);
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>();
                bllmodule.Add(t.Name + "." + t1.Name, c);
                return this;
            }
    
            public IComMethod setInstance<TBaseClass, TSubClass>(object[] args)
                where TBaseClass : class
                where TSubClass : class
            {
                Type t = typeof(TBaseClass);
                Type t1 = typeof(TSubClass);
                if (bllmodule.ContainsKey(t.Name + "." + t1.Name))
                    return this;
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>(args);
                bllmodule.Add(t.Name + "." + t1.Name, c);
                return this;
            }
    
            public IComMethod GMethod<TClass>(Func<TClass, IComMethod, IMsg, bool> fun) where TClass : class
            {
                Type t = typeof(TClass);
                if (!bllmodule.ContainsKey(t.Name))
                    return this;
                TClass c = bllmodule[t.Name] as TClass;
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public TResult GMethod<TClass, TResult>(Func<TClass, IComMethod, IMsg, TResult> fun) where TClass : class
            {
                Type t = typeof(TClass);
                if (!bllmodule.ContainsKey(t.Name))
                    return default(TResult);
                TClass c = bllmodule[t.Name] as TClass;
                return getResult(c, fun);
            }
    
            public IComMethod Method<TClass>(Func<TClass, IComMethod, IMsg, bool> fun) where TClass : class, new()
            {
                TClass c = CreateInstance.createInstance<TClass>();
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public IComMethod Method<TClass>(object[] args, Func<TClass, IComMethod, IMsg, bool> fun) where TClass : class
            {
                TClass c = CreateInstance.createInstance<TClass>(args);
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public IComMethod Method<TBaseClass, TSubClass>(Func<TBaseClass, IComMethod, IMsg, bool> fun)
                where TBaseClass : class
                where TSubClass : class,new()
            {
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>();
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public IComMethod Method<TBaseClass, TSubClass>(object[] args, Func<TBaseClass, IComMethod, IMsg, bool> fun)
                where TBaseClass : class
                where TSubClass : class
            {
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>(args);
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public TResult Method<TClass, TResult>(Func<TClass, IComMethod, IMsg, TResult> fun) where TClass : class, new()
            {
                TClass c = CreateInstance.createInstance<TClass>();
                return getResult(c, fun);
            }
    
            public TResult Method<TClass, TResult>(object[] args, Func<TClass, IComMethod, IMsg, TResult> fun) where TClass : class
            {
                TClass c = CreateInstance.createInstance<TClass>(args);
                return getResult(c, fun);
            }
    
            public TResult Method<TBaseClass, TSubClass, TResult>(Func<TBaseClass, IComMethod, IMsg, TResult> fun)
                where TBaseClass : class
                where TSubClass : class,new()
            {
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>();
    
                return getResult(c, fun);
            }
    
            public TResult Method<TBaseClass, TSubClass, TResult>(object[] args, Func<TBaseClass, IComMethod, IMsg, TResult> fun)
                where TBaseClass : class
                where TSubClass : class
            {
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>(args);
    
                return getResult(c, fun);
            }
    
            TResult getResult<TClass, TResult>(TClass c, Func<TClass, IComMethod, IMsg, TResult> fun)
            {
                Msg msg = new Msg();
                TResult result = fun(c, this, msg);
                if (result != null)
                    msg.State = true;
                msglist.Add(msg);
                top++;
                return result;
            }
    
            public Msg getResult()
            {
                return this.msglist[top];
            }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Bll
    {
        public class TMethod : IComMethod
        {
            private Dictionary<string, object> bllmodule = new Dictionary<string, object>();
            private List<Msg> msglist = new List<Msg>();
            private int top = -1;
            public IComMethod setInstance<TClass>() where TClass : class, new()
            {
                Type t = typeof(TClass);
                TClass c = CreateInstance.createInstance<TClass>();
                bllmodule.Add(t.Name, c);
                return this;
            }
    
            public IComMethod setInstance<TClass>(object[] args) where TClass : class
            {
                Type t = typeof(TClass);
                TClass c = CreateInstance.createInstance<TClass>(args);
                bllmodule.Add(t.Name, c);
                return this;
            }
    
            public IComMethod setInstance<TBaseClass, TSubClass>()
                where TBaseClass : class
                where TSubClass : class, new()
            {
                Type t = typeof(TBaseClass);
                Type t1 = typeof(TSubClass);
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>();
                bllmodule.Add(t.Name + "." + t1.Name, c);
                return this;
            }
    
            public IComMethod setInstance<TBaseClass, TSubClass>(object[] args)
                where TBaseClass : class
                where TSubClass : class
            {
                Type t = typeof(TBaseClass);
                Type t1 = typeof(TSubClass);
                if (bllmodule.ContainsKey(t.Name + "." + t1.Name))
                    return this;
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>(args);
                bllmodule.Add(t.Name + "." + t1.Name, c);
                return this;
            }
    
            public IComMethod GMethod<TClass>(Func<TClass, IComMethod, IMsg, bool> fun) where TClass : class
            {
                if (top != -1 && msglist[top].State == false)
                    return this;
                Type t = typeof(TClass);
                if (!bllmodule.ContainsKey(t.Name))
                    return this;
                TClass c = bllmodule[t.Name] as TClass;
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public TResult GMethod<TClass, TResult>(Func<TClass, IComMethod, IMsg, TResult> fun) where TClass : class
            {
                if (top != -1 && msglist[top].State == false)
                    return default(TResult);
                Type t = typeof(TClass);
                if (!bllmodule.ContainsKey(t.Name))
                    return default(TResult);
                TClass c = bllmodule[t.Name] as TClass;
                return getResult(c, fun);
            }
    
            public IComMethod Method<TClass>(Func<TClass, IComMethod, IMsg, bool> fun) where TClass : class, new()
            {
                if (top != -1 && msglist[top].State == false)
                    return this;
                TClass c = CreateInstance.createInstance<TClass>();
                Msg msg = new Msg();
                msg.State = fun(c,this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public IComMethod Method<TClass>(object[] args, Func<TClass, IComMethod, IMsg, bool> fun) where TClass : class
            {
                if (top != -1 && msglist[top].State == false)
                    return this;
                TClass c = CreateInstance.createInstance<TClass>(args);
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public IComMethod Method<TBaseClass, TSubClass>(Func<TBaseClass, IComMethod, IMsg, bool> fun)
                where TBaseClass : class
                where TSubClass : class,new()
            {
                if (top != -1 && msglist[top].State == false)
                    return this;
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>();
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public IComMethod Method<TBaseClass, TSubClass>(object[] args, Func<TBaseClass, IComMethod, IMsg, bool> fun)
                where TBaseClass : class
                where TSubClass : class
            {
                if (top != -1 && msglist[top].State == false)
                    return this;
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>(args);
                Msg msg = new Msg();
                msg.State = fun(c, this, msg);
                msglist.Add(msg);
                top++;
                return this;
            }
    
            public TResult Method<TClass, TResult>(Func<TClass, IComMethod, IMsg, TResult> fun) where TClass : class, new()
            {
                if (top != -1 && msglist[top].State == false)
                    return default(TResult);
                TClass c = CreateInstance.createInstance<TClass>();
                return getResult(c, fun);
            }
    
            public TResult Method<TClass, TResult>(object[] args, Func<TClass, IComMethod, IMsg, TResult> fun) where TClass : class
            {
                if (top != -1 && msglist[top].State == false)
                    return default(TResult);
                TClass c = CreateInstance.createInstance<TClass>(args);
                return getResult(c, fun);
            }
    
            public TResult Method<TBaseClass, TSubClass, TResult>(Func<TBaseClass, IComMethod, IMsg, TResult> fun)
                where TBaseClass : class
                where TSubClass : class,new()
            {
                if (top != -1 && msglist[top].State == false)
                    return default(TResult);
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>();
    
                return getResult(c, fun);
            }
    
            public TResult Method<TBaseClass, TSubClass, TResult>(object[] args, Func<TBaseClass, IComMethod, IMsg, TResult> fun)
                where TBaseClass : class
                where TSubClass : class
            {
                if (top != -1 && msglist[top].State == false)
                    return default(TResult);
                TBaseClass c = CreateInstance.createInstance<TBaseClass, TSubClass>(args);
    
                return getResult(c, fun);
            }
    
            TResult getResult<TClass, TResult>(TClass c, Func<TClass, IComMethod, IMsg, TResult> fun)
            {
                Msg msg = new Msg();
                TResult result = fun(c, this, msg);
                if (result != null)
                    msg.State = true;
                msglist.Add(msg);
                top++;
                return result;
            }
    
            public Msg getResult()
            {
                return this.msglist[top];
            }
        }
    }
    复制代码

    最后是实现过滤器部分,过滤器也是使用委托,将委托里面的方法放在一个池中,使用字典,将他们对应,在使用特性时候,就可以将对应方法的key写在特性上就可以了。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Bll
    {
        public class FilterAttribute:Attribute
        {
            public FilterAttribute(string key)
            {
                Action fun = FilterPool.DelegatePool[key];
                if (fun != null)
                    fun();
            }
        }
    }
    复制代码

    最后一个Bllhelper类,里面存放静态方法,用于创建对象,UI层不能访问CreateInstance,只能通过它;一个特殊的静态函数,就是在应用开始时候将需要的过滤器填充到里面。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Bll
    {
        public class BllHelper
        {
            public static TClass createInstance<TClass>()
                where TClass : class,new()
            {
                return CreateInstance.createInstance<TClass>();
            }
            public static TClass createInstance<TClass>(object[] args)
                where TClass : class
            {
                return CreateInstance.createInstance<TClass>(args);
            }
            public static TBaseClass createInstance<TBaseClass, TSubClass>()
                where TSubClass : class,new()
                where TBaseClass : class
            {
                return CreateInstance.createInstance<TBaseClass, TSubClass>();
            }
            public static TBaseClass createInstance<TBaseClass, TSubClass>(object[] args)
                where TBaseClass : class
                where TSubClass : class
            {
                return CreateInstance.createInstance<TBaseClass, TSubClass>(args);
            }
    
            public static void setFilter(string key,Action fun)
            {
                FilterPool.DelegatePool.Add(key, fun);
            }
    
            public static IComMethod getMethod<T>()
                where T:class,new()
            {
                return createInstance<IComMethod, T>();
            }
        }
    }
    复制代码

    好了,基本思路就这样。

  • 相关阅读:
    Maven工程读取properties文件过程
    Nginx实现高可用(了解)
    使用Nginx实现负载均衡(tomcat集群之后实现交叉访问)
    使用Nginx实现反向代理过程(一台服务器部署两个网站)
    一台服务器,通过不同域名区分不同主机,配置步骤
    EditPlus5.0破解激活
    [通知] 博客停更
    [论文理解] 活体检测算法论文小结 (一)
    [CUDA] CUDA编程入门
    [学习笔记]《机器学习基础》 课程总结(一)
  • 原文地址:https://www.cnblogs.com/zhaodahai/p/6831314.html
Copyright © 2020-2023  润新知