C#设计模式之:抽象工厂模式与反射
抽象工厂模式【实例】:
定义一个用于创建对象的接口,让子类决定实例化哪一个类
UML
代码
class User
{
private int _id;
public int Id { get => _id; set => _id = value; }
private string _name;
public string Name { get => _name; set => _name = value; }
}
interface IUser
{
void Insert(User user);
User GetUser(int id);
}
class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在SQL Server中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
class SqlServerFactory : IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
}
class AccessUser : IUser
{
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
}
}
class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
}
// test
User user = new User();
//IFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
// result
在Access中给User表增加一条记录
在Access中根据ID得到User表一条记录
抽象工厂模式(Abstract Factory)
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
UML
代码
class Department
{
private string name;
private string id;
public string Name { get => name; set => name = value; }
public string Id { get => id; set => id = value; }
}
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在SQL Server中给Department表增加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
return null;
}
}
class AccessDepartment : IDepartment
{
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Department表一条记录");
return null;
}
public void Insert(Department department)
{
Console.WriteLine("在Access中给Department表增加一条记录");
}
}
class SqlServerFactory : IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
}
class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}
// test
User user = new User();
Department dept = new Department();
//IFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
IDepartment id = factory.CreateDepartment();
id.Insert(dept);
id.GetDepartment(1);
// result
在Access中给User表增加一条记录
在Access中根据ID得到User表一条记录
在Access中给Department表增加一条记录
在Access中根据ID得到Department表一条记录
IFactory 就是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法
通常在运行时再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说为创建不同的产品对象,客户商应使用不同的具体工厂
优点
便于交换系列产品,由于具体工厂类,在一个应用中只需要在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,它只要改变具体工厂即可使用不同的产品配置
它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体的工厂实现分离,不会出现在客户代码中
缺陷
1,添加新的表,要更改多个工厂类
2,程序中有多个地方使用了
IFactory factory = new AccessFactory();
1
现在换个数据库
IFactory factory = new SqlServerFactory();
1
你也要更改多个地方
总结:
简单工厂模式:管理对象类 调用接口
抽象工厂模式:接口实现类 调用接口
用简单工厂改进其缺陷
去除IFactory、SqlServerFactory和AccessFactory三个工厂类
使用DataAccess类取代它们
UML
代码
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 "Access":
result = new AccessUser();
break;
}
return result;
}
public static IDepartment CreateDepartment()
{
IDepartment result = null;
switch (db)
{
case "SqlServer":
result = new SqlserverDepartment();
break;
case "Access":
result = new AccessDepartment();
break;
}
return result;
}
}
// test
User user = new User();
IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(1);
Department dept = new Department();
IDepartment id = DataAccess.CreateDepartment();
id.Insert(dept);
id.GetDepartment(1);
// result
在SQL Server中给User表增加一条记录
在SQL Server中根据ID得到User表一条记录
在SQL Server中给Department表增加一条记录
在SQL Server中根据ID得到Department表一条记录
这里使用了简单工厂的方法来解决了上面的缺陷,但同时又产生了新的问题(switch问题)
如果要新增Oracle数据库,抽象工厂本来只要增加一个OracleFactory工厂即可,这里简单工厂要修改switch增加case
.NET中的依赖注入( Dependency Injection)
using System.Reflection;
Assembly.Load("程序集名称").CreateInstance("命名空间.类的名称");
// 常规写法
IUser result = new SqlServerUser();
// 反射写法
using System.Reflection;
IUser result = (IUser)Assembly.Load("抽象工厂模式").CreateInstance("抽象工厂模式.SqlServerUser");
使用反射的具体代码
using System.Reflection;
class DataAccess
{
private static readonly string AssemblyName = "PatternTest";
private static readonly string db = "AbstractPattern.Sqlserver";
// private static readonly string db = "AbstractPattern.Access";
public static IUser CreateUser()
{
string className = AssemblyName + "." + db + "User";
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
}
public static IDepartment CreateDepartment()
{
string className = AssemblyName + "." + db + "Department";
return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
}
}
上述代码同样得到了结果
如果我们增加了Oracle数据访问,相关的类的增加是不可避免的,不过这叫扩展,开闭原则告诉我们对于扩展开放,对于修改关闭
我们只要修改db字符串变量的值为
// private static readonly string db = "AbstractPattern.Oracle";
1
每次更换数据库时还是要修改程序修改db值重编译,如果可以不修改程序,才是真正的开放-封闭原则
解决方案:使用配置文件
转载于:https://www.cnblogs.com/lvjy-net/p/10430762.html
C#设计模式之:抽象工厂模式与反射相关推荐
- 设计模式之四(抽象工厂模式第三回合)
原文:设计模式之四(抽象工厂模式第三回合) 前言 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 抽象工厂模式最大的好处便是易于交换产品系列,由于具体工厂类,例如I ...
- 设计模式系列·抽象工厂模式
前言 以小说的笔法写的设计模式系列文章,你绝对看得懂![首发于公众号:"聊聊代码"] 设计模式系列·王小二需求历险记(一) 设计模式系列·王小二需求历险记(二) 设计模式系列·封装 ...
- 设计模式三—抽象工厂模式
设计模式三-抽象工厂模式 一.定义 抽象工厂模式是工厂方法模式的进一步抽象.如果产品簇中只有一种产品,则退化为工厂方法模式. 二.原理图 三.代码实例 * 苹果和土豆是园丁1的杰作 * 葡萄和西红柿是 ...
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Facto ...
- 设计模式复习-抽象工厂模式
设计模式复习-抽象工厂模式 有两种硬件,PC和Phone,有两种系统,Windows和Linux,现在假设PC和Phone上全都能安装这两个系统,并且将来硬件不会在变化,但是系统可能需要扩展,比如扩展 ...
- python抽象工厂模式_Python设计模式之抽象工厂模式
Python设计模式之抽象工厂模式 这篇文章主要为大家详细介绍了Python设计模式之抽象工厂模式,感兴趣的小伙伴们可以参考一下 python面向对象编程入门,我们需要不断学习进步 "&qu ...
- 设计模式-04抽象工厂模式
设计模式-04抽象工厂模式 文章中涉及到的代码,请自行下载 https://gitee.com/pan_xiao_lei123/designmode.git 前面介绍的工厂方法模式中考虑的是一类产品的 ...
- C#设计模式(4)——抽象工厂模式
C#设计模式(4)--抽象工厂模式 一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法 ...
- 抽象工厂模式(JAVA反射)
实例代码(JAVA):模式动机 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法.但是 ...
最新文章
- c++无穷大怎么表示_压缩机接线柱烧坏怎么处理?
- JQuery dataTable 扩展+Ajax Post,Get一些基本操作(一)
- [[HOW TO]-ubuntu20.10安装openjrok指南
- php验证旧密码,PHP验证数据库密码问题
- HDU 1517 A Multiplication Game
- Python 基础篇:介绍
- Pokemon Go火了,他却要破产了...
- 一个简单词法分析器的实现代码(java实现)
- 在SAP云平台上部署和运行Docker应用
- centos yum安装nginx 提示 No package nginx available问题解决方法
- python程序设计实验七_Python程序设计实验报告七:组合数据类型
- 如何在 Linux 中使用 AppImage
- Django的rest_framework的视图之Mixin类编写视图源码解析...
- 转载windows的网络错误问题,备需要时查看
- validate.js的使用
- c语言游戏小型程序代码,C语言小游戏源码
- python算法基础教程_python算法教程pdf下载
- MATLAB求解线性规划(含整数规划和0-1规划)问题
- 【数理统计】单因素方差分析
- java推送微信消息换行_微信公众平台开发教程之文本消息如何换行(第十二课)
热门文章
- 10个优秀的 Web UI库/框架 详细出处参考:http://www.jb51.net/web/22251.html
- 国务院办公厅关于2022年部分节假日安排的通知
- 国家卫健委:我国男女性成人平均身高分别为169.7厘米和158厘米
- NLP技术路线详解:这是从数学到算法的艺术
- Redis三种特殊类型
- js如何写html中的内容,javascript怎样获取某个标签的内容?
- 双精度数举例_Aladdin阿拉丁:一套土木工程结构无损检测领域先进的双极化天线阵雷达...
- redis是单线程的吗?为什么执行速度这么快?
- 092_元素的几种宽度和高度
- 023_JavaScript数字方法