面向对象编程思想-抽象工厂模式

一、引言

在前两篇博客中,工厂方法模式的产生,克服了简单工厂模式随着产品的增加导致工厂类越来越复杂的问题,那么在工厂方法模式中,是不是我们每新增一个新的实例都需要新增一个工厂呢,想一下,在现实生活当然不是啦,工厂已经多元化,会生产一系列的产品(产品族概念产生),显然工厂方法模式的程序设计思想放在这里是不适用的,下面请看我们今天学习的抽象工厂模式是如何解决这个问题的。

二、抽象工厂模式

定义:抽象工厂模式把具体产品的创建延迟到具体的工厂中,将某一系列对象的创建封装起来。下面通过一个例子,帮助我们理解抽象工厂模式

下面是代码demo:

namespace DNA.Framework.AbstractFactory
{
  //车子类
public abstract class BaseCar { public abstract void Run(); } }
namespace DNA.Framework.AbstractFactory
{
  //宝马类
class BMW : BaseCar { public override void Run() { Console.WriteLine("我今天开{0}去上班",this.GetType().Name); } } }
namespace DNA.Framework.AbstractFactory
{
  //奔驰类
class MBZ : BaseCar { public override void Run() { Console.WriteLine("我今天开{0}去上班", this.GetType().Name); } } }
namespace DNA.Framework.AbstractFactory
{
  //跑车类
public abstract class BaseSportsCar { public abstract void MoreRun(); } }

namespace DNA.Framework.AbstractFactory
{
  //宝马系列跑车
class BMWSportsCar : BaseSportsCar
  {
     public override void MoreRun()
        {
            Console.WriteLine("我今天开{0}去兜风",this.GetType().Name);
        }
    }
}
namespace DNA.Framework.AbstractFactory
{
  //奔驰系列跑车
class MBZSportsCar : BaseSportsCar { public override void MoreRun() { Console.WriteLine("我今天开{0}去兜风", this.GetType().Name); } } }
namespace DNA.Framework.AbstractFactory
{
  //接口工厂类 提供创建一组产品的接口,而不需要关注具体产品是什么
interface IAbstractFactory { BaseCar GetCar(); BaseSportsCar GetSportsCar(); } }
namespace DNA.Framework.AbstractFactory
{
  //宝马工厂类 可以生产普通轿车,也可以生产宝马系列跑车
class BMWAbstractFactory:IAbstractFactory { public BaseCar GetCar() { return new BMW(); } public BaseSportsCar GetSportsCar() { return new BMWSportsCar(); } } }
namespace DNA.Framework.AbstractFactory
{
  //奔驰工厂类
class MBZAbstractFactory : IAbstractFactory { public BaseCar GetCar() { return new MBZ(); } public BaseSportsCar GetSportsCar() { return new MBZSportsCar(); } } }
namespace DNA.Framework.AbstractFactory
{
  //客户端 负责调用不同的工厂 生产不同系列的产品
class Program { static void Main(string[] args) { IAbstractFactory bmwFactory = new BMWAbstractFactory(); BaseCar bmw = bmwFactory.GetCar(); BaseSportsCar bmwSports = bmwFactory.GetSportsCar(); IAbstractFactory mbzFactory = new MBZAbstractFactory(); BaseCar mbz = mbzFactory.GetCar(); BaseSportsCar mbzSports = mbzFactory.GetSportsCar(); // IAbstractFactory ferrariFactory = new FERRARIAbstractFactory(); // BaseCar ferrari = ferrariFactory.GetCar(); // BaseSportsCar ferrariSports = ferrariFactory.GetSportsCar(); bmw.Run(); bmwSports.MoreRun(); mbz.Run(); mbzSports.MoreRun(); // ferrari.Run(); // ferrariSports.MoreRun(); Console.Read(); } } }

当有业务需求变化时,比如我们想增加 开着法拉利去上班,开着法拉利系列跑车去兜风,这时只需要增加法拉利的工厂类,负责创建法拉利普通车类和法拉利系列跑车类,增加法拉利类和法拉利跑车类

namespace DNA.Framework.AbstractFactory
{
  //法拉利工厂类
class FERRARIAbstractFactory : IAbstractFactory { public BaseCar GetCar() { return new FERRARI(); } public BaseSportsCar GetSportsCar() { return new FERRARISportsCar(); } } }
namespace DNA.Framework.AbstractFactory
{
  //法拉利类
class FERRARI:BaseCar { public override void Run() { Console.WriteLine("我今天开{0}去上班", this.GetType().Name); } } }
namespace DNA.Framework.AbstractFactory
{
  //法拉利跑车类
class FERRARISportsCar : BaseSportsCar { public override void MoreRun() { Console.WriteLine("我今天开{0}去兜风", this.GetType().Name); } } }

优点:抽象工厂对于系列产品的变化,扩展非常方便,只需新增具体工厂类及系列产品类。

缺点:当添加新产品时,由于工厂接口已经确定了创建产品的集合,这就不得不修改工厂创建类的接口,那么设计到的抽象工厂类以及子类都需要修改,违反了开闭原则。

适用场景:

1.不需要关注具体的产品实例如何被创建

2.产品有多个系列,而我们只消费其中的一个系列

3.要求提供一个产品的类型约束,所有的产品都要遵从该约束前提下才被创建时

关于抽象工厂模式的学习就到此结束了,希望能够帮到你,若有不足,欢迎斧正,感谢您的阅读。

参考:http://www.cnblogs.com/zhili/p/SimpleFactory.html

原文地址:https://www.cnblogs.com/jdzhang/p/6930347.html