设计模式-抽象工厂

简单工厂模式:https://www.cnblogs.com/Kyle-Wang/p/16063512.html

工厂模式:https://www.cnblogs.com/Kyle-Wang/p/16095863.html

一、抽象工厂的引入

  在工厂模式里或者简单工厂模式里,我们的工厂都只负责创建种族(IRace),但其实在很多情况下,工厂并不只是创建一种类型的。比如拿三国杀游戏来说,有主公、武将的概念,而不同的人物又属于某一个势力(魏蜀吴)。此时如果还用工厂模式,需要定义6个工厂类:创建魏国主公工厂类,创建蜀国主公工厂类,创建吴国主公工厂类、创建魏国武将工厂类、创建蜀国武将工厂类、创建吴国武将工厂类。

  此时引入抽象工厂模式,在抽象工厂里,并不只是创建一类对象,而是多类对象。此时工厂类便可以缩短为3个:创建魏国主公、武将工厂类,创建蜀国主公、武将工厂类,创建吴国主公、武将工厂类。

 

二、抽象工厂的实现

  1、创建主公、武将接口

public interface IMaster
    {
        void ShowKing();
    }

public interface IGeneral
    {
        void ShowKing();
    }

  2、创建主公、武将类

public class MasterWei : IMaster
    {
        public void ShowKing()
        {
            Console.WriteLine("The master of {0} is 曹操", this.GetType().Name);
        }
    }

public class MasterShu : IMaster
    {
        public void ShowKing()
        {
            Console.WriteLine("The master of {0} is 刘备", this.GetType().Name);
        }
    }

public class MasterWu : IMaster
    {
        public void ShowKing()
        {
            Console.WriteLine("The master of {0} is 孙权", this.GetType().Name);
        }
    }

public class GeneralWei : IGeneral
    {
        public void ShowKing()
        {
            Console.WriteLine("The general of {0} is 夏侯惇、华雄", this.GetType().Name);
        }
    }

public class GeneralShu : IGeneral
    {
        public void ShowKing()
        {
            Console.WriteLine("The general of {0} is 关羽、张飞", this.GetType().Name);
        }
    }

public class GeneralWu : IGeneral
    {
        public void ShowKing()
        {
            Console.WriteLine("The general of {0} is 黄盖、高顺", this.GetType().Name);
        }
    }

  3、创建抽象工厂类、具体工厂类

public abstract class AbstractFactory
    {
        public abstract IMaster CreateMaster();
        public abstract IGeneral CreateGeneral();
    }

public class FactoryWei : AbstractFactory
    {
        public override IGeneral CreateGeneral()
        {
            return new GeneralWei();
        }

        public override IMaster CreateMaster()
        {
            return new MasterWei();
        }
    }

public class FactoryShu : AbstractFactory
    {
        public override IGeneral CreateGeneral()
        {
            return new GeneralShu();
        }

        public override IMaster CreateMaster()
        {
            return new MasterShu();
        }
    }

public class FactoryWu : AbstractFactory
    {
        public override IGeneral CreateGeneral()
        {
            return new GeneralWu();
        }

        public override IMaster CreateMaster()
        {
            return new MasterWu();
        }
    }

  4、调用方式

            {
                AbstractFactory factory = new FactoryWei();
                IMaster master = factory.CreateMaster();
                IGeneral general = factory.CreateGeneral();
                master.ShowKing();
                general.ShowKing();
            }
            {
                AbstractFactory factory = new FactoryShu();
                IMaster master = factory.CreateMaster();
                IGeneral general = factory.CreateGeneral();
                master.ShowKing();
                general.ShowKing();
            }        

三、抽象工厂的缺点

  抽象工厂是一种倾斜的可扩展设计。把每一种势力称为一个产品簇,比如魏国是一种产品簇,吴国也是、蜀国也是。而产品簇下面有不同产品,对应主公、武将各是一种产品。

  而倾斜的可扩展设计指的是,要扩展一种新产品簇(势力)很方便,但要扩展一种产品(人物类型)需要修改工厂。

  比如此时要新增一种势力(产品簇)叫:群雄势力,群雄势力的主公代表是张角,而武将代表是吕布。此时要新增这种势力,只需要新增群雄主公类、群雄武将类、群雄工厂,代码如下:

public class FactoryQun : AbstractFactory
    {
        public override IGeneral CreateGeneral()
        {
            return new GeneralQun();
        }

        public override IMaster CreateMaster()
        {
            return new MasterQun();
        }
    }

public class MasterQun : IMaster
    {
        public void ShowKing()
        {
            Console.WriteLine("The master of {0} is 张角", this.GetType().Name);
        }
    }

public class GeneralQun : IGeneral
    {
        public void ShowKing()
        {
            Console.WriteLine("The general of {0} is 吕布", this.GetType().Name);
        }
    }

调用方式也很简单

            {
                AbstractFactory factory = new FactoryQun();
                IMaster master = factory.CreateMaster();
                IGeneral general = factory.CreateGeneral();
                master.ShowKing();
                general.ShowKing();
            }    

 

但是!如果此时要新增一种人物类型(产品),比如除了主公、武将,还有一种重要类型叫:军师。那此时就必须修改工厂了,因为之前的工厂只能创建主公、武将。此时需要对抽象工厂新增一个抽象方法

public abstract class AbstractFactory
    {
        public abstract IMaster CreateMaster();
        public abstract IGeneral CreateGeneral();
        public abstract IAdvisor CreateAdvisor();
    }

而一旦抽象类新增了抽象方法了,子类就必须实现这个方法,这样就会修改比较多代码了。

 

因此,抽象工厂适合的场景是:产品簇不固定,但是产品簇里的产品比较固定的场景。

比如ADO.NET,产品簇为:sqlserver、mysql、Oracle,如果有需要,可以新增sqlLite或者其他数据库。但是他们所需要的对象(产品)都已经固定了,只需要DBCommand、DBConnection、DBDataAdapter、DBParameter就足够了。

 

posted @ 2022-04-03 22:32  暗,伏!  阅读(32)  评论(0编辑  收藏  举报