抽象工厂模式
问题场景
有100个方法对Animal类型进行了引用,所以可能需要new100次Animal对象,如果总是使用new创建对象,那么100处都会有对该对象的引用。假如今后Animal被禁止使用,而用另一个具有与Animal类似行为的XAnimal替代Animal,那么你需要在100处使用new创建Animal的地方将代码修改为XAnimal,而假如可以利用抽象将这些引用全部指向一个抽象的实现,比如Animal和XAnimal都从一个Biological的抽象类派生,再用一个专门制造抽象实现的工厂类来返回Biological抽象的实例,再创建一个专门制造XAnimal的工厂类和制造Animal的工厂类,这两个工厂类都从抽象工厂派生,那么今后需求改动时,只需要new一个创建XAnimal的工厂类来创建XAnimal和Animal的共同抽象返回给外部调用即可。
总结模式
工厂模式将所有对具象的引用更改成了对抽象的引用,要使用抽象工厂模式,那么所有的类型都应该从抽象派生,以便彻底解耦对具象类型的依赖。
示例代码
{
//动物的抽象
public abstract class Biological
{
public abstract void Say( );
}
//动物的具象
public class Animal : Biological
{
public override void Say( )
{
Console.WriteLine( "汪汪" );
}
}
//工厂的抽象
public abstract class Factory
{
//创建动物的抽象
public abstract Biological CreateBiological( );
}
//工厂的具象
public class AnimalFactory : Factory
{
//返回一个抽象的实体
public override Biological CreateBiological( )
{
return new Animal( );
}
}
public class Programe
{
static void Main( string[] args )
{
Factory factory = new AnimalFactory( ); //得到抽象工厂的实现,今后需要XAnimal时,只需要new出一个专门制造XAnimal的工厂类即可
Biological biological = factory.CreateBiological( ); //得到抽象动物的实现
biological.Say( );
}
}
}
在System.Data.dll中的System.Data.Common.DbProviderFactory抽象工厂就提供了一系列用于创建操作数据库抽象类的抽象方法
{
// 提供了创建具体产品的接口方法
protected DbProviderFactory( );
public virtual DbCommand CreateCommand( );
public virtual DbCommandBuilder CreateCommandBuilder( );
public virtual DbConnection CreateConnection( );
public virtual DbConnectionStringBuilder CreateConnectionStringBuilder( );
public virtual DbDataAdapter CreateDataAdapter( );
public virtual DbDataSourceEnumerator CreateDataSourceEnumerator( );
public virtual DbParameter CreateParameter( );
public virtual CodeAccessPermission CreatePermission( PermissionState state );
}
DbCommand、DbCommandBuilder 、DbConnection 、DbConnectionStringBuilder 、DbDataAdapter 等等都是抽象的类型,DbProviderFactory由SqlClientFactory实现,SqlClientFactory专门创建基于sql的数据库操作类。这样就解耦了对具象的引用,你也可以自定义OracleClientFactory、MySqlClientFactory工厂,实现创建对应的数据库操作类。
{
//通过静态的Instance字段获取一个SqlClientFactory实例,确保全局唯一
public static readonly SqlClientFactory Instance = new SqlClientFactory( );
// 重写抽象工厂中的方法
public override DbCommand CreateCommand( )
{
// 创建DbCommand的具象
return new SqlCommand( );
}
public override DbCommandBuilder CreateCommandBuilder( )
{
return new SqlCommandBuilder( );
}
public override DbConnection CreateConnection( )
{
return new SqlConnection( );
}
public override DbDataAdapter CreateDataAdapter( )
{
return new SqlDataAdapter( );
}
//……
}