zoukankan      html  css  js  c++  java
  • 3. Abstract Factory抽象工厂(创建型模式)

    3. Abstract Factory抽象工厂(创建型模式)

    李建忠
    上海祝成科技高级培训讲师

    new的问题
    常规的对象创建方法:

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

    new的问题:

    实现依赖,不能应对具体实例化类型的变化。

    解决思路:

    封装变化点——哪里变化,封装哪里。
    潜台词:如果没有变化,当然不需要额外的封装!

    工厂模式的缘起
    变化点在对象创建,因此就封装对象创建
    面向接口编程——依赖接口,而非依赖实现。
    最简单的解决方法:

    [类库]

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

    [客户程序]

    //创建一个Road对象
    Road road=roadFactory.CreateRoad();

    创建一系列相互依赖的对象  

    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();

    简单工厂的问题

    简单工厂的问题:

    不能应对不同系列对象的变化。 比如有不同风格的游戏场景——对应不同风格的道路、房屋、地道……

    如何解决:

      使用面向对象的技术来封装变化点。

    动机(Motivation
    在软件系统中, 经常面临着一系列相互依赖的对象的创建工作;同时, 由于需求的变化, 往往存在更多系列对象的创建工作。

    如何应对这种变化? 如何绕过常规的对象创建方法(new)
    提供一种封装机制来避免客户程序和这种多系列具体对象创建工作的紧耦合?

    意图(Intent

        提供一个接口, 让该接口负责创建一系列相关或者相互依赖的对象, 无需指定它们具体的类。
                                                               ——《设计模式》GoF

    结构(Structure

    游戏框架中的Abstract Factory应用   Codes in VS.NET

    Abstract Factory模式的几个要点
    如果没有应对多系列对象构建的需求变化, 则没有必要使用Abstract Factory模式,这时候使用简单的静态工厂完全可以。

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

    • Abstract Factory模式主要在于应对新系列的需求变动。其缺点在于难以应对新对象的需求变动。

    • Abstract Factory模式经常和Factory Method模式共同组合来应对对象创建的需求变化。

    .NET框架中的Abstract Factory应用   Codes in VS.NET

    推荐参考书

    《设计模式: 可复用面向对象软件的基础》GoF
    《面向对象分析与设计》Grady Booch
    《敏捷软件开发: 原则、 模式与实践》Robert C. Martin
    《重构: 改善既有代码的设计》Martin Fowler
    Refactoringto PatternsJoshuaKerievsky

    Question & Answer
    如需提出问题, 请单击提问按钮并在随后显示的浮动面板中输入问题内容。一旦完成问题输入后, 请单击提问按钮。

    代码实现:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    namespace ConsoleApplication1

    {

        class Program

        {

            static void Main(string[] args)

            {

                GameManager g = new GameManager(new MordenFacilitiesFactory());

                g.BuildGameFacilities();

                g.Play();

            }

        }

        //道路

        public abstract class Road

        { }

        //房屋

        public abstract class Building

        { }

        //地道

        public abstract class Tunel

        { }

        //丛林

        public abstract class Jungle

        { }

        //总设施

        public abstract class FacilitiesFactory

        {

            public abstract Road CreateRoad();

            public abstract Building CreateBuilding();

            public abstract Tunel CreateTunel();

            public abstract Jungle CreateJungle();

        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        //客户程序

        class GameManager

        {

            Road road;

            Building building;

            Tunel tunel;

            Jungle jungle;

            FacilitiesFactory facilitiesFactory;

            public GameManager(FacilitiesFactory facilitiesFactory)

            {

                this.facilitiesFactory = facilitiesFactory;

            }

            public void BuildGameFacilities()

            {

                road = facilitiesFactory.CreateRoad();

                building=facilitiesFactory.CreateBuilding();

                tunel=facilitiesFactory.CreateTunel();

                jungle=facilitiesFactory.CreateJungle();

            }

            public void Play()

            {

                //真正的代码实现;

            }

        }

        //道路

        public  class MordenRoad:Road

        { }

        //房屋

        public class MordenBuilding:Building

        { }

        //地道

        public class MordenTunel:Tunel

        { }

        //丛林

        public class MordenJungle:Jungle

        { }

        //总设施

        public class MordenFacilitiesFactory:FacilitiesFactory

        {

            public override Road CreateRoad()

            {

                return new MordenRoad();

            }

            public override Building CreateBuilding()

            {

                return new MordenBuilding();

            }

            public override Tunel CreateTunel()

            {

                return new MordenTunel(); 

            }

            public override Jungle CreateJungle()

            {

                return new MordenJungle();

            }

        }

    }

  • 相关阅读:
    如何计算时间复杂度
    注意线程
    java中一个类要当作线程来使用有两种方法
    压缩和解压
    init [0123456]
    linux文件目录
    为什么使用combiner?【Hadoop】
    JAVA标识符
    关键字:java
    转 java 中int String类型转换
  • 原文地址:https://www.cnblogs.com/zhangqs008/p/1526320.html
Copyright © 2011-2022 走看看