<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                #抽象工廠模式(Abstract factory Pattern) ##簡介 抽象工廠模式是一種軟件開發設計模式。抽象工廠模式提供了一種方式,可以將一組具有同一主題的單獨的工廠封裝起來。在正常使用中,客戶端程序需要創建抽象工廠的具體實現,然后使用抽象工廠作為接口來創建這一主題的具體對象。客戶端程序不需要知道(或關心)它從這些內部的工廠方法中獲得對象的具體類型,因為客戶端程序僅使用這些對象的通用接口。抽象工廠模式將一組對象的實現細節與他們的一般使用分離開來。 ##簡例 有個項目原來是依賴于access數據庫,現在要用sqlserver,怎么更改呢(解耦)? ###用工廠方法模式的數據訪問程序 IUser接口,用于客戶端訪問,解除與具體數據庫訪問的耦合。 ``` interface IUser { void Insert(User user); User GetUser(int id); } ``` Sqlserver類,用于訪問SQL Server的User。 ``` class SqlserverUser : IUser { public void Insert(User user) { Console.WriteLine("在SQL Server中給User表增加一條記錄"); } public User GetUser(int id) { Console.WriteLine("在SQL Server中給User表獲取一條記錄"); return null; } } ``` AccessUser類,用于訪問Access的User。 ``` class AccessUser : IUser { public void Insert(User user) { Console.WriteLine("在access中給User表增加一條記錄"); } public User GetUser(int id) { Console.WriteLine("在access中給User表獲取一條記錄"); return null; } } ``` IFactory接口,定義一個創建訪問User表對象的抽象的工廠接口。 ``` interface Ifactory { IUser CreateUser(); } ``` sqlServerFactory類,實現IFactory接口,實例化SqlserverUser。 ``` class sqlServerFactory: IFactory { public IUser CreateUser() { return new SqlserverUser(); } } ``` AccessFactory類,實現IFactory接口,實例化AccessUser. ``` class AccessFactory: IFactory { public IUser CreateUser() { return new AccessUser(); } } ``` 客戶端代碼 ``` static void main(string[] args) { User user = new User(); IFactory factory = new SqlServerFactory(); IUser iu = factory.CreateUser(); iu.Insert(user); iu.GetUser(1); Console.Read(); } ``` 但是數據里面不可能只有一個User表,比如說增加部門表,此時怎么辦呢。 ###抽象工廠類 IUser接口,用于客戶端訪問,解除與具體數據庫訪問的耦合。 ``` interface IDepartment { void Insert(Department department); Department GetDepartment(int id); } ``` SqlserverDepartment類,用于訪問SQL Server的Department。 ``` class SqlserverDepartment : IDepartment { public void Insert(Department department) { Console.WriteLine("在SQL Server中給Department表增加一條記錄"); } public Department GetDepartment(int id) { Console.WriteLine("在SQL Server中給Department表獲取一條記錄"); return null; } } ``` AccessDepartment類,用于訪問Access的Department。 ``` class AccessDepartment : IDepartment { public void Insert(Department department) { Console.WriteLine("在Access中給Department表增加一條記錄"); } public Department GetDepartment(int id) { Console.WriteLine("在Access中給Department表獲取一條記錄"); return null; } } ``` *** ``` interface IUser { void Insert(User user); User GetUser(int id); } ``` Sqlserver類,用于訪問SQL Server的User。 ``` class SqlserverUser : IUser { public void Insert(User user) { Console.WriteLine("在SQL Server中給User表增加一條記錄"); } public User GetUser(int id) { Console.WriteLine("在SQL Server中給User表獲取一條記錄"); return null; } } ``` AccessUser類,用于訪問Access的User。 ``` class AccessUser : IUser { public void Insert(User user) { Console.WriteLine("在access中給User表增加一條記錄"); } public User GetUser(int id) { Console.WriteLine("在access中給User表獲取一條記錄"); return null; } } ``` IFactory接口,定義一個創建訪問User表對象的抽象的工廠接口。 ``` interface Ifactory { IUser CreateUser(); IDepartment CreateDepartment(); } ``` sqlServerFactory類,實現IFactory接口,實例化SqlserverUser。 ``` class sqlServerFactory: IFactory { public IUser CreateUser() { return new SqlserverUser(); } public IDepartment CreateDepartment() { return new SqlserverDepartment(); } } ``` AccessFactory類,實現IFactory接口,實例化AccessUser. ``` class AccessFactory: IFactory { public IUser CreateUser() { return new AccessUser(); } public IDepartment CreateDepartment() { return new AccessDepartment(); } } ``` 客戶端代碼 ``` static void main(string[] args) { User user = new User(); IFactory factory = new SqlServerFactory(); IUser iu = factory.CreateUser(); iu.Insert(user); iu.GetUser(1); Console.Read(); } ``` 抽象工廠模式:提供一個創建一系列相關或者相互依賴的對象的接口,而無需指定它們具體的類。 ###用簡單工廠來改進抽象工廠 ``` class DataAccess { private static readonly string db = "Sqlserver"; // private static readonly string db = "access"; public static IUser CreateUser() { IUser result = null; switch (db) { case:"Sqlserver": result = new SqlserverUser(); break; case:"Acesss": result = new AcesssUser(); break; } return result; } publci static IDepartment CreateDepartment() { IDepartment result = null; switch (db) { case:"Sqlserver": result = new SqlserverDepartment(); break; case:"Acesss": result = new AcesssDepartment(); break; } return result; } } ``` 客戶端代碼 ``` static void Main(string[] args) { User user = new User(); Department dept = new Department(); IUser iu = DataAccess.createUser(); iu.Insert(user); iu.GetUser(1); IDepartment id = DataAccess.createDepartment(); id.Inert(dept); id.GetDepartment(1); Console.Read(); } ``` 利用反射或者配置文件都可以減少在所有簡單工廠的switch和if,解除分支判斷帶來的耦合。 “工廠”是創建產品(對象)的地方,其目的是將產品的創建與產品的使用分離。抽象工廠模式的目的,是將若干抽象產品的接口與不同主題產品的具體實現分離開。這樣就能在增加新的具體工廠的時候,不用修改引用抽象工廠的客戶端代碼。 使用抽象工廠模式,能夠在具體工廠變化的時候,不用修改使用工廠的客戶端代碼,甚至是在運行時。然而,使用這種模式或者相似的設計模式,可能給編寫代碼帶來不必要的復雜性和額外的工作。正確使用設計模式能夠抵消這樣的“額外工作”。 ##從NSArray看類簇 Class Clusters(類簇)是抽象工廠模式在iOS下的一種實現,眾多常用類,如NSString,NSArray,NSDictionary,NSNumber都運作在這一模式下,它是接口簡單性和擴展性的權衡體現,在我們完全不知情的情況下,偷偷隱藏了很多具體的實現類,只暴露出簡單的接口。 雖然官方文檔中拿NSNumber說事兒,但Foundation并沒有像圖中描述的那樣為每個number都弄一個子類,于是研究下NSArray類簇的實現方式。 ###__NSPlacehodlerArray 熟悉這個模式的同學很可能看過下面的測試代碼,將原有的alloc+init拆開寫: ``` id obj1 = [NSArray alloc]; // __NSPlacehodlerArray * id obj2 = [NSMutableArray alloc]; // __NSPlacehodlerArray * id obj3 = [obj1 init]; // __NSArrayI * id obj4 = [obj2 init]; // __NSArrayM * ``` 發現+ alloc后并非生成了我們期望的類實例,而是一個__NSPlacehodlerArray的中間對象,后面的- init或- initWithXXXXX消息都是發送給這個中間對象,再由它做工廠,生成真的對象。這里的__NSArrayI和__NSArrayM分別對應Immutable和Mutable(后面的I和M的意思) 于是順著思路猜實現,__NSPlacehodlerArray必定用某種方式存儲了它是由誰alloc出來的這個信息,才能在init的時候知道要創建的是可變數組還是不可變數組 經過研究發現,Foundation用了一個很賤的比較靜態實例地址方式來實現,偽代碼如下: ``` static __NSPlacehodlerArray *GetPlaceholderForNSArray() { static __NSPlacehodlerArray *instanceForNSArray; if (!instanceForNSArray) { instanceForNSArray = [[__NSPlacehodlerArray alloc] init]; } return instanceForNSArray; } static __NSPlacehodlerArray *GetPlaceholderForNSMutableArray() { static __NSPlacehodlerArray *instanceForNSMutableArray; if (!instanceForNSMutableArray) { instanceForNSMutableArray = [[__NSPlacehodlerArray alloc] init]; } return instanceForNSMutableArray; } // NSArray實現 + (id)alloc { if (self == [NSArray class]) { return GetPlaceholderForNSArray() } } // NSMutableArray實現 + (id)alloc { if (self == [NSMutableArray class]) { return GetPlaceholderForNSMutableArray() } } // __NSPlacehodlerArray實現 - (id)init { if (self == GetPlaceholderForNSArray()) { self = [[__NSArrayI alloc] init]; } else if (self == GetPlaceholderForNSMutableArray()) { self = [[__NSArrayM alloc] init]; } return self; } ``` Foundation不是開源的,所以上面的代碼是猜測的,思路大概就是這樣,可以這樣驗證下: ``` id obj1 = [NSArray alloc]; id obj2 = [NSArray alloc]; id obj3 = [NSMutableArray alloc]; id obj4 = [NSMutableArray alloc]; // 1和2地址相同,3和4地址相同,無論多少次都相同,且地址相差16位 ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看