首页 > 其他分享 >第6章 创建型模式专题总结

第6章 创建型模式专题总结

时间:2023-06-11 12:35:05浏览次数:45  
标签:总结 专题 创建 abstract class void override public


创建型模式专题总结(Creational Pattern)

——.NET设计模式系列之七

Terrylee,2006年1月

概述

创建型模式,就是用来创建对象的模式,抽象了实例化的过程。它帮助一个系统独立于如何创建、组合和表示它的那些对象。本文对五种常用创建型模式进行了比较,通过一个游戏开发场景的例子来说该如何使用创建型模式。

为什么需要创建型模式

所有的创建型模式都有两个永恒的主旋律:第一,它们都将系统使用哪些具体类的信息封装起来;第二,它们隐藏了这些类的实例是如何被创建和组织的。外界对于这些对象只知道它们共同的接口,而不清楚其具体的实现细节。正因如此,创建型模式在创建什么(what),由谁(who)来创建,以及何时(when)创建这些方面,都为软件设计者提供了尽可能大的灵活性。

假定在一个游戏开发场景中,会用到一个现代风格房屋的对象,按照我们的一般想法,既然需要对象就创建一个:

ModernRoom room = new ModernRoom();

好了,现在现代风格房屋的对象已经有了,如果这时房屋的风格变化了,需要的是古典风格的房屋,修改一下:

ClassicalRoom room = new ClassicalRoom();

试想一下,在我们的程序中有多少处地方用到了这样的创建逻辑,而这里仅仅是房屋的风格变化了,就需要修改程序中所有的这样的语句。现在我们封装对象创建的逻辑,把对象的创建放在一个工厂方法中:

ModernFactory factory = new ModernFactory();

ModernRoom room = factory.Create();

当房屋的风格变化时,只需要修改

ClassicalFactory factory = new ClassicalFactory();

ClassicalRoom room = factory.Create();

而其它的用到room的地方仍然不变。这就是为什么需要创建型模式了。创建者模式作用可以概括为如下两点:

1.封装创建逻辑,绝不仅仅是new一个对象那么简单。

2.封装创建逻辑变化,客户代码尽量不修改,或尽量少修改。

常见的五种创建型模式

单件模式(Singleton Pattern)解决的是实体对象的个数问题,其他的都是解决new所带来的耦合关系问题。

工厂方法模式(Factory Pattern)在工厂方法中,工厂类成为了抽象类,其实际的创建工作将由其具体子类来完成。工厂方法的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中去,强调的是“单个对象”的变化。

抽象工厂模式(Abstract Factory)抽象工厂是所有工厂模式中最为抽象和最具有一般性的一种形态。抽象工厂可以向客户提供一个接口,使得客户可以在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象,强调的是“系列对象”的变化。

生成器模式(Builder Pattern)把构造对象实例的逻辑移到了类的外部,在这个类的外部定义了这个类的构造逻辑。他把一个复杂对象的构造过程从对象的表示中分离出来。其直接效果是将一个复杂的对象简化为一个比较简单的目标对象。他强调的是产品的构造过程。

原型模式(Prototype Pattern)和工厂模式一样,同样对客户隐藏了对象创建工作,但是,与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。

如何选择使用创建型模式

继续考虑上面提到的游戏开发场景,假定在这个游戏场景中我们使用到的有墙(Wall),屋子(Room),门(Door)几个部件。在这个过程中,同样是对象的创建问题,但是会根据所要解决的问题不同而使用不同的创建型模式。

如果在游戏中,一个屋子只允许有一个门存在,那么这就是一个使用Signleton模式的例子,确保只有一个Door类的实例被创建。解决的是对象创建个数的问题。

第6章 创建型模式专题总结_prototype

示例代码:

using System;
public sealed class SigletonDoor
{
    static readonly SigletonDoor instance=new SigletonDoor();
    static SigletonDoor()
    {
    }
    public static SigletonDoor Instance
    {
        get
        {
            return instance;
        }
    }
}

在游戏中需要创建墙,屋子的实例时,为了避免直接对构造器的调用而实例化类,这时就是工厂方法模式了,每一个部件都有它自己的工厂类。解决的是“单个对象”的需求变化问题。

第6章 创建型模式专题总结_产品_02

示例代码:

