設計開篇

来源:http://www.cnblogs.com/Skyven/archive/2016/06/19/5599032.html
-Advertisement-
Play Games

1 設計模式 類是我們面向對象編程的承載工具,可以說是面向對象的起點。 設計模式,這種算面向對象的進化。按照gof設計模式的分類 設計模式分為:創建型,結構型,行為型。 其中創建型主要和類的創建有關 結構性組織擴展類和類之間的關係 行為型主要擴展的類的訪問 這三個對應到類上 創建型模式對應的是構造函 ...


1 設計模式

   類是我們面向對象編程的承載工具,可以說是面向對象的起點。
   設計模式,這種算面向對象的進化。按照gof設計模式的分類
   設計模式分為:創建型,結構型,行為型。
   其中創建型主要和類的創建有關
   結構性組織擴展類和類之間的關係
   行為型主要擴展的類的訪問
   這三個對應到類上
   創建型模式對應的是構造函數
   結構型對應的是類的屬性
   行為型對應類的方法
   就想我們以前學數學中很多證明題,都源自最基本的定理,面向對象編程也有類似的地方
   設計模式就是類最基本功能的一個進化

 


 

2.依賴註入    

  相信大家對Ioc(依賴註入)肯定不陌生,Ioc主要遵循設計原則中的依賴倒置原則,  

  但是假設我們不要把這個東西提升到設計的高度,只看它的功能就會發現,   Ioc創建類正好就是控制類的構造函數,和設計模式中創建型模式有關,  

  例如創建型模式中單例模式用ioc生命周期管理可以達到同樣的效果,

  這裡以Unity為例,Untiy支持child容器。利用child容器,我們可以在運行時提供更多動態創建的內容。

  我們以asp.net mvc為例,我們可以在session初始化的時候根據不同用戶註入不同介面的實現。

  例如我們可以在repository中註入一個預設的規約,當不同用戶登錄   我們可以將用戶對數據的訪問許可權形成一個規約,

  註冊到child容器中,然後在controller激活的時候使用當前session的子容器來激活controller。

  在這裡使用例子中,Ioc又實現了類似factory,甚至是building模式的功能(這個例子會在後面的文章中給大家展現具體的實現).

 


 

3.抽象的維度  

  多態是代碼的下行  

  抽象是代碼的下行

  如果B繼承自A,C繼承自A,那麼A稱之為B,C這個維度的抽象,B,C稱之為A這個維度的變化 A,B,C稱之為一個維度的繼承關係

  傳統的繼承解決的是一個維度的變化,如果我們在這個維度上面引入泛型,並且用where限制泛型的行為 或者屬性,

  那麼就可以用諸如interface<T1,T2,T3>這樣,通過組合幾個泛型提供多個維度的變化。 此處用泛型擴展的繼承有點類似於多繼承。

 


 

4.元數據編程(Attribute)

  Attribute在我所使用的元數據編程占有重要位置。

  在asp.net mvc中,ValueProvider,ModuleBinding,Validator,Filter,都使用了元數據編程。

  不談這個大的我們看一個更小的例子。

  最早在winform中使用DateGrid的時候,我們都是在grid設計器中去設置列的屬性,名稱,綁定的欄位,等等。

  如果我們引入元數據編程,就可以通過在類的屬性上加上特性來擴展。

  這樣做更便於維護,當你的界面需要修改時,只需要在綁定的類上做修改,修改的地方相對集中,而不用去操作設計器。

 


 

5. 策略工廠

  上面說了很多理論的東西,下麵為大家帶來點乾貨。
  首先我們分析一個簡單工廠的代碼:

  public interface ITest
      {
          void DoSomething();
      }


      public class Test1: ITest
      {
          public void DoSomething()
          {

          }
      }
      public class Test2: ITest
      {
          public void DoSomething()
          {

          }
      }


      public class Factory
      {
          public static ITest Create(string type)
          {
              if (type == "1")
                  return new Test1();
              if (type == "2")
                  return new Test2();
              throw new NotImplementedException();
          }
      }

 

分析簡單工廠的弊端  

  1,擴展不方便需要改動create的邏輯  

  2,客戶需要知道create的具體邏輯 

  3,創建類型過於單一導致簡單工廠類的泛濫  

  4,無法為對象創建提供靈活性,例如構造函數參數  

  5,無法實現運行時擴展

