《深入浅出设计模式-中文版》读书笔记-工厂模式(五)
2010-07-16 12:46 Virus-BeautyCode 阅读(3088) 评论(9) 编辑 收藏 举报今天给大家带来的是:工厂模式。
我们在代码中创建一个对象,我们会很自然的想到new。其实,除了new意外,我们还有很多的方式可以创建对象。不说复杂的模式,就说简单的语法,其实.NET框架中还有下面的方法。根据需要创建的对象的类型,动态创建对象。
通过前面我们已经讲过一条原则:
针对接口编程,不针对实现编程。
使用new创建对象很明显就是一个针对实现编程,new后面需要一个具体的类,不允许你new一个接口或者是抽象类。包括用Activator.CreateInstance都不能创建接口或者抽象类。
那是不是就是说以后不能或者是不要再用new了,都用其他方式吗?
也不是的,也要根据情况来分析,不是一概而论的,在后面会给出一些简单的标准,更多的要结合具体的设计定夺。
很多时候我们会碰到下面的代码:

if (userType == "admin")
{//创建管理员
}
else if (userType == "supervisor")
{//创建超级管理员
}
else if (userType == "coommon")
{
//创建普通用户
}
如果以后增加了用户的类型,不仅要创建用户类型实体,还需要打开创建用户的这段代码,后面加上一个if。。。else。。。。
如果这段代码没有封装,就更麻烦了,散落在项目的各处,每个地方都要打开,ctrl+c,ctrl+v。开始了无尽的噩梦。
对于后面的维护成了问题,而且违反了一条原则:
OCP原则,对增加开放,对修改封闭。
首先使用封装变化原则对这段代码做一些抽象,上面这段明显是变化较多的地方,其他的代码可能是现实创建的用户的姓名之类的。变成一个方法,然后将用户类型定义为enum类型,减少调用者由于输入错误导致程序错误。

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.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;
}
}
}
调用代码
以后增加新的用户类型就不用在各处修改了,只要新建一个类型实体,然后打开工厂方法,修改一下就可以了。
有没有更好的呢?
能否只是增加一个用户类型实体类呢?
答案是:能
修改一下工厂方法,利用泛型和Activator
{
T user = null;
user = Activator.CreateInstance<T>();
return user;
}
调用者的代码修改为
有没有更好的呢?
期待大家的参与讨论!!!!
其实我这个还不算是真正意义上的工厂模式,顶多算是个简单的工厂,后面我会补充一些更好的例子。
感谢大家耐心看完本篇博文。
定义
工厂模式:定义了一个创建对象的借口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到了子类。
上面的描述中提到了“子类决定”的决定,希望不要错误理解,不是模式允许子类本身在运行的时候做决定,而是指在编写创建者类的时候,不需要知道实际创建的类是哪一个。调用者选择使用哪个类,自然就决定了实际创建的对象。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构