using System;
public abstract class Wall
{
    public abstract void Display();
}
public class ModernWall:Wall
{
    public override void Display()
    {
        Console.WriteLine("ModernWall Builded");
    }
}
public abstract class WallFactory
{
    public abstract Wall Create();
}
public class ModernFactory:WallFactory
{
    public override Wall Create()
    {
        return new ModernWall();;
    }
}

在游戏场景中,不可能只有一种墙或屋子,有可能有现代风格(Modern),古典风格(Classical)等多系列风格的部件。这时就是一系列对象的创建问题了,是一个抽象工厂的例子。解决的是“系列对象”的需求变化问题。

第6章 创建型模式专题总结_设计模式_03

示例代码:

using System;
 
public abstract class Wall
{
    public abstract void Display();
}
 
public class ModernWall:Wall
{
    public override void Display()
    {
        Console.WriteLine("ModernWall Builded");
    }
}
 
public class ClassicalWall:Wall
{
    public override void Display()
    {
        Console.WriteLine("ClassicalWall Builded");
    }
}
 
public abstract class Room
{
    public abstract void Display();
}
 
public class ModernRoom:Room
{
    public override void Display()
    {
        Console.WriteLine("ModernRoom Builded");
    }
}
 
public class ClassicalRoom:Room
{
    public override void Display()
    {
        Console.WriteLine("ClassicalRoom Builded");
    }
}
 
public abstract class AbstractFactory
{
    public abstract Wall CreateWall();
    public abstract Room CreateRoom();
}
 
public class ModernFactory:AbstractFactory
{
    public override Wall CreateWall()
    {
        return new ModernWall();
    }
    public override Room CreateRoom()
    {
        return new ModernRoom();
    }
}
 
public class ClassicalFactory:AbstractFactory
{
    public override Wall CreateWall()
    {
        return new ClassicalWall();
    }
    public override Room CreateRoom()
    {
        return new ClassicalRoom();
    }
}

如果在游戏场景中,构成某一个场景的算法比较稳定,例如:这个场景就是用四堵墙,一个屋子,一扇门来构成的,但具体是用什么风格的墙、屋子和门则是不停的变化的,这就是一个生成器模式的例子。解决的是“对象部分”的需求变化问题。

第6章 创建型模式专题总结_prototype_04

示例代码:

using System;
using System.Collections;
 
public class Director
{
    public void Construct( Builder builder )
    {
        builder.BuildWall();
        builder.BuildRoom();
        builder.BuildDoor();
    }
}
 
public abstract class Builder
{
    public abstract void BuildWall();
    public abstract void BuildRoom();
    public abstract void BuildDoor();
    public abstract GameScene GetResult();
}
 
public class GameBuilder : Builder
{
    private GameScene g;
 
    public override void BuildWall()
    {
        g = new GameScene();
        g.Add( "Wall" );
    }
    public override void BuildRoom()
    {
        g.Add( "Room" );
    }
    public override void BuildDoor()
    {
        g.Add( "Door" );
    }
    public override GameScene GetResult()
    {
        return g;
    }
}
 
public class GameScene
{
    ArrayList parts = new ArrayList();
    public void Add( string part )
    {
        parts.Add( part );
    }
    public void Display()
    {
        Console.WriteLine( " GameScene Parts:" );
        foreach( string part in parts )
            Console.WriteLine( part );
    }
}

如果在游戏中,需要大量的古典风格或现代风格的墙或屋子,这时可以通过拷贝一个已有的原型对象来生成新对象,就是一个原型模式的例子了。通过克隆来解决“易变对象”的创建问题。

第6章 创建型模式专题总结_游戏_05

示例代码:

using System;
 
public abstract class RoomPrototype
{
    public abstract RoomPrototype Clone();
}
 
public class ModernPrototype:RoomPrototype
{
    public override RoomPrototype Clone()
    {
        return (RoomPrototype)this.MemberwiseClone();
    }
}
 
public class ClassicalPrototype:RoomPrototype
{
    public override RoomPrototype Clone()
    {
        return (RoomPrototype)this.MemberwiseClone();
    }
}

究竟选用哪一种模式最好取决于很多的因素。使用Abstract Factory、Prototype Pattern或Builder Pattern的设计比使用Factory Method的设计更加灵活,但是也更加复杂,尤其Abstract Factory需要庞大的工厂类来支持。通常,设计以使用Factory Method开始,并且当设计者发现需要更大的灵活性时,设计便会向其他设计模式演化,当你在多个设计模式之间进行权衡的时候,了解多个设计模式可以给你提供更多的选择余地。

