1、new 的问题

常见的对象创建方法:

//创建一个Road对象
Road road=new Road();

new的问题:实现依赖,不能应对具体实例的变化

怎么理解上面这句话呢?

可以这样理解:我们创建的对象实例依赖于Road对象的内部实现,如果Road对象不会发生变化(或者发生变化的频率很小),那么单纯的用new是可以的,但是上面的Road我们单纯籽籽棉意思上理解,路肯定是变化很大的,路有水泥路,马路,公路等等,所以每当我们的Road发生变化,单纯用new的方式,我们就必须修改所有使用过Road的地方。

总结:所以可以得出一个结论,当我们new的业务对象变化比较频繁的时候,就不能使用new来创建对象;如果要创建的业务对象很稳定,不会发生平凡的变化,那么可以使用new.

2、如何解决new的问题呢?

解决new的问题,最好的方法就是封装变化点,哪里经常变化,就把那里封装起来

3、工厂模式源起

(1)、2中说了,要解决new的问题,就是封装变化点,而new的问题就是"对象创建的不定性",对象的频繁变化,所以我们就封装"对象的创建"。

(2)、这也引申出了另一个编程思想:面向接口编程---依赖接口,而非依赖实现

(3)、抽象工厂的简易版:

using System;
namespace AF
{
class AbstractFactorySimple
{
static void Main(string[] args)
{
//创建一个Road对象
Road road = AbstractFactory.CreateRoad();
}
}
public class AbstractFactory
{
public static Road CreateRoad()
{
return new Road();
}
}
class Road
{ }
}

4、假设有一个游戏开发场景:我们需要构造"道路"、"房屋"、"地道"、"丛林"等等对象,可以用下面的最浅层的工厂模式来封装

using System;
namespace AF
{
class AbstractFactoryShallow
{ }
public class AbstractFactory
{
public static Road CreateRoad() { return new Road(); }
public static Jungle CreateJungle() { return new Jungle(); }
public static Buliding CreateBuliding() { return new Buliding(); }
public static Postern CreatePostern() { return new Postern(); }
}
class Road { }
class Jungle { }
class Buliding { }
class Postern { }
}

上面的代码是最浅层的封装,也就是简单的工厂,也称之为"静态工厂";解决了对象创建的不确定性;

5、这个时候需求又变了,接着第四个问题,一般游戏都会有不同的风格,所以"道路","暗道","丛林","房屋"也会有不同的风格,这个时候在解决对象创建的不确定之后,产生了对象的不决定性,也就是道路对象可能会有很多种,丛林也可能会有很多种,等等的问题,那么显然上面的简单工厂(静态工厂)并不能解决我们的问题;

在提出上面问题的解决方案之前,先说下动机:

在软件系统中,经常面临着"一系列相互依赖的对象创建",而随着业务需求的改变,往往存在更多系列对象的创建

解决方法:绕过常规的对象创建方法,提供一种"封装机制",来避免客户程序和多系列对象创建的紧耦合。

,如果不理解前面的概念,可以4中的分析;

6、抽象工厂的意图

提供一个接口,让接口负责创建一系列"相关或者相互依赖"的对象,无须指定具体的类。

7、结构图

8、完整工厂代码

using System;

namespace AF
{
//抽象工厂层
public abstract class Road
{
public abstract void AAA(Jungle jungle);
}
public abstract class Jungle
{
public abstract void BBB();
}
public abstract class Building
{
public abstract void CCC();
}
public abstract class Tunnel
{
public abstract void DDD();
}
public abstract class AbstractFactory
{
public abstract Road CreateRoad();
public abstract Jungle CreateJungle();
public abstract Building CreateBuilding();
public abstract Tunnel CreateTunnel();
}
//抽象工厂层 //现代工厂层
public class ModernRoad :Road
{
public override void AAA(Jungle jungle) { }
}
public class ModernJungle : Jungle
{
public override void BBB() { }
}
public class ModernBuilding : Building
{
public override void CCC()
{
throw new NotImplementedException();
}
}
public class ModernTunnel : Tunnel
{
public override void DDD()
{
throw new NotImplementedException();
}
}
public class ModernFactory : AbstractFactory
{
public override Road CreateRoad()
{
return new ModernRoad();
}
public override Jungle CreateJungle()
{
return new ModernJungle();
}
public override Building CreateBuilding()
{
return new ModernBuilding();
}
public override Tunnel CreateTunnel()
{
return new ModernTunnel();
}
}
//现代工厂层结束 //古典工厂层
public class ClassicalRoad : Road
{
public override void AAA(Jungle jungle)
{
}
}
public class ClassicalJungle : Jungle
{
public override void BBB()
{
}
}
public class ClassicalBuiliding : Building
{
public override void CCC()
{ }
}
public class ClassicalTunnel : Tunnel
{
public override void DDD()
{
}
}
public class ClassicalFactory : AbstractFactory
{
public override Road CreateRoad()
{
return new ClassicalRoad();
} public override Jungle CreateJungle()
{
return new ClassicalJungle();
} public override Building CreateBuilding()
{
return new ClassicalBuiliding();
} public override Tunnel CreateTunnel()
{
return new ClassicalTunnel();
}
}
//古典工厂层结束 //客户端,客户端只依赖于抽象类个抽象方法,不依赖具体实现,这样客户端就很稳定
public class GameManager
{
Road road;
Building building;
Tunnel tunnel;
Jungle jungle;
AbstractFactory factory;
public GameManager(AbstractFactory factory)
{
this.factory = factory;
}
public void BulidFacilities()
{
road = factory.CreateRoad();
tunnel = factory.CreateTunnel();
jungle = factory.CreateJungle();
building = factory.CreateBuilding();
}
public void Run()
{
road.AAA(jungle);
tunnel.DDD();
building.CCC();
jungle.BBB();
}
} public class APP
{
static void Mains()
{
GameManager game = new GameManager(new ModernFactory());
game.Run();
}
}
}

