关于工厂模式和单例模式 大部分项目这2种模式都很常见
例如在orm框架中 工厂模式常用来封装数据库的创建 我们分3种case来看 简单工厂模式 普通工厂模式 抽象工厂模式
抽象一点的说 工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。直接看实例
一般惯性思维 我们遇到分支判断时会这样
public class NormalCase
{
private DBInstance dbInstance;
public NormalCase(string type)
{
if (type.Equals("SQL"))
{
dbInstance= new SqlInstance();
}
else if (type.Equals("Oracle"))
{
dbInstance = new OracleInstance();
}
else if (type.Equals("Mysql"))
{
dbInstance = new MysqlInstance();
}
}
public void ExecuteNonQuery()
{
this.dbInstance.ExecuteNonQuery();
}
public void ExecuteDataset()
{
this.dbInstance.ExecuteDataset();
}
}
{
private DBInstance dbInstance;
public NormalCase(string type)
{
if (type.Equals("SQL"))
{
dbInstance= new SqlInstance();
}
else if (type.Equals("Oracle"))
{
dbInstance = new OracleInstance();
}
else if (type.Equals("Mysql"))
{
dbInstance = new MysqlInstance();
}
}
public void ExecuteNonQuery()
{
this.dbInstance.ExecuteNonQuery();
}
public void ExecuteDataset()
{
this.dbInstance.ExecuteDataset();
}
}
那么 new有什么不好,在技术上new没什么错,但是好的设计针对扩展开放而对修改关闭。
针对接口编程,可以隔离掉以后系统可能发生的一大堆改变。如果代码是针对接口编写,那么通过多态,它可以与任何新类实现该接口。
下面让我们看看工厂模式如何解决该问题
先来看看简单工厂
public class SimpleFactory
{
public DBInstance createinstance(string type)
{
DBInstance di = null;
if (type.Equals("SQL"))
{
return new SqlInstance();
}
else if (type.Equals("Oracle"))
{
return new OracleInstance();
}
else if (type.Equals("Mysql"))
{
return new MysqlInstance();
}
return di;
}
}
public class SimpleCase
{
SimpleFactory facotory;
DBInstance di;
public SimpleCase(SimpleFactory facotory)
{
this.facotory = facotory;
}
public DBInstance CreateInstance(string type)
{
di = facotory.createinstance(type);
return di;
}
public void ExecuteNonQuery()
{
this.di.ExecuteNonQuery();
}
public void ExecuteDataset()
{
this.di.ExecuteDataset();
}
}
{
public DBInstance createinstance(string type)
{
DBInstance di = null;
if (type.Equals("SQL"))
{
return new SqlInstance();
}
else if (type.Equals("Oracle"))
{
return new OracleInstance();
}
else if (type.Equals("Mysql"))
{
return new MysqlInstance();
}
return di;
}
}
public class SimpleCase
{
SimpleFactory facotory;
DBInstance di;
public SimpleCase(SimpleFactory facotory)
{
this.facotory = facotory;
}
public DBInstance CreateInstance(string type)
{
di = facotory.createinstance(type);
return di;
}
public void ExecuteNonQuery()
{
this.di.ExecuteNonQuery();
}
public void ExecuteDataset()
{
this.di.ExecuteDataset();
}
}
准确来说,简单工厂并不是一种设计模式,反而比较像是一种编程习惯。上述case只是把问题从一个对象搬到另一个对象中,问题依然存在。但是SimpleFactory可以有许多客户,把创建实例的代码包装进一个类,当以后实现改变时,只需修改这个类就可以了。物品们也正要把具体实例化的过程从客户的代码中删除。
下面我就来介绍下两个重量级的模式!
工厂方法模式
public abstract class facotoryCase
{
DBInstance di;
public DBInstance CreateInstance(string type)
{
di = create(type);
return di;
}
public abstract DBInstance create(string type);
public void ExecuteNonQuery()
{
this.di.ExecuteNonQuery();
}
public void ExecuteDataset()
{
this.di.ExecuteDataset();
}
}
public class facotoryCaseA : facotoryCase
{
public override DBInstance create(string type)
{
if (type.Equals("SQL"))
{
return new SqlInstance();
}
else if (type.Equals("Oracle"))
{
return new OracleInstance();
}
return null;
}
}
public class facotoryCaseB : facotoryCase
{
public override DBInstance create(string type)
{
if (type.Equals("Mysql"))
{
return new MysqlInstance();
}
return null;
}
}
{
DBInstance di;
public DBInstance CreateInstance(string type)
{
di = create(type);
return di;
}
public abstract DBInstance create(string type);
public void ExecuteNonQuery()
{
this.di.ExecuteNonQuery();
}
public void ExecuteDataset()
{
this.di.ExecuteDataset();
}
}
public class facotoryCaseA : facotoryCase
{
public override DBInstance create(string type)
{
if (type.Equals("SQL"))
{
return new SqlInstance();
}
else if (type.Equals("Oracle"))
{
return new OracleInstance();
}
return null;
}
}
public class facotoryCaseB : facotoryCase
{
public override DBInstance create(string type)
{
if (type.Equals("Mysql"))
{
return new MysqlInstance();
}
return null;
}
}
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
设计原则:要依赖抽象不要依赖具体类。
接下来再看下抽象工厂模式
public class Param { }
public class sqlparm : Param { }
public class oracleparam : Param { }
public class connection { }
public class sqlconnecttion : connection { }
public class oracleconnecttion : connection { }
public interface abstractCase
{
Param GetParameter();
connection GetConnection();
}
public abstract class DBInstanceforabstract
{
public Param p;
public connection c;
public abstract void ExecuteNonQuery();
public abstract void ExecuteDataset();
}
public class DBInstanceforabstractA : DBInstanceforabstract
{
abstractCase ac;
public DBInstanceforabstractA(abstractCase ac)
{
this.ac = ac;
}
public override void ExecuteNonQuery()
{
p = ac.GetParameter();
}
public override void ExecuteDataset()
{
c = ac.GetConnection();
}
}
public class abstractCaseA : abstractCase
{
DBInstanceforabstract di;
public Param GetParameter()
{
return new sqlparm();
}
public connection GetConnection()
{
return new sqlconnecttion();
}
}
public class abstractCaseB : abstractCase
{
DBInstanceforabstract di;
public Param GetParameter()
{
return new oracleparam();
}
public connection GetConnection()
{
return new oracleconnecttion();
}
}
public class sqlparm : Param { }
public class oracleparam : Param { }
public class connection { }
public class sqlconnecttion : connection { }
public class oracleconnecttion : connection { }
public interface abstractCase
{
Param GetParameter();
connection GetConnection();
}
public abstract class DBInstanceforabstract
{
public Param p;
public connection c;
public abstract void ExecuteNonQuery();
public abstract void ExecuteDataset();
}
public class DBInstanceforabstractA : DBInstanceforabstract
{
abstractCase ac;
public DBInstanceforabstractA(abstractCase ac)
{
this.ac = ac;
}
public override void ExecuteNonQuery()
{
p = ac.GetParameter();
}
public override void ExecuteDataset()
{
c = ac.GetConnection();
}
}
public class abstractCaseA : abstractCase
{
DBInstanceforabstract di;
public Param GetParameter()
{
return new sqlparm();
}
public connection GetConnection()
{
return new sqlconnecttion();
}
}
public class abstractCaseB : abstractCase
{
DBInstanceforabstract di;
public Param GetParameter()
{
return new oracleparam();
}
public connection GetConnection()
{
return new oracleconnecttion();
}
}
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族而不需要明确指定具体类。