博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FactoryMethod工厂方法模式(创建型模式)
阅读量:5898 次
发布时间:2019-06-19

本文共 7146 字,大约阅读时间需要 23 分钟。

1、工厂方法模式解决的问题

现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路.

前提:抽象变化较慢,实现变化较快(不稳定)

整个抽象的游戏设施建造系统相对变化较慢,本例中只有一个Build的创建方法,而Build内部的方法实现,该实现依赖与各种具体的实现,而这些实现变化的非常频繁,现在虽然只有现代风格和古典风格的房屋和道路的构建,而将来可能会卡通风格、另类风格等各种各样的对象加入到Build方法中来渲染游戏的背景.

在不考虑第三方容器组件(如Unity)和设计模式的情况下,为了快速完成这个任务,我们通常会用以下这种方式编码,代码如下:

#region 抽象A    ///     /// 抽象的游戏设施建造系统    ///     public class BuildSystem    {        ///         /// Build方法的逻辑变化较慢(只需要创建2种风格的房屋和道路,总共8个对象),但是风格变化较快,由于需求变化,可能需要创建诸如卡通风格、另类风格等的房屋和道路        ///         public void Builld()        {            ModernHouse modernHouseA = new ModernHouse();            ModernHouse modernHouseB = new ModernHouse();            ModernRoad modernRoadA = new ModernRoad();            ModernRoad modernRoadB = new ModernRoad();            ClassicalHouse classicalBuildA = new ClassicalHouse();            ClassicalHouse classicalBuildB = new ClassicalHouse();            ClassicalRoad classicalRoadA = new ClassicalRoad();            ClassicalRoad classicalRoadB = new ClassicalRoad();            //下面是具体的对象实例操作,如现代化房屋虽然有两个实例,但是可能两个可能高矮、外形不同等        }    }     #endregion    #region 实现细节b    ///     /// 现代风格的房屋    ///     public class ModernHouse { }    ///     /// 现代风格的道路    ///     public class ModernRoad { }    ///     /// 古典风格的房屋    ///     public class ClassicalHouse { }    ///     /// 古典风格的道路    ///     public class ClassicalRoad { }     #endregion

客户端调用代码如下:

class Program    {        static void Main(string[] args)        {            BuildSystem buildSystem = new BuildSystem();            buildSystem.Builld();        }    }

从oop的角度分析上面的代码:

1、Build方法的主逻辑稳定(变化较慢),构建两种风格的房屋和道路,目前只需要构建8个对象,后续可扩展.

2、虽然上面的代码完成1中的要求,但是无法应对后续的扩展,假设新增加了一个需求,Build方法需要能切换风格,完成卡通和另类风格的房屋和道路的构建,显然上面的代码无法完成这个需求.(当然你可以在BuildSystem中新添一种新的Build方法来满足需求,但是这种方式的代码的重用性差)

3、代码的大致结构如下图:

代码虽然拥有大致的主逻辑,但是和各个子模块糅合在一起,代码复用性差,Build方法(抽象)依赖于其下面的具体实现,如下图:

所以我们需要对代码进行重构.

