《深入浅出设计模式-中文版》读书笔记-工厂模式(五)
今天给大家带来的是:工厂模式。
我们在代码中创建一个对象,我们会很自然的想到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;
}
调用者的代码修改为
有没有更好的呢?
期待大家的参与讨论!!!!
其实我这个还不算是真正意义上的工厂模式,顶多算是个简单的工厂,后面我会补充一些更好的例子。
感谢大家耐心看完本篇博文。
定义
工厂模式:定义了一个创建对象的借口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到了子类。
上面的描述中提到了“子类决定”的决定,希望不要错误理解,不是模式允许子类本身在运行的时候做决定,而是指在编写创建者类的时候,不需要知道实际创建的类是哪一个。调用者选择使用哪个类,自然就决定了实际创建的对象。
《深入浅出设计模式-中文版》读书笔记-工厂模式(五)相关推荐
- 《Head First 设计模式》读书笔记——工厂模式
今天是第几天我也忘了,反正就是继续写.前几天的还需要完善,今天力求完整! 奠定基调的例子 作为一名披萨店店主,我们需要售卖不同种类的披萨,所以就需要设计很多披萨的类型,并且需要增加一下代码来确定顾客需 ...
- 《深入浅出DPDK》读书笔记(十五):DPDK应用篇(Open vSwitch(OVS)中的DPDK性能加速)
Table of Contents Open vSwitch(OVS)中的DPDK性能加速 174.虚拟交换机简介 175.OVS简介 176.DPDK加速的OVS 177.OVS的数据通路 178. ...
- 《大话设计模式》读书笔记-建造者模式
// 建造者类 class PersonDirector { private PersonBuilder pb; public PersonDirector(Perso ...
- 《Head First 设计模式》读书笔记——迭代器模式
让客户遍历我们的数组.堆栈.列表或者散列表时,无法知道我们存储对象的方式,就靠今天的迭代器模式了. 案例 我们有两个餐饮店要合并经营,他们的菜品有共同的地方,所以我们这两个商店类需要一个共同的菜单属性 ...
- 《Head First 设计模式》读书笔记——组合模式
承接上篇博客,我们需要修改所有的菜单,以满足可以添加子菜单,但是我们由于已经把整个项目的框架搭好了,不可能重新实现菜单,所以我们只能修改,那么我们需要做些什么呢? 树形结构,可以容纳菜单.子菜单和菜单 ...
- 《Head First 设计模式》读书笔记——模板方法模式
模板方法模式. 案例 泡茶和冲咖啡的步骤很相似,咖啡的步骤: 把水煮沸 用沸水冲泡咖啡 把咖啡倒进杯子里 加糖和牛奶 泡茶的步骤: 把水煮沸 用沸水浸泡茶叶 把茶倒进杯子 加柠檬 所以咖啡的代码如下: ...
- 《深入浅出DPDK》读书笔记(十六):DPDK应用篇(基于DPDK的存储软件优化:SPDK)
Table of Contents 基于DPDK的存储软件优化 180.基于以太网的存储系统 181.以太网存储系统的优化 SPDK介绍 182.SPDK介绍 (1)兼容性 (2)性能 183.用户态 ...
- 《深入浅出DPDK》读书笔记(八):网卡性能优化(异步中断模式、轮询模式、混和中断轮询模式)
本文内容为读书笔记,摘自<深入浅出DPDK> 82.DPDK的轮询模式 <DPDK PMD( Poll Mode Driver)轮询模式驱动程序> DPDK采用了轮询或者轮询混 ...
- 《Head First设计模式》 读书笔记16 其余的模式(二) 蝇量 解释器 中介者
<Head First设计模式> 读书笔记16 其余的模式(二) 蝇量 解释器 中介者 蝇量(Flyweight Pattern) 如想让某个类的一个实例能用来提供许多"虚拟实例 ...
最新文章
- 运维需要掌握的基础知识
- ⑨①-成功者的路永远都是相通的
- PHP保存Base64图片的问题
- 神经网络 | BP神经网络介绍(附源代码:BP神经网络-异或问题)
- 字符串大小写字母转换c 语言,towlower()
- 前端学习(2758):view基本使用
- php js登录,php+js实现单点登录
- loadrunner录制回放常见问题及解决办法
- 前端开发经验:当初我是如何学习JavaScript
- 计算机程序员能做多久,这个行业有年龄限制吗?
- python3入门经典100例-Python3入门机器学习_经典算法与应用-慕课网实战
- ubuntu系统各pdf编辑器的使用体验和比较
- manjaro linux vmware,Manjaro Linux处理vmware的vmmon、vmnet8、Network configuration is missing一堆问题的记录...
- GSON处理URL转码
- 计算机图形学实验体会,计算机图形学实验报告.doc
- 项目时间和本地时间差8小时的问题
- 攻略 | 一文教你学会使用GitHub!(附视频)
- 浅谈Google分布式文件系统(GFS)
- 弹性布局(Flex布局)
- 个人博客系列【Hexo】——git 使用ssh协议免密登录
热门文章
- 【像程序员一样思考】 读书笔记2
- npm package.json文件解读
- Bootstrap入门(三十)JS插件7:警告框
- linux: convmv =-======pkgs.org
- Ubuntu的which、whereis、locate和find命令
- 使用GLSL实现雾化的效果
- 让FFMPEG支持实时流“伴随”转码
- Android的沉浸式状态栏与变色状态栏详解
- 基于 Bitbucket Pipeline + Amazon S3 的自动化运维体系
- JSTL中fmt标签详解