当前位置: 移动技术网 > IT编程>开发语言>c# > 详解C#的设计模式编程之抽象工厂模式的应用

详解C#的设计模式编程之抽象工厂模式的应用

2019年07月18日  | 移动技术网IT编程  | 我要评论
这里首先以一个生活中抽象工厂的例子来实现一个抽象工厂,然后再给出抽象工厂的定义和uml图来帮助大家更好地掌握抽象工厂模式,同时大家在理解的时候,可以对照抽象工厂生活中例子的

这里首先以一个生活中抽象工厂的例子来实现一个抽象工厂,然后再给出抽象工厂的定义和uml图来帮助大家更好地掌握抽象工厂模式,同时大家在理解的时候,可以对照抽象工厂生活中例子的实现和它的定义来加深抽象工厂的uml图理解。抽象工厂模式比其它工厂模式更加抽象,抽象工厂模式适用与多个抽象类的情况下,通过工厂返回多个抽象类中你需要得到的具体子类实例。

抽象工厂模式比其它工厂模式更加抽象,抽象工厂模式适用与多个抽象类的情况下,通过工厂返回多个抽象类中你需要得到的具体子类实例。

举例阐述抽象工厂模式:
假如中国对邪恶国家开战。

中国装备:炸弹类,坦克类,来消灭邪恶国家。

炸弹类:导弹,核弹;

坦克类:越野车,主站坦克;

战略:

前期中国兵工厂生产:导弹,越野车,打击邪恶国家。

后期中国兵工厂生产:核弹,主站坦克,毁灭邪恶国家。

类图:

2016217144844885.png (1091×595)

装备类代码:

  #region 炸弹系列
  abstract class bomb
  {
    abstract public void baozha();
  }
  /// <summary>
  /// 导弹
  /// </summary>
  class daodanbomb :bomb
  {
    public override void baozha()
    {
      console.writeline("我是一颗中国造导弹,来轰炸不老实的小邪恶国家!");
    }
  }
  /// <summary>
  /// 核弹
  /// </summary>
  class hedanbomb : bomb
  {
    public override void baozha()
    {
      console.writeline("我是一颗中国造核弹,来轰炸不老实的小邪恶国家!");
    }
  }
  #endregion

  #region 坦克系列
  abstract class tank
  {
    abstract public void go();
  }
  /// <summary>
  /// 越野车
  /// </summary>
  class yueyetank : tank
  {
    public override void go()
    {
      console.writeline("我是一颗中国造越野车,来踏平不老实的小邪恶国家!");
    }
  }
  /// <summary>
  /// 主站坦克
  /// </summary>
  class zhuzhantank : tank
  {
    public override void go()
    {
      console.writeline("我是一颗中国造主站坦克,来踏平不老实的小邪恶国家!");
    }
  }
  #endregion工厂类代码


  #region 中国兵工厂
  abstract class chinafactory
  {
    //装甲车制造车间
    public abstract tank createtank();
    //炸弹知道车间
    public abstract bomb createbomb();
  }
  //兵工厂前期制造
  class qianqifactory : chinafactory
  {   
    public override bomb createbomb()
    {
      //导弹
      return new daodanbomb();
    }
    public override tank createtank()
    {
      //越野车
      return new yueyetank();
    }
  }
  //兵工厂后期制造
  class houqifactory : chinafactory
  {
    public override bomb createbomb()
    {
      //核弹
      return new hedanbomb();
    }
    public override tank createtank()
    {
      //主站坦克
      return new zhuzhantank();
    }
  }
  #endregion客户端代码:(打仗)


  // 备战
  class make
  {
    //装备 
    private bomb bomb;
    private tank tank;
    //制造加工
    public make(chinafactory factory)
    {
      bomb = factory.createbomb();
      tank = factory.createtank();
    }

    //开始打仗
    public void warstar()
    {
      //炸弹类爆炸
      bomb.baozha();
      //战车类前进
      tank.go();
    }

  }
  public class start
  {
    public static void main()
    {
      //大战前期
      chinafactory qianqimake = new qianqifactory();
      make qianqi = new make(qianqimake);
      qianqi.warstar();

      //点任意键,进行后期攻势!!
      console.readkey();

      //大战后期
      chinafactory houqimake = new houqifactory();
      make houqi = new make(houqimake);
      houqi.warstar();

      console.writeline("钓鱼岛是中国的,神圣不可侵犯!小邪恶国家,滚开!!");
      console.readline();
    }
  }


抽象工厂模式的定义和类图

抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么。这样客户就可以从具体产品中被解耦。下面通过抽象工模式的类图来了解各个类中之间的关系:

2016217144927859.png (633×457)

抽象工厂的分析
抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展,这真是抽象工厂模式的优点所在,然后抽象模式同时也存在不足的地方。下面就具体看下抽象工厂的缺点(缺点其实在前面的介绍中以已经涉及了):

抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

知道了抽象工厂的优缺点之后,也就能很好地把握什么情况下考虑使用抽象工厂模式了,下面就具体看看使用抽象工厂模式的系统应该符合那几个前提:

一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
这个系统有多个系列产品,而系统中只消费其中某一系列产品
系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。


.net中抽象工厂模式实现
抽象工厂模式在实际中的应用也是相当频繁的,然而在我们.net类库中也存在应用抽象工厂模式的类,这个类就是system.data.common.dbproviderfactory,这个类位于system.data.dll程序集中,该类扮演抽象工厂模式中抽象工厂的角色,我们可以用reflector反编译工具查看该类的实现:

/// 扮演抽象工厂的角色
/// 创建连接数据库时所需要的对象集合,
/// 这个对象集合包括有 dbconnection对象(这个是抽象产品类,如绝味例子中的yabo类)、dbcommand类、dbdataadapter类,针对不同的具体工厂都需要实现该抽象类中方法,
public abstract class 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);
}
dbproviderfactory类是一个抽象工厂类,该类提供了创建数据库连接时所需要的对象集合的接口,实际创建的工作在其子类工厂中进行,微软使用的是sql server数据库,因此提供了连接sql server数据的具体工厂实现,具体代码可以用反编译工具查看,具体代码如下:

/// 扮演着具体工厂的角色,用来创建连接sql server数据所需要的对象
public sealed class sqlclientfactory : dbproviderfactory, iserviceprovider
{
  // fields
  public static readonly sqlclientfactory instance = new sqlclientfactory();
  // 构造函数
  private sqlclientfactory()
  {
  }
      
  // 重写抽象工厂中的方法
  public override dbcommand createcommand()
  { // 创建具体产品
    return new sqlcommand();
  }
  public override dbcommandbuilder createcommandbuilder()
  {
    return new sqlcommandbuilder();
  }
  public override dbconnection createconnection()
  {
    return new sqlconnection();
  }
  public override dbconnectionstringbuilder createconnectionstringbuilder()
  {
    return new sqlconnectionstringbuilder();
  }
  public override dbdataadapter createdataadapter()
  {
    return new sqldataadapter();
  }
  public override dbdatasourceenumerator createdatasourceenumerator()
  {
    return sqldatasourceenumerator.instance;
  }
  public override dbparameter createparameter()
  {
    return new sqlparameter();
  }
  public override codeaccesspermission createpermission(permissionstate state)
  {
    return new sqlclientpermission(state);
  }
}

因为微软只给出了连接sql server的具体工厂的实现,我们也可以自定义连接oracle、mysql的具体工厂的实现。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网