创建型设计模式总结

顾名思义创建型设计模式自然就与对象的产生有关了。而对类实例化为什么我们还要使用设计模式,而不是像往常在编程时用哪个类就直接实例化哪个类呢?这是因为我们在要考虑软件的灵活性,还有就是为满足一些即将被实例化的类的特殊要求。总之这种设计模式是解决类的实例化过程中遇到的问题的。

 

一、各个模式的含义

1、工厂方法(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法模式使一个类的实例化延迟到其子类。

2、抽象工厂(Abstract Factory Pattern)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

3、建造者模式(Builder pattern)将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

4、原型模式(Prototype Pattern)用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

5、单例模式(singleton Pattern)保证一个类仅有一个实例,并提供一个访问它的全局访问点。

二、各模式的重点类的实现

1Builder Pattern :具体的建造类(concreteBuilder)负责对象的创建,和必要初始条件的填充。这一步其实就是在concreteBuilder类里new了一个要新建的对象,并在这个类里设置了新new的对象的一些方法或属性等,这样这个过程就不必在客户端里知道了。

2Prototype Pattern的重点主要是原型类(prototype)实现了接口ICloneableclone方法。这里就涉及到浅层副本和深层副本的问题。我们可以利用.netobject类自身的方法MemberwiseClone对某个类创建浅副本。此方法的实现其实就是在此方法中新建一个浅副本的原类,然后将原类中的值类型赋值给此副本,然后使此前副本引用原类中的引用类型。之索引称之为浅副本,也就是因为他并未真正的完全复制了原先的类,而是原先类型同这个浅副本共同引用了原类型中引用类型。创建深副本其实就是将我们在原型中引用的类型,在创建原型的副本时也同时创建该引用类型的副本,而不是只是引用该类型

以下是浅复制的示意图,深复制中副本不会像途中所示引用原型中的应用类型。

3Singleton Pattern 中依据类是否实例化过来决定该类是否可以new,其中的判断条件有两个:if(ftb==null || ftb.isDisposed)我们要注意只有ftb是窗体类时才在我们的代码中涉及到disposesingleton Pattern 为的就是只实例化一个,但要是有多个进程同时来使用这段代码时则不能确保只实例化一个了,这时我们就需要加一把锁lock,同一时刻只允许一个进程来使用该代码。

在这个模式里就涉及到多线程的问题了,不多做深究,但有几个类得知道(threadmonitor等),并且得将c#对此模式的实现转化成VB.NET对此设计模式的实现。在C#中只需lock(写入一个对象){这里的代码将在同一时刻只允许一个线程访问}。而在vb.net中则使用的synclock

至于c#设计模式中提到的饿汉式单例模式的实现使用了关键字sealed,而此关键字对应在vb.netNotOverrideable,此关键字不能用于声明类,故而尚未发现在vb.net中如何实现饿汉式单例模式。虽然我们之前的懒汉式单例模式中会有多线程问题,但是用synclock已得到解决。

三、比较

(一)简单工厂、工厂方法法、抽象工厂

可以说这三个模式都做到了去除客户端与具体产品的依赖关系,但我们不能完全说这三个模式是层层递进或逐步完善的。先解释后一句话的原因:

简单工厂的最大优点就是工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类。但这也恰恰是简单工厂的弊端。因为Factory类在封装逻辑判断的同时,也对修改开放了(我们要向生产其他的产品,就必须得修改Factory类),这违背了开放封闭原则。

为了使Single Factory Pattern 对修改封闭对扩展开放,我们引入了工厂方法模式(Factory Method Pattern)。这种模式使生产产品的过程延迟到了子工厂中,客户端类调用子工厂生产产品,这样便将single Factory Pattern中的判断转移到了客户端。虽然解决了简单工厂中Factory类判断的弊端,但这却是一种治标不治本的做法。

其实解决这个问题关键不是应用另一个设计模式(包括Abstract Factory Pattern),而是应用反射技术来解决的。反射技术能够解决这种分支判断的问题,也就是说我们无论我们用Single Factory Pattern还是用Factory Method Pattern,只要在反射技术的配合使用下,都可到到相同的效果。

Factory Method PatternSingle Factory Pattern中的问题上移到了客户端,实质上这两个模式是同级别的,都存在类似问题。我想这也就是为什么两个模式没有同时放到23种设计模式的原因。(解释到这,我们便清楚这两种模式都不能完全说是逐步完善的)

那么抽象工厂模式是解决什么问题的呢?这一点从抽象工厂与工厂方法含义的对比中我们会有所领悟。虽然两种都是提供一个创建对象的接口,但抽象工厂是提供的创建一系列相关或相互依赖对象的接口,而工厂方法则不是。从它们的类图中可以看出,抽象工厂创建多个不同接口下的类,工厂方法则是创建单一接口下的类。

抽象工厂同时也带有Single Factory PatternFactory Method Pattern中的问题,此外由于它的工厂过多,使我们在实例化工厂尤其是要修改时产生了问题,这时我们便用简单工厂模式来修改了一下抽象工厂,再加之反射和配置文件的应用使我们的抽象工厂模式完善了许多。

不过这三个模式有着很大的联系,而从客户端来说,这三者都将客户端与其所需的类松耦合了。这一点靠的就是每个工厂在生产类时只是返回一个接口类型,这样在客户端只要有个接口类型就可以生产产品了,而不用管产品是哪个工厂生产的(即具体的产品是什么)。

(二)建造者模式(Builder Pattern)和 原型模式(prototype Pattern

这两个模式所生产的对象似乎都与生产之前的某些东西有关。那么究竟这两个模式所实例化的对象与该对象产生前的那些因素有关呢?下面对比说明:

Builder Pattern是说所要实例化的对象的构建与其表示分离,而prototype Pattern则是将原型中的内容拷贝到要新实例化的对象中。其实就是在说,Builder Pattern要创建的对象有些是在实例化的时候就要加上的初始化值,而prototype Pattern则是用于用户操作了已经实例化的对象,如果我们在其他地方也需要这个类的实例,并且需要知道用户对它填充了哪些数据的情况,如在机房收费系统中有一个Saving类来保存必要的数据,无论我在哪需要实例化Saving,该类所保存的值都要知道这时就和有必要对其进行拷贝了。也就是说前者是说前者是对象本身的要求,后则是对用户操作的复制。

 

四、总结

我们在实例化类时,可能要求它(它们)与客户端松耦合,也可能要求它(它们)容易被替换(工厂模式组),还可能要求这个对象与这个类已有对象的内容相同(prototype Pattern),再有就是这个类有复杂的构建过程需要与其表现分离(Builder Pattern)和只允许实例化一次该类(singleton Pattern),下面从两大方面概述:

 

从依赖关系上看:

(一)客户端与产生的对象不依赖

1、产生一个接口下的类(Factory Method Pattern

2、产生多个接口下的类(Abstract Factory Pattern

(二)客户端与产生的对象相依赖

1、客户端完全拷贝所依赖的对象(prototype Pattern

2、对客户端隐藏实例化对象的细节(Builder pattern

3、只允许实例化一次(singleton Pattern

从创建时间和数量上看:

(一)从无到有创建

1、创建一个接口下的类(Factory Method Pattern

2、创建多个接口下的类(Abstract Factory Pattern

3、一次性实例化(singleton Pattern

(二)从有到多的创建

1、纯复制(prototype Pattern

2、实例化过程相同(Builder pattern

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值