下麵我對簡單工廠做了一些改造

    public  interface IStrategy
    {
    }

    public interface IGenericsFactory<TStrategy>
        where TStrategy : IStrategy
    {

        /// <summary>
        /// 註冊處理策略
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        void Regist(Type type);


        /// <summary>
        /// 獲取處理策略
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        TStrategy GetStrategy(string name);

        /// <summary>
        /// 獲取所有的處理策略
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        List<string> GetStrategys();
    }

    public class GenericsFactory<TStrategy> : IGenericsFactory<TStrategy>
        where TStrategy : IStrategy
    {
        public GenericsFactory()
        {
            if (_strategys == null)
            {
                _strategys = GetType().Assembly
                        .GetTypes()
                        .Where(item => item.GetInterfaces().Contains(typeof(TStrategy)) || item.IsSubclassOf(typeof(TStrategy)))
                        .Where(item => !item.IsAbstract)
                        .ToDictionary(item =>
                        {
                            var desc = item.GetCustomAttribute<DescriptionAttribute>();
                            return desc != null ? desc.Description : string.Empty;
                        }, item => item);
            }
        }

        protected Dictionary<string, Type> _strategys;

        public void Regist(Type type)
        {
            if (type.GetInterfaces().Contains(typeof(TStrategy)) && type.IsSubclassOf(typeof(TStrategy)))
                throw  new TypeLoadException(string.Format("類型不是從{0},繼承",typeof(TStrategy).Name));
            if (_strategys.ContainsKey(MetaDataManager.Attribute.GetDescription(type)))
                return;
            _strategys.Add(MetaDataManager.Attribute.GetDescription(type), type);
        }

        public TStrategy GetStrategy(string name)
        {
            if (!_strategys.ContainsKey(name))
                _strategys.Add(name, typeof(TStrategy));
            return (TStrategy)UnityService.Resolve(_strategys[name]);
        }


        public List<string> GetStrategys()
        {
            return _strategys.Keys.ToList();
        }
    }

 

改造思路
  1,使用將create的類型標記在對應的介面實現上,反射獲取子類的特性,如果新增加一個類型只
       需要增加子類,並且在子類添加特性
  2,將所有可用子類的元素據緩存起來,在工廠構造函數中反射所有子類和子類的特性用字典緩存起來
       並且所有可創建的類型暴露給外部
  3,將構造出來的類型做成泛型,並且提供泛型限制,將可構造類型獨立出一個維度來變化
  4,通過ioc來動態創建類型
  5,通過提供regist來提供運行時擴展

使用的案例:
  1,SSO登陸,前臺用戶和後臺用戶,存放在不同的數據表,數據結構也可能不一樣
  2,動態數據許可權配置,例如,某個角色只能訪問某部分數據 =,>,<等等這些篩選條件的擴展
  3,狀態者模式,狀態可擴展,可以由界面去選擇某種狀態對應那種處理方式,
     將處理方式類型放在資料庫
  4,責任鏈模式中節點的擴展和配置
       通過緩存可以直接所有節點,靈活配置節點來實現流程的功能
  5,裝飾器的擴展
  可以搭配裝飾器模式配置出先用某個裝飾後用某個裝飾、

 


 

總結:

  上面的這些關於程式設計的一些思考,會在後面的文章中分享一些自己在實際項目中的
  具體案例,請關註後續文章。要想一個架構設計能順利推廣,最簡單粗暴的方法就是這個架構能夠幫助程式員少些代碼。
  下一篇文章將分享一個,全棧式編程的設計,主要應用於後臺系統的增刪改查,方便程式員更
  快速的處理掉數據的增刪改查這部分通用邏輯

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 Swift提供了類似C語言的流程式控制制結構,包括可以多次執行任務的for和while迴圈。還有基於特定條件選擇執行不同代碼分支的if、guard和switch語句,還有控制流程跳轉到其他代碼的break和continue語句。 Swift增加了for-in迴圈,用來更簡單地遍曆數組、字典、區間、 ...
  • 習題集解析部分 第7章 圖 ——《數據結構題集》-嚴蔚敏.吳偉民版 源碼使用說明 鏈接☛☛☛ 《數據結構-C語言版》(嚴蔚敏,吳偉民版)課本源碼+習題集解析使用說明 課本源碼合輯 鏈接☛☛☛ 《數據結構》課本源碼合輯 習題集全解析 鏈接☛☛☛ 《數據結構題集》習題解析合輯 相關測試數據下載 鏈接☛ ...
  • AVL樹是高度平衡的二叉樹,任何節點的兩個子樹的高度差別<=1 實現AVL樹 定義一個AVL樹,AVLTree,定義AVLTree的節點內部類AVLNode,節點包含以下特性: 1.key——關鍵字,對AVL樹的節點進行排序 2.left——左子樹 3.right——右子樹 4.height——高度 ...
  • 補充說明: 當前環境是在windows環境下 python版本是:python 3.4. 剛開始學習python,一邊看書一邊論壇里閱讀感興趣的代碼, http://www.oschina.net/code/snippet_1406266_43470 的代碼運行報錯情況及解決方案。 1. Impor ...
  • 1 在windows下運行python程式 1)從DOS命令行運行python腳本 用python解釋器來執行python腳本,在windows下麵python解釋器是python.exe,我的python文件安裝在D:\Python27,在這個目錄下可以看到python解釋器。完整的命令應該是: ...
  • C++引用的學習: 通常引用第一個作用,人們會想到的是引用的變數的別名;(可以說是直接操作這個變數); 引用的聲明: Type + & + name(可以認為是一個常指針) 註意:(1)&是起標識符的作用; (2)聲明引用時,必須先將其進行初始化; (3)不能建立數組的引用,因為數組是因為由若幹個元 ...
  • shell變數的賦值、變數的取值、變數的取消與查看、局部變數/用戶變數、全局變數/環境變數、特殊變數 ...
  • 本文將介紹Java多線程開發必不可少的鎖和同步機制,同時介紹sleep和wait等常用的暫停線程執行的方法,並詳述synchronized的幾種使用方式,以及Java中的重入鎖(ReentrantLock)和讀寫鎖(ReadWriteLock),之後結合實例分析了重入鎖條件變數(Condition)... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...