文档章节

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

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

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

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

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

    为什么呢?因为类工厂隐藏了类的构造过程,并且整个模块里面就只有类工厂是对外公开的访问对象(其他开发人员是没有办法直接调用此模块里面的其他对象的)。其他开发人员只要访问工厂类就能够得到相应的类对象,而不需要关心此模块内部的实现。为了证明此一设计方法的可行性,以下采用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

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

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

wbf961127 ⋅ 2017/11/12 ⋅ 0

C#设计模式(2)——简单工厂模式

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

技术小胖子 ⋅ 2017/11/08 ⋅ 0

简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

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

法斗斗 ⋅ 05/08 ⋅ 0

Java经典设计模式-结构型模式-适配器模式(Adapter)

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

Idea ⋅ 01/20 ⋅ 0

代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

前言 今天我来全面总结开发中最常用的设计模式 - 代理模式中的动态代理模式 其他设计模式介绍 1分钟全面了解“设计模式” 单例模式(Singleton) - 最易懂的设计模式解析 简单工厂模式(Sim...

Carson_Ho ⋅ 04/09 ⋅ 0

设计模式Java Design Pattern-工厂方法模式FactoryMethod

我的博客 一、 设计模式的分类 大体可以分为三类: 创建型模式(5个) 单例模式、原型模式、工厂方法模式、抽象工厂模式、建造者模式 结构性模式(7个) 适配器模式、装饰器模式、代理模式、...

勇敢写信 ⋅ 03/22 ⋅ 0

[设计模式]简单工厂模式

简介 简单工厂模式 (Simple Factory) 又叫静态工厂方法(Static Factory Method)模式。 简单工厂模式通常是定义一个工厂类,这个类可以根据不同变量返回不同类的产品实例。 简单工厂模式是一...

静默虚空 ⋅ 2015/06/03 ⋅ 0

设计模式梳理(一)

设计模式梳理(一) 总体来说设计模式分为三大类: @案例源码地址:https://gitlab.com/lxqxsyu/DisgnPattern 创建型模式 简单工厂模式 工厂类是整个模式的关键。它包含必要的判断逻辑,能够...

lxq_xsyu ⋅ 2017/11/02 ⋅ 0

设计模式的作用

设计模式描述的是软件设计,因此它是独立于编程语言的,但是最终实现仍然要使用编程语言来表达。设计模式不像算法技巧,可以照搬照用,它是建立在对“面向对象”纯熟、深入理解的基础上的经验...

Dwyane_Coding ⋅ 01/22 ⋅ 0

Android 架构师9 设计模式之策略模式

前言 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们之间可以相互替换。这些策略算法是相同行为的不同实现。 需求 三国故事中,刘备要到江东娶孙权的妹妹孙尚香,由于这行...

zhang_pan ⋅ 04/26 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Boost库编译应用

版本:Boost 1.66.0 Windows库编译 官网指南:直接执行bootstrap.bat处理文件即可,可以我却遇到一堆的问题。 环境:Windows 10 + Visual Studio 2017 Boost编译出来库命名 boost库生成文件命...

水海云 ⋅ 12分钟前 ⋅ 0

解决Eclipse发布到Tomcat丢失依赖jar包的问题

如果jar文件是以外部依赖的形式导入的。Eclipse将web项目发布到Tomcat时,是不会自动发布这些依赖的。 可以通过Eclipse在项目上右击 - Propertics - Deployment Assembly,添加“Java Build ...

ArlenXu ⋅ 12分钟前 ⋅ 0

iview tree组件层级过多时可左右滚动

使用vue+iview的tree组件,iview官网iview的tree树形控件 问题描述:tree层级过多时左右不可滚动 问题解决:修改overflow属性值 .el-tree-node>.el-tree-node_children { overflow: vi...

YXMBetter ⋅ 14分钟前 ⋅ 0

分布式锁

1.通过数据库实现 http://www.weizijun.cn/2016/03/17/%E8%81%8A%E4%B8%80%E8%81%8A%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E7%9A%84%E8%AE%BE%E8%AE%A1/ 2.ZK实现:curator-recipes分布式锁的......

素雷 ⋅ 22分钟前 ⋅ 0

Sublime Text3 快捷键

选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本。 Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑。举个栗子:快速选中并更改所有相同的变量名...

AndyZhouX ⋅ 29分钟前 ⋅ 0

XamarinAndroid组件教程RecylerView自定义适配器动画

XamarinAndroid组件教程RecylerView自定义适配器动画 如果RecyclerViewAnimators.Adapters命名空间中没有所需要的适配器动画,开发者可以自定义动画。此时,需要让自定义的动画继承Animation...

大学霸 ⋅ 29分钟前 ⋅ 0

eureka 基础(二)

使用Eureka服务器进行身份验证 如果其中一个eureka.client.serviceUrl.defaultZone网址中包含一个凭据(如http://user:password@localhost:8761/eureka)),HTTP基本身份验证将自动添加到您...

明理萝 ⋅ 32分钟前 ⋅ 1

Kubernetes(五) - Service

Kubernetes解决的另外一个痛点就是服务发现,服务发现机制和容器开放访问都是通过Service来实现的,把Deployment和Service关联起来只需要Label标签相同就可以关联起来形成负载均衡,基于kuberne...

喵了_个咪 ⋅ 32分钟前 ⋅ 0

更新队友POM文件后报错

打开报错的地方的pom及其引用方法所在文件的pom,观察其版本号是否一致,不一致进行更改

森火 ⋅ 46分钟前 ⋅ 0

IDEA使用sonarLint

一、IDEA如何安装SonarLint插件 1.打开 Idea 2.点击【File】 3.点击【Settings】 4.点击【Plugins】 5.在搜索栏中输入“sonarlint”关键字 6.点击【Install】进行安装 7.重启Idea 二、IDEA如...

开源中国成都区源花 ⋅ 51分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部