文档章节

我对类工厂模式有了新认识(ActionScript描述)

vimfung
 vimfung
发布于 2016/06/26 22:01
字数 1585
阅读 39
收藏 2

最近在做架构设计研究时忽然地对类工厂模式有了新的认识,因此把自己的一些设计上的心得跟大家分享。希望可以跟大家共同探讨,废话就少说了,直接就进入主题。

    以前一直搞不懂为什么要有类工厂这种设计模式,因为我之前一直认为他仅仅是把一些类对象构造的功能摆在一起,然后通过工厂类来进行构造对象。这种设计很让我费解,因为他不像单例模式、观察者模式那么易懂。不明白使用了类工厂模式这样做的好处到底是什么,虽然一些资料上有说是隐藏了一些类的构造过程,但是如果我直接调用这些类的构造函数和使用工厂类来构造对象的效果还不是一样吗?(以前我是这样想的。呵呵~)

    经过这段时间的学习,我似乎有点懂了。原来我之前一直想不通的原因是在于我把整个软件设计的过程都集中在一个人的身上了,任何功能化模块化的事情都是以自我为中心考虑了。因此体现不出类工厂模式的好处。其实,如果我们的一个软件当中划分了很多个模块,而这些模块都是由不同的人去负责,当某些功能模块需要提供一组数据模型或者工具类,而又不想把具体的实现暴露给其他人知道时,这时候使用类工厂模式是最佳选择。

    为什么呢?因为类工厂隐藏了类的构造过程,并且整个模块里面就只有类工厂是对外公开的访问对象(其他开发人员是没有办法直接调用此模块里面的其他对象的)。其他开发人员只要访问工厂类就能够得到相应的类对象,而不需要关心此模块内部的实现。为了证明此一设计方法的可行性,以下采用ActionScript脚本进行举例说明(以下代码采用ActionScript3语法进行阐述,在Flash Builder下进行实现)。

假如现在我需要设计一个模块提供一组数据模型给其他模块进行调用,这时候我需要创建一个SWC类库,启动Flash Builder新建一ActionScript库项目。假设有ClassA和ClassB两个数据模型类,其定义如下:

//----------------------------------------------------------------------

//ClassA定义

package{

  internal class ClassA extends Object{

    public functionClassA():void{

      _value=1;

    }

    private var_value:int;

    public function get value():int{

      return _value;

    }

    public function set value(value:int):void{

      _value=value;

    }

  }

}

//----------------------------------------------------------------

//ClassB定义

package{

  internal class ClassB extends Object{

    public functionClassB(value:int):void{

      _value=value;

    }

    private var_value:int;

    public function get value():int{

      return _value;

    }

    public functionset value(value:int):void{

      _value=value;

    }

  }

}

    为了能够尽量说明问题,上面定义的ClassA和ClassB都包含一个属性value,而这个value在构造的时候是有所不同的。ClassA是在构造的时候给_value赋上了一个整型值1,而ClassB在构造时是由构造参数来指定_value的值。大家可能已经注意到了,就是ClassA和ClassB的访问权限为internal(包内访问),并不是public(公开)。这样的做法就是为了防止其他调用此库的模块非法访问库中对外隐藏的对象。

数据模型类已经定义完毕,那么开始定义工厂类,其实这里的工厂类要做的事情很简单,就是把ClassA和ClassB生成对象并返回给调用者。因此,类工厂有如下定义:

//--------------------------------------------------------

//类工厂定义

package{

  public class ClassFactory extends Object{

    public functionClassFactory():void{}

    public static functioncreateClassA():ClassA{

      return new ClassA();

    }

    public staticfunction createClassB(value:int):ClassB{

      return new ClassB(value);

    }

  }

}

    上面的工厂类中分别定义了两个静态方法createClassA和createClassB。分别调用这两个方法可以返回ClassA或ClassB对象。

    从上面的例子来看,是否让你的思路清晰了很多呢?不过上面的例子是存在一点问题的,那就是之前定义的ClassA和ClassB的访问权限定义为internal,所以如果在工厂类中直接返回这些对象是不合法的。那么,有什么办法可以解决这样的问题呢?这时候接口的设计能够帮助我们解决这一难题。接口是用于定义一组公开的方法提供给外部调用,使用接口可以很好地实现内外分离的效果。在ActionScript中一个类可以继续一个或一个以上的接口。以下分别定义了IClassA和IClassB接口:

//------------------------------------------------------

//IClassA接口定义

package{

  public interface IClassA{

    public function get value():int;

    public function set value(value:int):void;

  }

}

