《深入浅出设计模式-中文版》读书笔记-工厂模式(五)
今天給大家帶來的是:工廠模式。
我們在代碼中創建一個對象,我們會很自然的想到new。其實,除了new意外,我們還有很多的方式可以創建對象。不說復雜的模式,就說簡單的語法,其實.NET框架中還有下面的方法。根據需要創建的對象的類型,動態創建對象。
Activator.CreateInstance
?
通過前面我們已經講過一條原則:
針對接口編程,不針對實現編程。
使用new創建對象很明顯就是一個針對實現編程,new后面需要一個具體的類,不允許你new一個接口或者是抽象類。包括用Activator.CreateInstance都不能創建接口或者抽象類。
那是不是就是說以后不能或者是不要再用new了,都用其他方式嗎?
也不是的,也要根據情況來分析,不是一概而論的,在后面會給出一些簡單的標準,更多的要結合具體的設計定奪。
很多時候我們會碰到下面的代碼:
代碼 ?????string?userType?=?"";
????????????????if?(userType?==?"admin")
????????????????{//創建管理員
????????????????}
????????????????else?if?(userType?==?"supervisor")
????????????????{//創建超級管理員
????????????????}
????????????????else?if?(userType?==?"coommon")
????????????????{
????????????????????//創建普通用戶
????????????????}
?
如果以后增加了用戶的類型,不僅要創建用戶類型實體,還需要打開創建用戶的這段代碼,后面加上一個if。。。else。。。。
如果這段代碼沒有封裝,就更麻煩了,散落在項目的各處,每個地方都要打開,ctrl+c,ctrl+v。開始了無盡的噩夢。
對于后面的維護成了問題,而且違反了一條原則:
OCP原則,對增加開放,對修改封閉。
首先使用封裝變化原則對這段代碼做一些抽象,上面這段明顯是變化較多的地方,其他的代碼可能是現實創建的用戶的姓名之類的。變成一個方法,然后將用戶類型定義為enum類型,減少調用者由于輸入錯誤導致程序錯誤。
代碼 using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
namespace?BeautyCode.DesignPattern.Head.First.Factory
{
????public?enum?UserType
????{
????????Admin,
????????Supervisor,
????????Common
????}
????public?abstract?class?User
????{
????????public?virtual?UserType?UserType
????????{
????????????get;
????????????protected?set;
????????}
????????public?User(UserType?userType)
????????{
????????????UserType?=?userType;
????????}
????????public?virtual?string?Username
????????{
????????????get;
????????????set;
????????}
????????public?virtual?int?Age
????????{
????????????get;
????????????set;
????????}
????????public?virtual?void?DisplayName()
????????{
????????????Console.WriteLine("my?name?is?{0},?i'm?{1}?years?old.",?Username,?Age);
????????}
????}
????public?class?AdminUser?:?User
????{
????????public?AdminUser()
????????????:?base(UserType.Admin)
????????{?}
????}
????public?class?CommonUser?:?User
????{
????????public?CommonUser()
????????????:?base(UserType.Common)
????????{?}
????}
????public?class?SupervisorUser?:?User
????{
????????public?SupervisorUser()
????????????:?base(UserType.Supervisor)
????????{
????????}
????}
}
?
代碼 using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
namespace?BeautyCode.DesignPattern.Head.First.Factory
{
???public??class?UserFactory
????{
???????public static?User?CreateSingleUser(UserType?userType)
???????{
???????????User?user?=?null;
???????????switch?(userType)
???????????{
???????????????case?UserType.Admin?:
???????????????????user?=?new?AdminUser();?
???????????????????break;
???????????????case?UserType.Common?:
???????????????????user?=?new?CommonUser();
???????????????????break;
???????????????case??UserType.Supervisor?:
???????????????????user?=?new?SupervisorUser();
???????????????????break;
???????????????default?:
???????????????????break;
???????????}
???????????return?user;
???????}
????}
}
?
調用代碼
?
Head.First.Factory.User?user?=?Head.First.Factory.UserFactory.CreateSingleUser(Head.First.Factory.UserType.Admin);?
以后增加新的用戶類型就不用在各處修改了,只要新建一個類型實體,然后打開工廠方法,修改一下就可以了。
有沒有更好的呢?
能否只是增加一個用戶類型實體類呢?
答案是:能
?
修改一下工廠方法,利用泛型和Activator
?public?static?T?CreateSingleUser2<T>()?where?T:User
???????{
???????????T?user?=?null;
???????????user?=?Activator.CreateInstance<T>();
???????????return?user;
???????}
?
調用者的代碼修改為
?Head.First.Factory.User?user1?=?Head.First.Factory.UserFactory.CreateSingleUser2<Head.First.Factory.AdminUser>();
?
有沒有更好的呢?
期待大家的參與討論!!!!
其實我這個還不算是真正意義上的工廠模式,頂多算是個簡單的工廠,后面我會補充一些更好的例子。
感謝大家耐心看完本篇博文。
定義
工廠模式:定義了一個創建對象的借口,但由子類決定要實例化的類是哪一個。工廠方法讓類把實例化推遲到了子類。
? 上面的描述中提到了“子類決定”的決定,希望不要錯誤理解,不是模式允許子類本身在運行的時候做決定,而是指在編寫創建者類的時候,不需要知道實際創建的類是哪一個。調用者選擇使用哪個類,自然就決定了實際創建的對象。
總結
以上是生活随笔為你收集整理的《深入浅出设计模式-中文版》读书笔记-工厂模式(五)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ajax使用总结
- 下一篇: 网站社区类产品管理经验