文档章节

我对类工厂模式有了新认识(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

粉丝 60
博文 59
码字总数 85338
作品 4
广州
技术主管
私信 提问
PHP设计模式(一):简介及创建型模式

我们分三篇文章来总结一下设计模式在PHP中的应用,这是第一篇创建型模式。 一、设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用、容易被他人理解的、可靠的代码设...

juhenj
2014/05/15
228
2
简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

转载:原地址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
Java经典设计模式-结构型模式-适配器模式(Adapter)

适配器模式 适配器模式主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。 适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的...

Idea
01/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

eureka多注册中心

eureka分区的深入讲解

miaojiangmin
19分钟前
1
0
RAM SSO功能重磅发布 —— 满足客户使用企业本地账号登录阿里云

阿里云RAM (Resource Access Management)为客户提供身份与访问控制管理服务。使用RAM,可以轻松创建并管理您的用户(比如雇员、企业开发的应用程序),并控制用户对云资源的访问权限。 对云资...

阿里云官方博客
22分钟前
0
0
Mysql 8.0 | #08004Client does not support authentication protocol requested by server

完整报错 #08004Client does not support authentication protocol requested by server; consider upgrading MySQL client 解决方法 Using the old mysql_native_password works:ALTER ......

云迹
24分钟前
0
0
kylin入门到实战

1.概述 kylin是一款开源的分布式数据分析工具,基于hadoop之上的sql查询接口,能支持超大规模的数据分析。响应时间在亚秒级别,其核心是预计算,计算结果存放在hbase中。 2.特性 可扩展超快O...

hblt-j
27分钟前
0
0
vagrant mac 安装和使用

varant 在mac上使用起来非常的方便,具体的下载步骤可以看这里https://segmentfault.com/a/1190000000264347 这里主要是记录一下配置文件 # -*- mode: ruby -*- # vi: set ft=ruby : # All V...

一千零一夜个为什么
27分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部