//---------------------------------------------------

//IClassB接口定义

package{

  public interface IClassB{

    public function get value():int;

  }

}

    上面所写的就是关于ClassA和ClassB的两个接口定义。这里要分享一点小心得,接口定义的属性或方法不一定要跟类定义的属性或者方法相等,接口只要把外界需要调用的方法定义出来即可。上面写的IClassB就是这样的一个例子,他只定义了value的获取方法,并没有定义value属性的设置方法,也就是说ClassB对于外界来说他的value属性是只读的。

接口定义完毕后,那么类和工厂类要作如下的修改(加粗红色为修改部分):

//----------------------------------------------------------------------

//ClassA定义

package{

  internal class ClassA extends Object implements IClassA{

    public functionClassA():void{

      _value=1;

    }

    private var_value:int;

    public function get value():int{

      return _value;

    }

    public function set value(value:int):void{

      _value=value;

    }

  }

}

//----------------------------------------------------------------

//ClassB定义

package{

 internal class ClassB extends Object implements IClassB{

    public functionClassB(value:int):void{

      _value=value;

    }

    private var_value:int;

    public function get value():int{

      return _value;

    }

    public function set value(value:int):void{

      _value=value;

    }

  }

}

//--------------------------------------------------------

//类工厂定义

package{

 public class ClassFactory extends Object{

    public functionClassFactory():void{}

    public staticfunction createClassA():IClassA{

      return new ClassA();

    }

    public staticfunction createClassB(value:int):IClassB{

      return new ClassB(value);

    }

  }

}

    整个SWC的类库设计到此告一段落。我们把源码进行编译生成SWC库。那么在其他地方我们可以直接把这个SWC进行引入,然后就可以调用了。调用的方法也很简单,调用的代码如下所示:

varclsA:IClassA=ClassFactory.createClassA();

varclsB:IClassB=ClassFactory.createClassB(5);

© 著作权归作者所有

共有 人打赏支持
vimfung

vimfung

粉丝 59
博文 59
码字总数 85338
作品 4
广州
技术主管
系统架构技能之设计模式-单件模式

一、开篇 其实我本来不是打算把系统架构中的一些设计模式单独抽出来讲解的,因为很多的好朋友也比较关注这方面的内容,所以我想通过我理解及平时项目中应用到的一 些常见的设计模式,拿出来给...

wbf961127
2017/11/12
0
0
C#设计模式(2)——简单工厂模式

一、引言   这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式——简单工...

技术小胖子
2017/11/08
0
0
简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

转载:原地址http://www.cnblogs.com/zhangchenliang/p/3700820.html 简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别 结合简单示例和UML图,讲解工厂模式简单原理。 一、引子 话说...

法斗斗
05/08
0
0
Java语言编程学习之Lambda表达式设计和架构的原则[图]

Java语言编程学习之Lambda表达式设计和架构的原则[图]: 大家都知道,Lambda表达式是对Java语言的一点简单改进,在JDK标准类库中,运行它的方式各种各样。但是大多数的Java代码都不是由开发J...

原创小博客
07/17
0
0
23种设计模式(3):抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。 类型:创建类模式 类图: 抽象工厂模式与工厂方法模式的区别 抽象工厂模式是工厂方法模式的升级版本,他用来...

LCZ777
2014/07/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

nginx模块学习六 add_header 跨域访问

语法 Syntax: add_header name value [always];Default: --Context:http,server,location,if in location 例:/etc/nginx/conf.d/default.conf server {    listen       80; ......

Romanceling
今天
0
0
SpringBoot初探

#SpringBoot初探 三种创建SpringBoot项目的方式: 第一种:使用IDEA创建maven项目,选择maven-archetype-quickstart; 第二种:使用IDEA创建Spring Initializer,选择web组件; 第三种:使用...

向码而生
今天
2
0
IO

JAVA中IO技术:BIO、NIO、AIO 1、同步异步、阻塞非阻塞概念 同步和异步是针对应用程序和内核的交互而言的。 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方...

DemonsI
今天
0
0
org.apache.commons 常用工具类

一. org.apache.commons.io.IOUtils closeQuietly 关闭一个IO流、socket、或者selector且不抛出异常。通常放在finally块。 toString 转换IO流、 Uri、 byte[]为String。 copy IO流数据复制,...

sprouting
今天
0
0
linux使用Inotify监控目录或者文件状态变更

基本概念: Inotify 是一个 Linux特性,它监控文件系统操作,比如读取、写入和创建。Inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多。 需求: 1.有一个文件采集进程,...

mickelfeng
今天
0
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部