新定義三層,指揮官模式

孫凱旋發表於2016-09-04

一、概念

1、三層:

 

表示層及UI層: 主要是頁面顯示與控制操作

業務層:業務邏輯的處理

資料訪問層:封裝了對資料庫的增、刪、查和改操作。

 

為什麼三層這麼好用

原因是他的結構體系非常的清晰易懂,從功能與實現方面進行了層次劃分,實現了高內聚和低耦合。

我們專案最常用結構體系就是在三層的基礎加上一個通用層(Common)、第三方介面或者工具層等,方便對一些公用的東西和特殊性的東西進行分類。

至今為止這個結構體系依然是最好用的專案結構體系。

 

2、指揮官模式:

傳統的三層架構

傳統的三層架構是不允許跨層呼叫的 ,也就是說指揮官是UI層

缺點:

1、來回切換

指揮官只能指揮業務層並不能知道資料層在做什麼,這就意味著我們在寫程式碼的時候需要看2層才能看清晰這個功能具體做了些什麼,在編碼過程中就需要頻繁的來回切換。

2、浪費

很多時候指揮官只需要直接傳達給資料層,現在只能強制傳達給業務層,然後在通過業務層轉達給資料層

3、寫好業務層有難度

為什麼說寫好這個業務層有難度,也許是大家很疑惑的一件事情下面我就舉例子講解

現實案例:

很多人工作二三年都認為業務層是多餘的不方便,不加又不合適,寫著寫著指揮官就直接調資料層了。

解答案例:

原因是業務層受到了限制,UI層的所有東西不能使用,但是又要把非UI部分進行邏輯分離,在這種情況下 業務層本能發揮100%實力,現在就只能發揮70%。

正是這種原因好多的邏輯都寫在了指揮官層(UI層),業務層就是個空架子,只有指揮官層(UI層)東西太多時才交給業務層處理,有經驗的程式設計師才能夠真正的把UI層和業務層的東西劃分清楚,大大提高了分層難度。

 

指揮官重定義三層

指揮官模式是將權力全部掌控在自已手上,只做我能做和我想做的事情。

 

 

指揮官是用來把控全域性的  技術活他做不了(資料訪問層),體力活他做不了(包外層)。

優點:也就是解決了傳統三層的3個缺點

1、指揮官層就能看透一切,並且沒有冗餘程式碼

2、減少不必要的開銷,指揮官可以直接向資料層下達指令

3、分層更加清晰,指揮官層只做我想做的事情,不想做的事情直接外包,不能做的事情只能找資料層。

 

 

 

二、基於 ASP.NET MVC +IOC+ SqlSugar.ORM+語法糖.dll實踐指揮官模式

DEMO地址:

https://github.com/sunkaixuan/ASPNETMVCCRUDDEMO

1、建立專案:

新建MVC4專案,全部預設刪掉沒用的資料夾和檔案

2、nuget引用dll:

我們使用的ORM為SqlSugar,語法糖框架 SyntacticSugar.dll 主要封裝了一些常用函式

3、目錄結構

每個控制器都用一個pack資料夾包著 例如homeController為指揮官層,homeController裡面不想處理的事情都交給Outsourcing檔案,

控制器不能處理的事情通過一個DbService.Command把 DAO層打通

 

從上圖可以看出DAO層已經精簡到只有三個檔案,是的只要這三個檔案及可。

如果需要一些通用資料服務可以對DB物件進行一層封裝

 

 

控制器程式碼:

  public class ListController : Controller
    {
        private DbService _service;
        public ListController(DbService service)
        {
            _service = service;
        }

        public ActionResult Index(string title, int pageIndex = 1, int pageSize = 5)
        {
            var model = new ResultModel<string, List<dnt_test_topics>, HtmlString, List<dnt_test_forums>>();
            _service.Command<Outsourcing>((db, o) =>
            {
                model.ResultInfo = "增刪查改";
                var queryable = o.GetQueryable(title);//處理查詢邏輯
                queryable.DB = db;//設定連線物件
                int pageCount = queryable.Count();
                model.ResultInfo2 = queryable.ToPageList(pageIndex, pageSize);
                model.ResultInfo3 = o.GetPageString(pageIndex, pageSize, pageCount);//獲取分頁字串
                model.ResultInfo4 = db.Queryable<dnt_test_forums>().ToList();//編輯用到的分類下拉選單
            });
            return View(model);
        }


        public JsonResult Delete(int id)
        {
            ResultModel<dynamic> model = new ResultModel<dynamic>();
            _service.Command<Outsourcing>((db, o) =>
            {
                model.IsSuccess = model.ResultInfo = db.Delete<dnt_test_topics, int>(id);
                //減少了2個類的冗餘程式碼,這就是和傳統三層最大區別
            });
            return Json(model, JsonRequestBehavior.AllowGet);
        }

        public JsonResult GetById(int id)
        {
            ResultModel<dynamic> model = new ResultModel<dynamic>();
            _service.Command<Outsourcing>((db, o) =>
            {
                model.ResultInfo = db.Queryable<dnt_test_topics>().Single(it => it.tid == id);
                model.IsSuccess = true;
            });
            return Json(model, JsonRequestBehavior.AllowGet);
        }


        public JsonResult Insert(dnt_test_topics obj)
        {
            ResultModel<dynamic> model = new ResultModel<dynamic>();
            _service.Command<Outsourcing>((db, o) =>
            {
                obj.postdatetime = DateTime.Now;
                obj.lastpost = DateTime.Now;
                obj.lastposter=obj.poster = "管理員";
                model.ResultInfo = db.Insert(obj);
                model.IsSuccess = true;

            });
            return Json(model, JsonRequestBehavior.AllowGet);
        }


        public JsonResult Update(dnt_test_topics obj)
        {
            ResultModel<dynamic> model = new ResultModel<dynamic>();
            _service.Command<Outsourcing>((db, o) =>
            {
                model.IsSuccess = model.ResultInfo = db.Update<dnt_test_topics>(
                    new { title = obj.title, fid = obj.fid }
                    , it => it.tid == obj.tid);

            });
            return Json(model, JsonRequestBehavior.AllowGet);
        }
    }
View Code

 

 

4、指揮官與指揮官的操作

指揮官層也相當於應用介面層,介面與介面之間的操作使用  RestSharp 。  

三、總結

指揮官模式是以業務為核心的真正意義上的面向介面面向服務程式設計架構,適合多平臺應用。(傳統寫法都是表或者類去作為服務一個業務可能會有多張表的操作,所以以表劃分的介面是不合理的)

一切從簡,沒有冗餘代,這個是我工作多年總結出的最偷懶寫法,但不能保證每個人都喜歡,喜歡的就給個贊。

 

 

DEMO地址:

 

https://github.com/sunkaixuan/ASPNETMVCCRUDDEMO

 

相關文章