总结

使用创建者模式是为了提高系统的可维护性和可扩展性,提高应对需求变化的能力!

参考文献:
《设计模式中文版》
《DesignPatternsExplained》
  idior 的《你了解创建者模式了吗? --- 创建者模式详解 》
  MSDN WebCast:http://www.microsoft.com/china/msdn/events/webcasts/shared/Webcast/MSDNWebCast.aspx


作者: TerryLee

标签:总结,专题,创建,abstract,class,void,override,public
From: https://blog.51cto.com/u_130277/6457411

相关文章

  • 每周总结--第八周
    本周进行了期末一些学科的复习。如数据库,数学建模。学习了数据库基础知识,sql语句的基础运行,授权和权限管理,x锁和s锁等等数据库知识。数学建模完成了对初等数学建模,线性规划建模,动态规划建模以及概率建模进行了复习。......
  • 时间序列预测的20个基本概念总结
    1、时间序列时间序列是一组按时间顺序排列的数据点比如:每小时的气压每年的医院急诊按分钟计算的股票价格2、时间序列的组成部分 完整文章:https://avoid.overfit.cn/post/7bc21f124d284b47becbeca6dc5c07c7......
  • 5.28学习总结thread多线程理解
    多线程早在大二刚来的时候就听王建民老师提到过,但是当时觉得多线程肯定很难,而且现在也用不到,就没有接触。现在看来多线程的学习还是比较简单的。下面演示代码均为PythonfromthreadingimportThreadth=thread(target=,args=())#target指向新线程执行的目标函数,args中......
  • 个人总结
    1)回顾查看本学期第1日的计划,我的完成度比较好。从三方面来说。第一方面是结对项目,两个人的地铁查询系统完成度比较好,完成了一个较为完整的地铁查询的安卓APP的开发。而且用到了本机的数据库。和外部的Mysql数据库。第二方面是结对项目。我作为团队的队长带领,我们团队参加了这半年......
  • odoo context上下文用法总结
    环境odoo-14.0.post20221212.tarcontext用法总结获取上下文>>>self.env.context#返回字典数据,等价于self._context{'lang':'en_US','tz':'Europe/Brussels'}>>>self._context{'lang':'en_US',&......
  • 200场面试总结的诀窍,都说好用!
    大家好,我是田哥这段时间忙得飞起,天天忙于学习,忙于模拟面试,忙于和大家聊面试相关的内容。从各位老铁的反馈来看,今年找工作本来就不容易,加上最近两年受到疫情影响,很多公司都在裁员,哎。先不说内卷吧,咱们还是多找找自身问题。古话说的:不打无准备的仗。所以面试前一定要准备,再去面试。面......
  • 6.2总结
    回顾你的课程计划(第一周的计划),你完成的程度如何?请列出具体数据和实际例子。我第一周的计划1.制定一个能执行的切合实际的计划,加强对自己的管理2.通过自己看视频学习Javaweb的知识,自己制定计划学习进度 3.在这门课结束时四人团队完成一个具有软件著作权的软件.......
  • 个人总结
    这是软件工程的最后一次作业,在这里我写上本学期以来的体会和总结。阅读《构建之法》:我已经快速浏览了《构建之法》这本书,其中涉及了软件工程的一些基本概念和原则。我理解了书中讲述的软件构建的重要性以及遵循良好工程实践的必要性。1.软件构建的重要性:《构建之法》将软件构建......
  • 6.1每日总结
    今天准备复习周的考试了,可能有关软件工程专业的内容就是计算机网络实验的部分。在最近的学习中,计网中的内容能很大程度上补足我在软件工程专业学习过程中缺漏的知识储备部分。实验一VLAN一、实验名称交换机划分Vlan配置二、实验目的1.理解虚拟LAN(VLAN)基本配置;2.掌握......
  • 5.20每日总结(补)
     今天和队友总结了第一阶段,主要是验收第一阶段,在第一阶段任务完成后,有优点,也有不足,不足之处我们会根据老师的建议和要求在第二阶段改善,争取做到最好。第一阶段中,由于我们做的人脸识别系统缺少相应场景,在第二阶段中,我们会将产品放在场景中实践,在场景中可以使用,坚决以老师的要求:......