设计模式_2_抽象工厂

1.Singleton 单例设计模式。
利用面向对象的知识不多,只有一个面向对象的东西,就是封装。关于多态,继承的东西不多。理解和控制起来都比较容易。

面向对象设计模式:
根据面向推向推演出来的二十三种设计模式。
2.Abstract Factory 抽象工厂(创建型模式)

3.创建型的模式:解决new 的问题。
(1)常规的创建对象的方法:Road road=new Road();
(2)new 的问题? 实现依赖,不能应对“具体实例化类型” 的变化。
(3)解决思路:封装变化点--哪里有变化,就封装哪里。
潜台词:如果没有变化,不需要额外的封装。
4.面向接口编程

工厂模式的缘起
(1)变化点:“创建对象”,封装创建对象
(2)面向接口编程:依赖接口,而非依赖实现。
(3)解决办法(Simple):
public class RoadFactory{
public static Road CreateRoad(){
return new Road();
}
}
//创建一个Road对象
Road road=roadFactory.CreateRoad();

1.缘起
封装变化点:变化点---对象创建。
面向对象遵循的一个原则:哪里有变化,封装哪里。
面向接口编程:依赖接口,而不是依赖实现。
最简单的解决方法:
public class RoadFactory{
public static Road CreateRoad{
return new Road();
}
}
//
Road road=RoadFactory.CreateRoad();

public class RoadFactory{
public static Road CreateRoad(){
return new WaterRoad();
}
}

Road road=RoadFactory.CreateRoad();
Road .抽象类。
WaterRoad
FeetRoad
HotRoad

Road road=RoadFactory.CreateRoad();
下面使用的road 都统一使用,而不必改变。
屏蔽不同类型。
//服务器端
public class RoadFactory{
public static Road CreateRoad(){
return new WaterRoad();
//return new HotRoad();
}
}
//客户程序
Road road=RoadFactory.CreatRoad();

版本一:
Road road=new Road();
版本二:
public class RoadFactory{
public static Road CreateRoad(){
return new WaterRoad();
}
}
//
Road road=RoadFactory.CreateRoad()
版本三:
public class RoadFactory{
public static Road CreateRoad(){
return new Road();
}
public static Building CreateBuilding(){
return new Building();
}
public static Tunnel CreateTunnel(){
return new Tunnel();
}
public static Jungle CreateJungle(){
return new Jungle();
}
}
//
Road road=roadFactory.CreateRoad();
Building building=roadFactory.CreateBuilding();
缺点:不能应对多系列对象的构建
版本四:
//客户端依赖的抽象方法 client relays abstract function
public abstract class Road{}
public abstract class Building{}
public abstract class Tunnel{}
public abstract class Jungle{}
public abstract class FacilitiesFactory{
public abstract Road CreateRoad();
public abstract Building CreateBuilding();
public abstract Tunnel CreateTunnel();
public abstract Jungle CreateJungle();
}
//抽象方法的现代实现
public class ModernRoad:Road{}
public class ModernBuilding:Building{}
public class ModernTunnel:Tunnel{}
public class ModernJungle:Jungle{}
public class ModernFacilitiesFactory:FacilitiesFactory{
public override Road CreateRoad(){
return new ModernRoad();
}
public override Building CreateBuilding(){
return new ModernBuilding();
}
public override Tunnel ModernTunnel(){
return new ModernTunnel();
}
public override Jungle ModernJungle(){
return new ModernJungle();
}
}
//客户端管理类
public class GameManager{
FacilitiesFactory facilitesFactory;
Road road;
Building building;
Tunnel tunnel;
Jungle jungle;
public GameManager(FacilitiesFactory facilitesFactory){
this.facilitiesFactory=facilitesFactory;
}
public void BuildGameFacilities(){
road=facilities.CreateRoad();
building=facilites.CreateBuilding();
tunnel=facilities.CreateTunnel();
jungle=facilities.CreateJungle();
}
public void Run(){
road.AAA();
building.BBB(road);
tunnel.CCC();
jungle.DDD(tunnel);
}
}
//Main
public class Test{
public static void Main(){
GameManager g=new GameManager(new ModernFacilitiesFactory());//构建一个现代风格的游戏场景
g.BuildGameFacilities();
g.Run();
}
}
改进:后续有需求更改,要求改HotRoad .只用改RoadFactory 的CreateRoad就可以。