///     /// 抽象的游戏建造系统    ///     public class BuildSystem    {        ///         /// 具体的构建方法,Build方法的逻辑变化较慢(只需要创建2种风格的房屋和道路,总共8个对象),但是风格变化较快,由于需求变化,可能需要创建诸如卡通风格、另类风格等的房屋和道路        ///         public void Build(HouseFactory houseFactoryOne, HouseFactory houseFactoryTwo,RoadFactory roadFactoryOne, RoadFactory roadFactoryTwo)        {            House HFirstStyleOne = houseFactoryOne.CreateHouse();            Console.WriteLine(HFirstStyleOne.ShowHouseStyle());            House HFirstStyleTwo = houseFactoryOne.CreateHouse();            Console.WriteLine(HFirstStyleTwo.ShowHouseStyle());            Road RFirstStyleOne = roadFactoryOne.CreateRoad();            Console.WriteLine(RFirstStyleOne.ShowRoadStyle());            Road RFirstStyleTwo = roadFactoryOne.CreateRoad();            Console.WriteLine(RFirstStyleTwo.ShowRoadStyle());            House HSecondStyleOne = houseFactoryTwo.CreateHouse();            Console.WriteLine(HSecondStyleOne.ShowHouseStyle());            House HSecondStyleTwo = houseFactoryTwo.CreateHouse();            Console.WriteLine(HSecondStyleTwo.ShowHouseStyle());            Road RSecondStyleOne = roadFactoryTwo.CreateRoad();            Console.WriteLine(RSecondStyleOne.ShowRoadStyle());            Road RSecondTwo= roadFactoryTwo.CreateRoad();            Console.WriteLine(RSecondTwo.ShowRoadStyle());        }    }    #region 抽象工厂方法    ///     /// 抽象的House工厂方法    ///     public abstract class HouseFactory    {        public abstract House CreateHouse();    }    ///     /// 抽象的Road工厂方法    ///     public abstract class RoadFactory    {        public abstract Road CreateRoad();    }    #endregion    #region 工厂方法    public class ModernHouseFactory : HouseFactory    {        public override House CreateHouse()        {            return new ModernHouse();        }    }    public class ModerRoadFactory : RoadFactory    {        public override Road CreateRoad()        {            return new ModernRoad();        }    }    public class ClassicalHouseFactory : HouseFactory    {        public override House CreateHouse()        {            return new ClassicalHouse();        }    }    public class ClassicalRoadFactory : RoadFactory    {        public override Road CreateRoad()        {            return new ClassicalRoad();        }    }    public class CartoonHouseFactory : HouseFactory    {        public override House CreateHouse()        {            return new CartoonHouse();        }    }    public class CartoonRoadFactory : RoadFactory    {        public override Road CreateRoad()        {            return new CartoonRoad();        }    }    public class AlternativeHouseFactory : HouseFactory    {        public override House CreateHouse()        {            return new AlternativeHouse();        }    }    public class AlternativeRoadFactory : RoadFactory    {        public override Road CreateRoad()        {            return new AlternativeRoad();        }    }    #endregion    #region 抽象    public abstract class House    {        public abstract string ShowHouseStyle();    }    public abstract class Road    {        public abstract string ShowRoadStyle();    }    #endregion    #region 具体的实现    public class ModernHouse : House    {        public override string ShowHouseStyle()        {            return "Modern现代化风格房屋";        }    }    public class ModernRoad : Road    {        public override string ShowRoadStyle()        {            return "Modern现代化风格道路";        }    }    public class ClassicalHouse : House    {        public override string ShowHouseStyle()        {            return "Classical古典化风格房屋";        }    }    public class ClassicalRoad : Road    {        public override string ShowRoadStyle()        {            return "Classical古典化风格道路";        }    }    public class CartoonHouse : House    {        public override string ShowHouseStyle()        {            return "Cartoon卡通化风格房屋";        }    }    public class CartoonRoad : Road    {        public override string ShowRoadStyle()        {            return "Cartoon卡通化风格道路";        }    }    public class AlternativeHouse : House    {        public override string ShowHouseStyle()        {            return "Alternative另类化风格房屋";        }    }    public class AlternativeRoad : Road    {        public override string ShowRoadStyle()        {            return "Alternative另类化风格道路";        }    }    #endregion

客户端调用代码如下:

///     /// FactoryMethod工厂方法-创建型模式    ///     class Program    {        static void Main(string[] args)        {            BuildSystem buildSystem = new BuildSystem();            buildSystem.Build(new CartoonHouseFactory(), new AlternativeHouseFactory(), new CartoonRoadFactory(),new AlternativeRoadFactory());            Console.ReadKey();        }    }

ok,重构后的代码很好的完成的了需求,而且扩展性更高,这就是FactoryMethod工厂模式,通过工厂模式,完成对主逻辑的整理,让主逻辑不在依赖具体的实现细节,而是依赖于抽象工厂.,通过传入的具体类型的工厂类来完成具体类型的创建,如果后续需要增加具体类型实例的实例,则只需要调用Create方法即可,完成依赖倒置.

重构后的代码如下图:

中间的实折现代表Build方法,主逻辑稳定,圈圈代表抽象工厂类,通过抽象工厂类完成主逻辑和实现的解耦.

 

虽然工厂模式能很好的解决这一类问题,但是如果具体的实现细节过多,比如在增加N种风格的房屋和道路,这个时候就会存在工厂泛滥的问题?

解决方案如下:

1、使用第三方依赖注入工具,如Unity等  参考

2、使用原型模式,原型模式能很好的解决工厂泛滥的问题.关于原型模式,请参考

 

关于抽象工厂模式和工厂模式的区别:

工厂模式只能解决单个对象的需求变化,实际上面的代码还能进一步进行抽象,对工厂类进行抽象,将现代化的道路和房屋抽象到一起,构成一个现代化风格系列对象创建工厂,这个时候就是工厂模式的升级版-抽象工厂,抽象工厂模式解决系列对象的对象变化.

 

转载于:https://www.cnblogs.com/GreenLeaves/p/9795620.html

你可能感兴趣的文章
【AS】使用数组
查看>>
Codeforces Round #546 (Div. 2) C. Nastya Is Transposing Matrices
查看>>
linux 各种格式的压缩/解压文件
查看>>
线性分类器及python实现
查看>>
理解 Linux 的硬链接与软链接
查看>>
day6 time和datetime模块
查看>>
log4j配置
查看>>
PhoneApplicationFrame以及设置Obscured/Unobscured的event handler
查看>>
1064 Complete Binary Search Tree
查看>>
iOS添加快捷方式到桌面
查看>>
股票图形入门
查看>>
基于数据库开发常用方法逻辑总结
查看>>
[工具]iostat
查看>>
Xcode 8带来的新特性和坑
查看>>
【51NOD-0】1106 质数检测
查看>>
我理解的MVC
查看>>
TF基础2
查看>>
[译] WebSockets 与长轮询的较量
查看>>
前端mongo聚合笔记
查看>>
SQl 事务 异常和游标
查看>>