程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#多態“說來也說”——邏輯層BLL中的多態使用,

C#多態“說來也說”——邏輯層BLL中的多態使用,

編輯:C#入門知識

C#多態“說來也說”——邏輯層BLL中的多態使用,


本文版權歸博客園和作者吳雙本人共同所有。歡迎轉載,轉載和爬蟲請注明原文地址  http://www.cnblogs.com/tdws/p/5861842.html

昨天晚上,有個朋友說學了好久,依然沒搞懂多態,讓我簡單講解一下。我覺得多態在面向多想的三大特性當中,算是最簡單的,最難的是看似容易的封裝。在編寫面向對象代碼時,如何讓代碼可讀性更強,除了變量和方法命名標准外,要做的到一個方法只做一件事情,這樣的思想是《代碼整潔之道》一書中主要推崇的思想,其實有經驗的各位都希望自己看到的代碼是簡短,可維護,可讀性強的,相信大家也都“有幸”遇到過幾百上千行的代碼,更過分的是有個朋友曾經維護一個上萬行的Action,誇張的說,調試並走通邏輯,一次要三天,有的人說這是業務邏輯不斷增加所導致,但我認為,在這種情況下,更應該盡量做到一個方法做一件事情。我也不多吐槽了,關於代碼整潔,我在大三的時候,就"吐槽"過http://www.cnblogs.com/tdws/p/4674489.html。

封裝也不是今天的主題,今天我們要說的是多態,在朋友問我的時候,我給他舉了下面這個簡短的例子。

總體概括這個例子來講就是在基本的三層架構當中,DAL層建兩個類AdminDal,UserDal。兩個類中,都有增加對象和刪除對象地方法,那這個時候,我們應該給兩個類抽象出一個父類BaseDal<T>,父類中是他們的公共方法,並且父類需要一個泛型T,這樣父類的方法,才能明白你所要添加或者刪除的object到底是什麼類型的。請看如下代碼。雖然兩個類的公共方法在父類當中,但是他們自身特有的方法,還是要寫在自己的Dal層當中。

1   public class UserDal: BaseDal<UserEntity>
2   {
3         
4   }
1   public class AdminDal: BaseDal<AdminEntity>
2     {
3         public void Manage()
4         {
5             Console.WriteLine("管理員管理網站");
6         }
7     }
 1 public class BaseDal<T>
 2     {
 3         public void AddObj(T obj)
 4         {
 5             Console.WriteLine("添加對象成功,對象屬於"+obj.GetType().ToString());
 6         }
 7 
 8         public void DeleteObj(T obj)
 9         {
10             Console.WriteLine("刪除對象成功,對象屬於"+obj.GetType().ToString());
11         }
12 
13     }

 下面給出邏輯層代碼,如果說普通的開發過程當中,你的代碼也許是這樣的。

 1  public class UserBll 
 2     {
 3         UserDal dal = new UserDal();
 4 
 5         public void Add(UserEntity obj)
 6         {
 7             dal.AddObj(obj);
 8         }
 9 
10         public void Delete(UserEntity obj)
11         {
12             dal.DeleteObj(obj);
13         }
14      }
    public class AdminBll 
{ AdminDal dal = new AdminDal(); public void Add(AdminEntity admin) { dal.AddObj(admin); } public void Delete(AdminEntity admin) { dal.DeleteObj(admin); } public void Manage() { dal.Manage(); } }

也就是在各自的邏輯層當中,調用dal層。這個時候你又看到依然有這麼多重復的代碼,是不是應該再次封裝成一個BaseBll<T>呢。答案是肯定的,但是問題又來了,在封裝父類的過程中,你會發現,這個dal的對象怎麼封裝呢?這就是用到多態的關鍵點。下面看一下BaseBll.cs的代碼。

 public abstract class BaseBll<T> where T:class, new()
    {
        public BaseDal<T> currentDal;

        public BaseBll()
        {
            SetCurrentDal();
        }

        public abstract void SetCurrentDal();


        public void BaseAdd(T obj)
        {
            currentDal.AddObj(obj);
        }

        public void BaseDelete(T obj)
        {
            currentDal.DeleteObj(obj);
        }

    }

我給了一個抽象的基類,並且給出抽象的SetCurrentDal的抽象方法定義。該方法用於設置當前類的currentDal到底是adminDal還是userDal。我們在構造函數中調用SetCurrentDal這個抽象方法,為什麼在構造函數中調用的原因是,當實例化子類對象時,一定是首先進入其父類的構造函數。當子類AdminBll和UserBll繼承BaseBll<T>的時候,必須重寫抽象方法,並且為BaseDal<T> currentDal對象設置實際的值。我先給出子類的代碼

 1 public class AdminBll : BaseBll<AdminEntity>
 2     {
 3         AdminDal dal = new AdminDal();
 4         public AdminBll()
 5         {
 6 
 7         }
 8         public void Manage()
 9         {
10             new AdminDal().Manage();
11         }
12 
13         public override void SetCurrentDal()
14         {
15             currentDal = new AdminDal();
16         }
17     }
1 public class UserBll : BaseBll<UserEntity>
2     {
3         public override void SetCurrentDal()
4         {
5             base.currentDal = new UserDal();
6         }
7     }

當實例化子類的對象時,過程為:子類構造函數(不進入)—進入父類構造函數—父類構造內部調用子類重寫的SetCurrentDal(當前多態的currentDal到底是誰的實例)—父類構造執行完畢(設置currentDal完成)—子類構造函數。這就是抽象方法實現的多態。

下面在UI層調用一下,看看結果:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             AdminBll adminBll = new AdminBll();
 6             AdminEntity admin = new AdminEntity() {AdminName="吳雙",AdminPwd="123" };
 7             adminBll.Manage();
 8             adminBll.BaseAdd(admin);
 9             Console.ReadKey();
10         }
11     }

輸出結果:

 

在開發的過程中,也許你會有很多實體類,每個實體類都有各自的增刪改查等其他共有方法,基於這樣的情況,我們就需要手段來將其封裝。為什麼在邏輯層使用了多態,原因就是我們封裝父類的時候,不確定當前的currentDal到底是adminDal還是userDal還是xxxDal。為了封裝出基類,這個多態的對象就必不可少了。

當然在實際當中,如果你是寫原生sql,這樣封裝的確不容易,各種拼接sql。但如果說你用ORM框架,EF,Dapper之類的,這個方法真的是必不可少的,你可能再加上接口層,加上工作單元,創建對象非new,使用抽象工廠,依賴注入等。無論怎樣,這一層的多態一定能用到,只是創建對象稍作修改。

 

下一階段也打算進行後台架構搭建分享,MVC WebApi+EF/Dapper+工作單元+抽象工廠/依賴注入Autofac+AutoMapper+日志組件等。

我也曾多次在項目中搭建此類框架,在緩存提高性能,處理高並發,應用服務器集群,緩存集群,隊列集群等方面,本次也會加入到分享當中。

 

如果今天的點滴分享,對您有點滴幫助,請點贊支持,也為自己的進步點贊。

點擊下方關注,我們共同進步。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved