博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工厂模式(Factory Pattern)
阅读量:5272 次
发布时间:2019-06-14

本文共 9464 字,大约阅读时间需要 31 分钟。

简介

1、工厂模式主要是为对象的创建提供一个统一的方法,工厂模式主要分为三类

  1. 简单工厂模式(Simple Factory) 
  2. 工厂方法模式(Factory Method) 
  3. 抽象工厂模式(Abstract Factory)

2、工厂模式的主要应用场景:

  1. 在编码是不能预见需要创建那种类的实例
  2. 系统不应依赖于产品类实例如何被创建、组合和表达的细节

 

简单工厂模式

  简单工厂模式又叫静态工厂,简单工厂模式:工厂是根据调用者传入的参数决定创建哪一种产品类的

简单工厂模式的4个角色

  1. 抽象产品:所有的产品必须实现这个共同的接口,这样一来,使用这些产品的类即可以引用这个抽象产品。而不是具体类(可以使用接口/和抽象类)
  2. 具体产品:基础或实现了抽象产品的类(调用者实际需要的对象)
  3. 工厂:负责生产具体产品,并以其父类的方式返回
  4. 调用者

 简单工厂模式实例:

1   ///  2     /// 简单工厂 3     ///  4     class SimpleFactory 5     { 6         ///  7         /// 通过参数获取 IProduct 接口 的实例 8         ///  9         /// 类型参数10         /// 
11 public static IProduct GetProductInstance(string paramType)12 {13 IProduct instance;14 switch (paramType)15 {16 case "a": instance = new ProductA();17 break;18 case "b": instance = new ProductB();19 break;20 default: throw new ArgumentOutOfRangeException("paramType", "ProductFactory中未定义" + paramType);21 }22 return instance;23 }24 }25 26 /// 27 /// 抽象产品基类28 /// 29 interface IProduct30 {31 string Name { get; }32 void ShowName();33 }34 35 /// 36 /// 产品类A37 /// 38 class ProductA : IProduct39 {40 public string Name41 {42 get43 {44 return "a";45 }46 }47 48 public void ShowName()49 {50 {51 Console.Write("My name is " + Name);52 }53 }54 }55 56 /// 57 /// 产品类B58 /// 59 class ProductB : IProduct60 {61 public string Name62 {63 get64 {65 return "b";66 }67 }68 69 public void ShowName()70 {71 {72 Console.Write("My name is " + Name);73 }74 }75 }
View Code

 

 工厂方法模式

  工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让实例化推迟到子类。

工厂方法模式有5个角色

  1. 抽象产品:所有的产品必须实现这个共同的接口,这样一来,使用这些产品的类即可以引用这个抽象产品。而不是具体类(可以使用接口/和抽象类)
  2. 具体产品:基础或实现了抽象产品的类(调用者实际需要的对象)
  3. 抽象工厂:制造产品的实际工厂。它负责创建一个或者多个具体产品,只有具体工厂知道如何创建这些具体产品。
  4. 具体工厂:负责生产具体产品,并以其父类的方式返回
  5. 调用者

工厂方法模式实例

1     ///   2     /// 抽象工厂类  3     ///   4     interface IFactory  5     {  6         ///   7         /// 通过参数获取 IProduct 接口 的实例  8         ///   9         /// 类型参数 10         /// 
11 IProduct GetProductInstance(string paramType); 12 } 13 14 /// 15 /// 具体工厂A 16 /// 17 class FactoryA : IFactory 18 { 19 public IProduct GetProductInstance(string paramType) 20 { 21 IProduct instance; 22 switch (paramType) 23 { 24 case "a1": instance = new ProductA1(); 25 break; 26 case "a2": instance = new ProductA2(); 27 break; 28 default: throw new ArgumentOutOfRangeException("paramType", "FactoryB中未定义" + paramType); 29 } 30 return instance; 31 } 32 } 33 34 /// 35 /// 具体工厂B 36 /// 37 class FactoryB : IFactory 38 { 39 public IProduct GetProductInstance(string paramType) 40 { 41 IProduct instance; 42 switch (paramType) 43 { 44 case "b1": instance = new ProductB1(); 45 break; 46 case "b2": instance = new ProductB2(); 47 break; 48 default: throw new ArgumentOutOfRangeException("paramType", "FactoryB中未定义" + paramType); 49 } 50 return instance; 51 } 52 } 53 54 55 56 /// 57 /// 抽象产品基类 58 /// 59 interface IProduct 60 { 61 string Name { get; } 62 void ShowName(); 63 } 64 65 /// 66 /// 产品类A1 67 /// 68 class ProductA1 : IProduct 69 { 70 public string Name 71 { 72 get 73 { 74 return "a1"; 75 } 76 } 77 78 public void ShowName() 79 { 80 { 81 Console.Write("My name is " + Name); 82 } 83 } 84 } 85 /// 86 /// 产品类A2 87 /// 88 class ProductA2 : IProduct 89 { 90 public string Name 91 { 92 get 93 { 94 return "a2"; 95 } 96 } 97 98 public void ShowName() 99 {100 {101 Console.Write("My name is " + Name);102 }103 }104 }105 106 /// 107 /// 产品类B1108 /// 109 class ProductB1 : IProduct110 {111 public string Name112 {113 get114 {115 return "b1";116 }117 }118 119 public void ShowName()120 {121 {122 Console.Write("My name is " + Name);123 }124 }125 }126 127 /// 128 /// 产品类B2129 /// 130 class ProductB2 : IProduct131 {132 public string Name133 {134 get135 {136 return "b2";137 }138 }139 140 public void ShowName()141 {142 {143 Console.Write("My name is " + Name);144 }145 }146 }
View Code

 

抽象工厂模式

给客户端提供一个接口,可以创建多个产品族中的产品对象。而且使用抽象工厂模式还要满足一下条件

  1. 系统中有多个产品族,而系统一次只可能消费其中一族产品
  2. 同属于同一个产品族的产品一起使用时

产品族:位于不同产品等级结构中,功能相关联的产品组成的家族, 如下示例中:SqlConnection,SqlCommand,SqlParameter 就属于同一个产品族

抽象工厂模式的5角色(与工厂方法的角色差不多):

  1. 抽象产品:所有的产品必须实现这个共同的接口,这样一来,使用这些产品的类即可以引用这个抽象产品。而不是具体类(可以使用接口/和抽象类)
  2. 具体产品:基础或实现了抽象产品的类(调用者实际需要的对象)
  3. 抽象工厂:制造产品的实际工厂。它负责创建一个或者多个具体产品,只有具体工厂知道如何创建这些具体产品。
  4. 具体工厂:负责生产产品族中成员的具体产品,并以其父类的方式返回
  5. 调用者

抽象工厂模式实例:使用的是System.Data.Common.DbProviderFactory 微软提供的跨数据库查询抽象工厂

1 //抽象工厂, 这个是ado.net 的源码  2 namespace System.Data.Common  3 {  4     public abstract class DbProviderFactory  5     {  6         public virtual bool CanCreateDataSourceEnumerator  7         {  8             get  9             { 10             } 11         } 12  13         public virtual DbCommand CreateCommand() 14         { 15         } 16  17         public virtual DbCommandBuilder CreateCommandBuilder() 18         { 19         } 20  21         public virtual DbConnection CreateConnection() 22         { 23         } 24  25         public virtual DbConnectionStringBuilder CreateConnectionStringBuilder() 26         { 27         } 28  29         public virtual DbDataAdapter CreateDataAdapter() 30         { 31         } 32  33         public virtual DbParameter CreateParameter() 34         { 35         } 36  37         public virtual CodeAccessPermission CreatePermission(PermissionState state) 38         { 39         } 40  41         public virtual DbDataSourceEnumerator CreateDataSourceEnumerator() 42         { 43         } 44     } 45 } 46  47   48 ///  49     /// MSSQL 的 具体工厂 50     ///  51     public class MSSQLDbProviderFactory : System.Data.Common.DbProviderFactory 52     { 53         static readonly string sqlConn = "数据库连接字符串"; 54  55         public override DbConnection CreateConnection() 56         { 57             return new SqlConnection(sqlConn); 58         } 59  60         public override DbCommand CreateCommand() 61         { 62             return new SqlCommand(); 63         } 64  65         public override DbParameter CreateParameter() 66         { 67             return new SqlParameter(); 68         } 69     } 70  71 //Globol 中 初始化 72     public class MvcApplication : System.Web.HttpApplication 73     { 74         public static System.Data.Common.DbProviderFactory ProviderFactory; 75         protected void Application_Start() 76         { 77             // 实例化 ProviderFactory 为MSSQL 数据库的 78             // 如果未来我们是用MYSQL数据库 那么就可以只要修改一下 这个变量的初始化为MYSQLDbProviderFactory 那么这个系统就切换到了MYSQL了(不考虑SQL兼用性的情况下--) 79             ProviderFactory = new Models.MSSQLDbProviderFactory(); 80  81             AreaRegistration.RegisterAllAreas(); 82             RouteConfig.RegisterRoutes(RouteTable.Routes); 83         } 84     } 85  86 // 使用 87  88             // 传统方式访问数据库 89             using (var conn = new SqlConnection("")) 90             { 91                 var cmd = new SqlCommand(); 92                 cmd.CommandText = "SELETE * FROM Table"; 93                 cmd.Connection = conn; 94                 var read = cmd.ExecuteReader(); 95                 while (read.Read()) 96                 { 97                     Console.Write(read.GetString(1)); 98                 } 99             }100 101             // 在查询中使用到的SQL对象全部依赖抽象工厂来创建102             using (var conn = MvcApplication.ProviderFactory.CreateConnection())103             {104                 var cmd =  MvcApplication.ProviderFactory.CreateCommand();105                 cmd.CommandText = "SELETE * FROM Table";106                 cmd.Connection = conn;107                 var read = cmd.ExecuteReader();108                 while (read.Read())109                 {110                     Console.Write(read.GetString(1));111                 }112             }
View Code

 

简单工厂模式:

只有一个工厂类,工厂类可以创建一个抽象产品类的所以具体产品实例

 

工厂方法模式:

一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建同一个抽象产品类的具体产品实例。

 

抽象工厂模式:

多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个抽象产品类的具体产品类实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

转载于:https://www.cnblogs.com/mirck/p/5326196.html

你可能感兴趣的文章
Leetcode Balanced Binary Tree
查看>>
[JS]递归对象或数组
查看>>
linux sed命令
查看>>
湖南多校对抗赛(2015.03.28) H SG Value
查看>>
hdu1255扫描线计算覆盖两次面积
查看>>
hdu1565 用搜索代替枚举找可能状态或者轮廓线解(较优),参考poj2411
查看>>
程序存储问题
查看>>
优雅地书写回调——Promise
查看>>
AX 2009 Grid控件下多选行
查看>>
PHP的配置
查看>>
Struts框架----进度1
查看>>
Round B APAC Test 2017
查看>>
MySQL 字符编码问题详细解释
查看>>
Ubuntu下面安装eclipse for c++
查看>>
Windows 2003全面优化
查看>>
格而知之2:UIView的autoresizingMask属性探究
查看>>
我的Hook学习笔记
查看>>
js中的try/catch
查看>>
寄Android开发Gradle你需要知道的知识
查看>>
整理推荐的CSS属性书写顺序
查看>>