抽象工厂(AbstractFactory)模式-创建型模式的更多相关文章

  1. FactoryMethod工厂方法模式(创建型模式)

    1.工厂方法模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只 ...

  2. Prototype原型模式(创建型模式)

    1.原型模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只有一 ...

  3. 工厂方法模式——创建型模式02

    1. 简单工厂模式     在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...

  4. 设计模式(五):PROTOTYPE原型模式 -- 创建型模式

    1.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.适用场景 原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对 ...

  5. 设计模式(二): BUILDER生成器模式 -- 创建型模式

    1.定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 2.适用场景 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式 ...

  6. AbstractFactory抽象工厂模式(创建型模式)

    1.new 的问题 常见的对象创建方法: //创建一个Road对象 Road road=new Road(); new的问题:实现依赖,不能应对具体实例的变化 怎么理解上面这句话呢? 可以这样理解:我 ...

  7. 设计模式(一): abstract factory抽象工厂模式 -- 创建型模式

    1.定义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.适用场景 1.一个系统要独立于它的产品创建.组合和表示. 2.一个系统要由多个产品系列中的一个来配置. 3.当你要 ...

  8. C#设计模式--抽象工厂模式(创建型模式)

    一.抽象工厂模式: 在工厂模式中具体的产品和具体的工厂是一一对应的,一个工厂只能生产一种产品,结构单一,例如小米公司刚开始是只生产小米手机,但是伴随着公司的发展,他们需要生产不同型号的手机,也会生产路 ...

  9. 工厂模式/factory模式/创建型模式

    工厂模式 普通工厂模式 原本需要new出来的对象,通过一个类的方法去搞定,Factory.build(parameter),类似这种. public interface Sender { public ...

随机推荐

  1. 基于MATLAB的数字基带信号的各种码型的产生

    单极性非归零码 单极性非归零码使用电平1来表示二元信息中的“1”,用电平0来表示二元信息中的“0”,电平在整个码元的时间里不变单极性非归零码的优点是实现简单,但由于含有直流分量,对在带限信道中的传输不 ...

  2. redis的安装和测试

    redis一直都是调用别人部署好的,近日想要自己从灵开始搭建一次.其中也生出不少枝节,与各位猿友共同分享,望少走些弯路! 1.提前准备的资源 redis安装包(本人上传到csdn不需积分即可下载): ...

  3. mysql数据库实操笔记20170419

    一.insert与replace区别: insert:当表里有字段设置了主键或者唯一时,插入重复的唯一或主键字段值是不能执行的: replase:当表里有字段设置了主键或者唯一时,插入重复的唯一或主键 ...

  4. 初识JS

    今儿我遇到一特别恐怖的事儿,JS 刚开始的我看到JS感觉是懵逼的,翻开第一页,感觉是棒棒哒,再看第二页,感觉是easy的,看到第三页是恐怖的,当看到的第四页的时候,我感觉今年的清明节是为我准备的 废话 ...

  5. 笔记:查看linux系统开机时间

    [root@localhost ~]# uptime -s -- :: 通过命令uptime -s 查看系统开机时间

  6. HashMap 构造函数

    HashMap总共提供了三个构造函数 /** * Constructs an empty <tt>HashMap</tt> with the default initial c ...

  7. Android 如何本地加载pdf文件

    大部分app打开pdf文件是通过intent调起手机中能打开pdf文件的工具,来查看pdf文件,如果需求是,用户在app内下载好pdf文件后,不通过第三方的工具,本地打开. 这样的需求要怎么实现呢?上 ...

  8. Linux 上搭建 git 的服务器

    搭建服务器 假设服务器的名字是 git.example.com. 首先,添加一个叫做git的用户adduser git. 然后如果不存在的话, 为这个用户新建一个主目录mkdir /home/git, ...

  9. javascript执行原理

    执行环境 当执行流执行到函数时会创建一个执行环境,这个执行环境包含了函数内部 语句可以访问的所有变量和函数,当代码执行完时,销毁执行环境.所以一般情 况下,局部变量在函数执行完时会被销毁. 作用域.调 ...

  10. 基于Struts2,Spring4,Hibernate4框架的系统架构设计与示例系统实现

    笔者在大学中迷迷糊糊地度过了四年的光景,心中有那么一点目标,但总感觉找不到发力的方向. 在四年间,尝试写过代码结构糟糕,没有意义的课程设计,尝试捣鼓过Android开发,尝试探索过软件工程在实际开发中 ...