假设一个游戏开发场景:
我们需要构造“道路”,“房屋”,"地道","丛林" 等对象
战争执行任务,开发场景。
需求;
对象:道路,房屋,地道,丛林。
交互:相互之间交互,丛林的地下,拉一个地道。房屋的里面,安装一个地道。
道路旁边建一个房屋。建两个房屋。
开发:建立一系列对象,而且对象之间相互依赖。
代码:
public class RoadFactory{
public static Road CreateRoad(){
return new Road();
}
public static Building CreateBuilding(){
return new Building();
}
public static Tunnel CreateTunnel(){
return new Tunnel();
}
public static Jungle CreateJungle(){
return new Jungle();
}
}
Road road=roadFactory.CreateRoad();
Building building=roadFactory.CreateBuilding();
更深层次的封装,将RoadFactory 转换成接口,然后由具体的实例化的类来实例化它 。

简单工厂的问题?
不能应对“不同系列对象” 的变化。比如有不同风格的游戏场景----对应不同风格的道路、房屋、地道
解决办法:
使用面向对象的技术“封装变化点”
一个风格下,道路,丛林,地道是什么样的
另外一个风格下,道路,丛林,地道是什么样的
动机:
在软件系统中,经常面临着:“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列
对象的创建工作。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建”
工作的紧耦合。
总结:一系列相互依赖的对象,多系列。
意图:
提供一个接口,让接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们具体的类。《设计模式》GoF
Abstract Factory .
AbstractFactory
--ConcreateFactory1
--CreateProductA
--CreateProductB
--ConcreateFactory2
--CreateProductA
--CreateProductB
AbstractProductA
--ProductA1
--ProductA2
AbstractProductB
--ProductB1
--ProductB2
客户端依赖的是:
AbstractFactory
AbstractProductA
AbstractProductB
不在客户程序中出现的:ConcreateProduct1,ConcreateProduct2,ProductA1,ProductA2,ProductB1,ProductB2
客户程序不依赖于具体的实现。

需求变化:
	古典风格,现代风格,超未来风格。
	public class ConcreateFactory3:AbstractFactory(){
		public static ProductA CreateProductA(){}
		public static ProductB CreateProductB();
	}
	public class ProductA3:ProductA{}
	public class ProductB3:ProductB{}
	//client
	//factory=new ConcreateFactory3(); 这种改动可以通过配置文件来改变。
	AbstractProductA productA=factory.CreateProductA();
	AbstractProductB productB=factory.CreateProductB();

AbstractFactory 模式的几个要点。

1.如果没有应对“多系列变化”的需求,没有必要使用Abstract Factory 的模式。这时候,使用简单的静态工厂(版本三)完全可以。

2.“系列对象” 指的是,这些对象之间,相互依赖,或作用的关系。例如,游戏开发场景中,“道路”与“房屋” 的依赖,

“地道”与“道路”的依赖

3.AbstractFactory 模式,主要在于应对“新系列” 的需求的变动。缺点在于难以应对“新对象” 的需求变动。

4.AbstractFactory 模式经常和Factory Method 模式共同组合 应对“对象创建”的需求变化。

例如:
1.如果变化的轴线,在于经产加一个类,如加一个 public abstract Desert {},后天又加一个湖泊的类,
那么使用AbstractFactory ,反而使需求变化的时候,变的非常麻烦。属于误用设计模式。
2.适应:对象结构稳定,系列需求经常变化。
3.在做应用程序设计的时候,要预见变化点,选择适合的设计模式。
4.实际开发中,有很多 多个设计模式,组合应用的情况。MVC 就是几种模式的组合。
在Java sdk 中,Abstract Factory 的应用很广泛,在.net的框架中,Abstract Factory 的应用不多。
abstract Factory 的应用,更多的体现在业务层。

问题:
1.能否提供包含设计模式的成熟案例,来供大家学习。
2.abstract factory 与builder 模式的区别。 build 模式,更强调对象部分的构建的封装。abstract factory 构建
一组互相交互的依赖的多个对象。

posted @ 2018-11-21 20:08  sujingnuli  阅读(128)  评论(0编辑  收藏  举报