• 定义:

1.) 工厂方法模式是用来封装对象的创建,通过让子类来决定创建的对象是什么,来达到将对象创建的过程封装的目的;

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

  • 适用场景:

代码中经常会出现:根据条件创建实现了同一个接口的不用类实例,而这些判定条件可能随时变动,导致我们这个不得不去改动很多代码。

备注:简单工厂在Head First中,被认为不是设计模式的一种,但人们经常使用,大家习惯性的叫,久了也就言传为“工厂方法模式”。

  • 简单工厂方法
  • 解决了什么问题

例如:

string dbName=string.Empty;
            dbName="Access";
            MemberDaoBase memberDao=null;
            
            if(dbName.ToUpper()=="ACCESS"){
                memberDao=new Access.MemberDao();
            }
            else if(dbName.ToUpper()=="SQLSERVER")
            {
                memberDao=new SqlServer.MemberDao();
            }
            memberDao.Create(new Member());
            memberDao.Modify(new Member());
            memberDao.Remove(0);
            

如果代码中不再变动还好,但这种情况很多时候是不存在的,当来了一个新的领导,领导说Sqlite的性能好且免费,那你就不得不去重新去写一个Sqlite.MemberDao,之后再在这里的判断条件中添加上

1 else if(dbName.ToUpper()=="SQLITE")
2 {
3       memberDao=new SqlServer.SqliteDao();
4 }

当某天另外一个领导说我们不再支持SqlServer了,我们就不得不把else if(dbName.ToUpper()=="SQLSERVER") {...} 这块代码给注释了。我们就痛苦在这种“变动”中。

问题分析:

不稳定部分:

 1 string dbName=string.Empty;
 2             dbName="Access";
 3             MemberDaoBase memberDao=null;
 4             
 5             if(dbName.ToUpper()=="ACCESS"){
 6                 memberDao=new Access.MemberDao();
 7             }
 8             else if(dbName.ToUpper()=="SQLSERVER")
 9             {
10                 memberDao=new SqlServer.MemberDao();
11             }

稳定部分: 

1 memberDao.Create(new Member());
2 
3 memberDao.Modify(new Member());
4 
5 memberDao.Remove(0);

如果我们将不稳定的部分给交给两外一个类单独管理,就能把这种耦合变得低一点,当我们需要“变动”时,只用去修改这个管理类;而这管理来是用来new 实例的,我们习惯。

  • “new管理类(简单工厂方法核心类)”:
 1 /// <summary>
 2     /// Description of MemberDaoFactory.
 3     /// </summary>
 4     public class MemberDaoFactory
 5     {        
 6         public MemberDaoBase Create(string dbName)
 7         {    
 8             if(dbName.ToUpper()=="ACCESS")
 9             {
10                 Console.WriteLine("new Access.MemberDao()");
11                 return new Access.MemberDao();
12             }
13             else if(dbName.ToUpper()=="SQLSERVER")
14             {
15                 Console.WriteLine("new SqlServer.MemberDao()");
16                 return new SqlServer.MemberDao();
17             }
18             else
19             {
20                 throw new NotSupportedException(string.Format("Not supported {0}",dbName));
21             }
22         }
23     }

 

  • 按照简单工厂方法的定义调整

代码结构图:

设计模式(二)(Factory method)工厂方法设计模式

Member.cs

 1 /// <summary>
 2     /// Description of Member.
 3     /// </summary>
 4     public class Member
 5     {    
 6         private int id;
 7         private string name;
 8         
 9         public Member()
10         {
11         }
12             
13         public int Id 
14         {
15             get { return id; }
16             set{id=value;}
17         }
18         
19         public string Name 
20         {
21             get { return name; }
22             set { name = value; }
23         }
24     }
View Code

相关文章: