求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
快速理解设计模式之创建型设计模式
 

发布于2013-5-17

 

导语:本文将教大家一个快速理解设计模式的方法,以及如何自己通过日常生活来体会设计模式。

前言:虽然这个方法有让大家为了用设计模式而学习设计模式的嫌疑,或者不能让你完全意义上的理解设计模式,但是我认为先要学会用然后在把它变成自己的东西吧,怪咖们也是从这个过程走出来的,除了最早提出设计模式的J。好了废话少说,直接上内容。

内容:我们设计高楼、桥梁都会先用前人积累的知识技术画好图纸,然后建设,所谓站在巨人的肩膀上前进才会有进步。设计模式也是一样,我们先要UML建模,然后根据模型编程,OK过程很简单吧。如果UML类中的一些继承、组合、聚合、关联关系不太清楚可以去网上查一下。我要教大家的就是用前辈设计好的各个设计模式的UML模型,编程。这样即使忘了某个设计模式的意义,下次直接看UML模型就可以了,哈哈。

1.创建型设计模式:

说到创建模式那就是创建对象了,是不是和工厂生产产品一样呢?YES。所以简单工厂、工厂方法、抽象工产就这么得名了。其实工厂方法和抽象工厂就可以理解为是简单工厂的改进,我们设计桥梁也会对图纸改进吧。

1.1简单工厂:

1.1.2简单工厂建模

想想,如果我们要对一个工厂的生产进行建模,应该怎么设计呢?简单点就该这么画吧,(我用类似UML模型来描述)。

1.1.3 伪代码

总结:上述就是简单工厂的模型和代码框架了,如果一时忘了简单工厂可以按照上面的思路快速恢复记忆,哇,其实这个思想我们在生活中到处都是吧,所以只要你能想到和创建、生产相关的都可以用简单工厂来实现。

1.2工厂方法模式

简单工厂思路是简单,正常人都是这么想的。可是我们毕竟是编程的,伟大的程序员!看到简单工厂中表达依赖关系的这块代码你是否会皱眉呢?Bad taste!伟大的Programmer会告诉你,代码中不要出现switch语句,你会问why?Sorry,maybe you can google...

所以我们要把代码进行重构,希望能去掉switch。如果我们把每个产品的创建都放在各自的工厂中,就不需要判断了吧,试试建模:

好啦,我们现在来写一下伪代码:

总结:上述是对简单工厂的改进,就是我们熟知的工厂方法模式,记住了它的由来,那么这个模式就很好理解啦。

1.3 抽象工厂设计模式

前面我们讲解工厂就只考虑了所有的产品都是由一个工厂来生产,想想这个工厂的老板是不是赚疯了呢?现在竞争这么大,你这个赚钱当然会有很多其它的厂家也会来生产你的产品,太不厚道了这些人,哈哈我们建模试试呢。

上图中工厂和竞争工厂同时创建产品A,这个在代码中改如何表达呢?怎么知道产品A是哪个工厂创建的呢?现实生活中,一个产品肯定有厂家说明的,所以我们对上述模型稍加改进一下,给每个产品加上商家说明。

哈哈,看到上面的模型是不是非常激动,好啦,我们现在来写写代码:

上述就是抽象工厂的UML模型和代码逻辑了,通过推理一步步得到该设计模式,相信不会这么容易忘记吧。

在上篇,给大家介绍了简单工厂、工厂方法、抽象工厂3种创建者模式,这3种设计模式如果没真正理解,就很难弄清楚他们的区别。文章没有采用大多数介绍设计模式的篇章介绍各个设计模式的优点、缺点、应用场景,原因是我看过很多关于这样的文章,可是后来一点印象也没有了,而且感觉越看越高深,思想本来挺简单的。我想记录我对设计模式的理解,记录让我真正对某一个设计模式豁然开朗的那种感觉。接下来我们看看创建型模式中的单例模式、建造者模式、原型模式。

1 单例模式

单例模式通俗一点讲就是独一无二的我,只提供一个访问点给你访问我。

例 1:一颗树上有很多苹果,那么苹果这个类就有很多个实例了,所以不能用单例模式。

例 2:一个公司只有一个boss,那么任何职员需要和boss会话,都是和同一个boss会话。

从例2中我们知道,只有一个boss,boss需要提供一个让所有的员工都找到他的方法,找到他就可以和他会话了。我们来UML建模看看。

根据上面的模型,我们来写写伪代码:

单例模式最核心的思想就是把构造函数改为私有private,来实现有且仅有一个实例。

我们讨论设计模式肯定是编程用的,所以我们会遇到多线程这些问题,那么在多线程的时候上面的代码可能就不能保证Boss只有一个了,应为他们可能同时调用findMe,怎么解决这个问题呢?我们会想到加锁。YES。加锁之后如果一个线程A在访问findMe,那么线程B就只能等待了,等线程A解锁之后,线程B访问findMe时由于对象已经创建,所以就不会再重复创建。我们来看看代码:

上面这个代码是由于有多线程这个概念所以我们进行了改进,和设计模式的思想没有关系,看我们编码的功底了。

高手看到上面加锁的代码是不是又有疑问了,当多线程访问findMe()的时候,如果Boss这个实例不为null,由于加锁的原因使得线程需要排队来返回实例,是不是不好呢这样,该怎么解决这个问题。这个好解决,我们判断一下Boss是否为空,如果为空就加锁,不为空就不加锁,就可以解决这个问题了。改进代码如下:

单例扩展:

上述的对象的创建都是在findMe中实现的,我们可不可以在Boss声明的时候直接new呢?答案是可以的,首先我们了解一下sealed、readonly关键字。

readonly常量只能声明为类字段,支持实例类型或静态类型,可以在声明的同时初始化或者在构造函数中进行初始化,初始化完成后便无法更改。

sealed 修饰符可以应用于类、实例方法和属性。密封类不能被继承。

单例另一实现方法如下:

2 建造者模式

建造者模式我的理解就是某某指挥某某做事情。

那我们就对某某指挥某某做事情进行UML建模吧。

下面我们来实现代码:

首先有事情这个对象:

然后是工人相关的对象:

好啦,这些对象都创建好了,就剩下指挥者了,注意了指挥者是指挥某人做事情,这个也要表达出来,我们看看实现。

效果:

效果:

总结:只要我们清楚建造者模式表达的思想是某某指挥某某做事情,那么遇到相似的场景我们都可以用建造者模式,比如以前网上经常举建造者模式例子 如麦当劳、肯德基,收银员点餐、工作人员出餐就是这个思想。

3 原型模式

我们前面已经讲了5种创建型模式了,最后还剩下原型模式。原型模式怎么理解呢?我想大家都知道克隆吧,就是复制一份或者多份一模一样的出来。建模就这样画吧。

原型模式比较简单,相信大家以前看过原型模式讲解的例子也明白了,需要注意的就是浅拷贝与深拷贝的概念。声明:这两个概念和原型设计模式的思想无关,只是因为我们开发语言中有值类型和引用类型导致的。

浅拷贝:通俗一点讲就是引用类型的对象不能被拷贝。

深拷贝:通俗一点讲就是提供了引用类型对象不能被拷贝的解决方案。

我们来看看代码:

浅拷贝克隆:

效果:

看到了吧,如果是浅拷贝,克隆的对象对引用进行赋值,都是对同一个引用对象进行赋值,所以显示出来的结果也是一样的。

深拷贝克隆:

为了达到真正的完全克隆,我们的解决办法是把引用对象也进行克隆

调用:

效果:

看到上面的结果是否激动了一番,终于实现完美的克隆。好啦,创建型模式就讲到这里了。

我们回顾一下创建型设计模式有哪几种呢?

  • 简单工厂 这个工厂可以生产各种产品
  • 工厂方法(为了解决简单工厂中switch坏味道)
  • 抽象工厂(为了解决几个工厂同时生产某个产品的问题,同时给每个产品加上厂家说明)
  • 单例模式 独一无二的我,只提供一个访问点给你访问我
  • 建造者模式 提供某某指挥某某做事情的模型
  • 原型模式 提供克隆技术给你快速拷贝。

 
分享到
 
 


重构-使代码更简洁优美
Visitor Parttern
由表及里看模式
设计模式随笔系列
深入浅出设计模式-介绍
.NET中的设计模式
更多...   

相关培训课程

J2EE设计模式和性能调优
应用模式设计Java企业级应用
设计模式原理与应用
J2EE设计模式指南
单元测试+重构+设计模式
设计模式及其CSharp实现


某电力公司 设计模式原理
蓝拓扑 设计模式原理及应用
卫星导航 UML & OOAD
汤森路透研发中心 UML& OOAD
中达电通 设计模式原理
西门子 嵌入式设计模式
更多...