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>();
        }
    }
}

 

好了,基本思路就這樣。

 項目地址鏈接:http://files.cnblogs.com/files/jnxzk/Work18.rar

不過,這個項目還沒完工,因為還有好多沒有考慮進去。是一時想法一時寫的代碼,所以就沒有注釋。項目能夠正常使用,如果大家有什么不理解的地方,或者不足,可以下邊評論,謝謝大家~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM