抽象工厂模式

概念:

       抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

       上面这段话,我到现在还是不怎么明白。分析:首先抽象工厂是提供一个接口,什么样的接口?创建对象的接口。创建什么对象?一系列相关或相互依赖的对象。而且创建了这个接口之后,不需要指定这个接口的具体的类。还是不明白?

        百度百科是这么说的:抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

UML类图:

       从左到右,从上到下,依次是:客户端,客户端关联抽象工厂,抽象产品A,抽象产品B。然后抽象产品A,有两个具体子类:具体产品1类和具体产品2类(他们的实例化对象就是我们要创建的产品对象)。同理,抽象产品B。最后就是,抽象工厂,以及他的2个具体工厂。他们都有两个方法,用来创建具体的产品。


代码:

       分析:还是汽车的例子。由于生意越做越大,所以要扩展行业。决定,工厂不只生产汽车,还生产汽车运动服装。(这只是为了说明汽车类和服装类不是同一种产品,真实的工厂是不会一边生产汽车,还生产衣服的)。

       运动服装(SportsWear),两种牌子的宝马牌(BMWwear)和奔驰牌子(Benzwear)。其实衣服的牌子也可以完全和汽车没有关系。本来我打算用的是耐克(NIKE)和阿迪达斯(Adidas),但是后来写代码的时候,是在奔驰工厂或宝马工厂中的创建服饰,我就觉得在奔驰工厂中生产耐克,额~,觉得有些问题,就把耐克改成了奔驰服装,这样理解也方法。奔驰工厂生产的东西,带上标识,汽车就是奔驰汽车,衣服就是奔驰衣服,手机就是奔驰手机。

不过现在想想耐克其实也是可以的吧,大不了我说明下奔驰工厂生产的服装就是叫耐克服装也没什么,不过我代码已完成就不该了。

UML类图:

       为了简化问题,所有的产品类都只有一个方法,Show。然后工厂类增加一个方法CreateSportsWear,返回值是ISportsWear类型。

 

代码:

Namespace CarAbstractFactory
{
    class Program
   {
        static void Main(string[] args)
        {
            //最后,客户端修改下,首先要实例化具体工厂.
            //然后具体工厂创建具体的车,
           //具体的车创建完成了,自己展示下.
            Factory factory;
            ICar car; //客户端是通过他们的抽象接口(ICar)操纵实例
            //比较部分,开始
            factory = new BenzFactory();      
          car=factory.CreateCar();//产品的具体类(Benz)名也被具体工厂(BenzFactory)的实现(factory)分离,(Benz)没有出现在客户端中
            car.Show();
          //比较部分,结束
            //然后是具体工厂创建具体的服饰,然后具体服饰显示下,表明创建是成功的
            ISportsWear benzsports =factory.CreateSportsWear();
           benzsports.Show(); 

          //为了体现抽象工厂的易于交换产品系统的优点。我把代码修改了一下,可以比较客户端两段代码,
           //两段代码只有new的对象不一样,其他都一样,所以要修改是非常方便的。
            factory = new BMWFactory();
          car = factory.CreateCar();
          car.Show();
          //同理
            ISportsWear bmwsports =factory.CreateSportsWear();
          bmwsports.Show();          

          Console.Read();
        }
    }

    //首先还是抽象产品角色,汽车接口(产品角色都没变,不管抽象产品还是具体产品)
    interface ICar
    {
        void Show();
    }

    //然后是两个具体产品角色,宝马和奔驰,他们都要实现ICar接口
    class BMW:ICar
    {
        public void Show()
        {
            //内容很简单,只是输出一句话
              Console.WriteLine("一辆宝马诞生了!!!");
        }
    }

    //Benz类
    class Benz:ICar
    {
        public void Show()
        {
           Console.WriteLine("我是一辆奔驰!!!");
        }
    }

    //增加一个抽象产品系列,运动服装类
    interface ISportsWear
    {
        void Show();//只有这个方法,显示
    }

    //接着具体的运动服装产品类
    class BMWwear : ISportsWear
    {
        //实现接口的方法
        public void Show()
        {
            Console.WriteLine("宝马服饰");
        }
   }

    //奔驰服饰
    class Benzwear : ISportsWear
    {
       public void Show()
        {
            //这个效果和"Benzwear服饰"是一样的.
            Console.WriteLine("{0}服饰 ",this.GetType().Name);
        }
    }

    //然后要增加工厂类的方法,增加CreateSportsWear方法,
   //抽象工厂的名字从CarFactory改为Factory,因为现在不只是生产车子。
    abstract class Factory
    {
        //是个抽象方法,修改了下这个方法,原来是CarCreate,改成了CreateCar(我类图是这么写的)
        public abstract ICar CreateCar();
        //增加抽象方法,子类要实现
        public abstract ISportsWearCreateSportsWear();
    }

    //新开的两个工厂
    //宝马工厂
    class BMWFactory : Factory
    {
        //实现父类的抽象方法
        public override ICar CreateCar()
        {
            //CreateCar方法,它就是实例化个宝马类,也就是子类决定实例化哪一个类.类的实例延迟到子类.
            return new BMW();
        }
        public override ISportsWearCreateSportsWear()
        {
            //创建一种衣服,宝马服装
            return new BMWwear();
       }
    }
    //奔驰工厂,同宝马工厂
    class BenzFactory :Factory
    {
       public override ICar CreateCar()
        {
            return new Benz();
        }

        //和上面的相比,方法名一样,参数一样的,但是因为对象不一样,所以返回的结果不一样,是多态.

       public override ISportsWear CreateSportsWear()
        {
            //创建一种衣服,宝马服装
            return new Benzwear();
        }
    } 
}

运行结果:

       抽象工厂的优点是,易于交换产品系列,如我客户端中表示的,变换工厂只需要修改一个地方就可以。第二个优点是,让具体的创建实例过程和客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端中。

       但是他的缺点,如果我要在生产别的东西。比如我要增加一个生产家具的类,那么我就要增加一个家具的抽象类,两个具体的家具类,一个奔驰家具类和一个宝马家具类。然后还要增加方法CreateFurniture,就要更改Factory,BenzFactory和BMWFactory。要改三个类,太糟糕了。

       其实就上面的修改三个类,我觉得已经违背了开发-封闭原则,但是好像没有谁说这是修改,而是说这是扩展。我只好往这上面凑,觉得他们是增加了一个方法,而没有修改其他的地方,所以算是扩展。

       可以用简单工厂来改进抽象工厂,简单工厂就是把3个工厂类又简化成一个工厂类,然后具体要实例化那个产品类,肯定要有switch…case或if语句来选择。而使用switch…case或if语句不好,因为分支判断会耦合性高,然后使用反射来去除switch或if,解除分支判断带来的耦合。

       反射代码我就不写了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值