zoukankan      html  css  js  c++  java
  • 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>();
            }
        }
    }
    复制代码

    好了,基本思路就这样。

  • 相关阅读:
    caffe常用层: batchNorm层和scale层
    简述configure、pkg-config、pkg_config_path三者的关系
    python删除list中元素的三种方法
    Leetcode 872. Leaf-Similar Trees
    Leetcode 508. Most Frequent Subtree Sum
    Leetcode 572. Subtree of Another Tree
    Leetcode 894. All Possible Full Binary Trees
    Leetcode 814. Binary Tree Pruning
    Leetcode 557. Reverse Words in a String III
    python 多维list声明时的小问题
  • 原文地址:https://www.cnblogs.com/zhaodahai/p/6831314.html
Copyright © 2011-2022 走看看