as3设计模式乱用之工厂模式
好久没写技术相关的日记了,一忙,二懒,三则被这单调的生活熏得没什么感悟。
其实这篇日记早就想写了,项目开发初期的时候,带学生。经常看到那种乱用设计模式的现象。一方面,公司面试人的时候喜欢问设计模式,另一方向设计模式相关的书夸大了设计模式。紧接着的就是一群刚入行的人盲目的崇拜和乱用,感觉用了设计模式就牛逼,用了就脱离菜鸟群体。
好吧,今天蛋痛。先声明,这篇文字纯个人感觉写,我不是博士也不是研究生,不保证观点全正确。
我用一个简单的程序员说法,工厂模式是一个类里面有个工厂,工厂通过switch把字符串转成新建的子对象。
as代码大概如下:
class factory
{
public function createItem(itemName:String):ItemBase
{
switch(itemName)
{
case...
} }
详细的那几个类的网上随便搜,我就不粘贴了。
我想说的是这个模式给我们开发带来的好处有哪些。读过两本关卡设计模式的书,不知是巧合还是不负责的抄袭。两本书为说明工厂的好处都举了个打印机的例子。
按书上说,用工厂的好处是隐藏产品类。如果我需要创建一台打印机,我只需要创建工厂就行。其实这个说法非常别扭,换个说法我只需要打印,我干麻要非要多余找个工厂。尽信书不如无书啊,这摆明就是google翻译忽悠买书人啊。
o'reilly的书(as设计模式)还举了个飞机和子弹的例子。当年刚开始看的时候,是和两个刚出社会的同事一起的。有人表示,很灵活啊,我要创建子弹就从工厂里面创建。其实我那时就很纳闷,我直接new一个子弹就得了。搞个子弹基类,还得建立工厂,建好了还要从工厂里面通过字符串创建。码量多了好多,其结果就是出个子弹而已。这个飞机子弹的例子,我们加个另一个前提就更容易理解了,因为前后端交互,服务端给客户端的是字符串或者是整型,客户端要通过这个字符串转换成子弹显示在场景。如此就不得不用上工厂模式。不过话说回来,既然是不得不用,那书就算不看我们也一样是这样写代码,而看了书的人大多只会用switch。不看的还会用反射和映射。
谈到了这里我想起不只一次听过的话,"用模式,性能会下降些"。其实这句话是有问题的,很多情况下我们是不得不用模式。就如上面说的服务端字段转子弹的例子。所以跟本不存在用会下降不用提升的说法。硬要说会造成性能浪费的话,只能说是乱用,见下例。
这是个奇怪的例子,这串代码是要创建一个按钮显示到界面上。我读旧项目经常碰到这种写法,毕竟一个项目经过的人手多,什么风格都有。
var btn:RedButton = BtnFactory.createBtn(BtnName.RED) as RedButton;
开发者本来只需要一个红色的按钮,但是却弄了个工厂,在工厂里面通过switch来创建。这样做有什么好处?干麻不直接btn = new RedButton();我只能说,死读书害死人。上例这种写法我们也不能说他有错,但是不得不说,浪费这么多代码没换来什么好处。
如果说我们希望一个xml来配置显示产生不同的按钮,那工厂写法是有用的,因为配置文件全是字符串,我们需要字符串来创建不同的按钮。但是自己写的一个项目,并无任何配置的东西,这样硬生生加个工厂不就变成了浪费体力了吗。
搜了很多国外的资料,老外关于as3用是否合适用设计模式进行了不少口水战。而到了国内,就变成了尽信模式,省下了口水。首先我先表明一下自己的关点,本人认为如果追求快速开发,并且对代码严谨性没有强迫证的话,as3的很多设计模式都可以用反射替代。
说起反射这个词,是从java那学来的,详细的作用是通过类的字符串创建实例。在as里面实现比java简单得多。例如:
public function getBut(btnName:String="Button"):Button
{
var cls:Class = applicationDomain.getDefinition("Button") as Class;
return new cls();
}
这个写法也很简单和工厂一样,通过一个字符串来创建子项产品。但是为什么书上不说用反射工厂,却要搞好几个类来连接呢?其实这也是有原因的,因为早年,java刚开始的那几个版本是没有反射这个东西的。别说早年的java,现在的C要实现反射也是件麻烦的事。
举个常用的例子,例如我们要写个列表组件List。列表通过循环创建有子项,每个子项从上到下按Y抽进行排列。我写好了列表之后,给其他人用,别人当然就不希望再重新写一次子项创建和Y排列啦,但是他们要显示的子项是不一样的。相信开发过一个项目的人都知道,在列表里面用一个Class类型的变量存子项类型,循环创建子项可通过这个变量来创建子项。
大致代码如下:
var ls:List = new List();
ls.itemClass = OtherItem;
ls.data = [11,22,33];
在这里我提个假设,如果不用Class变量来反射的话,(也就是不准用Class类型的变量)。别人要用你写的List类,但又要产生不同的子项,要怎么办?
这种情况下我们可以写一个protected方法来创建子项,别人用的时候就新建一个List2和一个自己的MyItem,继承于List,然后覆盖掉那个protected方法来返回新子项MyItem。这个方法比较简单就不上码了,至于叫什么模式我不记得了,毕竟不是搞学术,唉。
还有另一种方法就是搞模式的人最喜欢用的,定一个工厂方法接口IItemFactory,这个接口有一个创建子项的方法,List里定一个接口变量。别人扩展的时候新建一个子项工厂接入那个IItemFactory,然后实现那个方法返回一个新的MyItem。(写完这段,发现自己表述水平真有限,算了,上码吧)。
//IItemFactory代码
class IItemFactory
{
function createItem():ItemBase;
} //ItemFactory代码:
class ItemFactory implements IItemFactory
{
public function createItem():ItemBase
{
return new MyItem();
}
} //List部份代码:
class List
{
...
public var itemFactory:IItemFactory; for (var i:int = 0; i < data.length; i++)
{
var itm:ItemBase = itemFactory.createItem();
...
addChild(itm);
}
}
//使用代码
var ls:List = new List();
var itmf:IItemFactory = new ItemFactory();
ls.itemFactory = itmf;
ls.data = [11,22,33];
...
怎么样,很复杂吧。这就是命贱不用反射,硬生生要用工厂的后果。呵呵~~
这两个例子算是把反射替代工厂好处说完了吧。下面想说一下严谨性这个东西。虽然我目前是搞as3的,但说句实话,as3的语法确实不如java严谨,java有一个叫做泛型的东西,泛型用得好的话,项目在编译之前就几乎把bug找完了。as3的Vector硬搬了泛型这个概念,相比全抄这概念的C#算是弱暴了。
举个例子,List中的itemClass属性能赋值任何类型,如果赋值对象不是显示对象的话,我们只有在项目运行的时候,调整这个List才能知道这个赋值有问题。java的泛型解决了这点,直接来个Class<DisplayObject>这样的变量,如果赋值的不是显示对象,那在项目编译之前就会报错了。
as3没有严格的泛型,所以有严谨性强迫证的同学,就宁愿弃反射而用工厂。因为工厂方法也是可以在编译之前报错的。详细的我就说不了太多,自己也不知道自己是否研究的到可以吹的程度。
C语言是没有反射,java是早期的版本没有反射(本人研究不算深,纯属听说)。Adobe在设计as的时候很多高级语言里复杂的东西都被简化了,我们干麻还非要走回高级语言那个套路呢。
as3的Object已经包含有了HashMap的功能,但有些人还是硬生生的又搞一个HashMap类。里面又是一堆看着蛋疼的代码。算了,扯远了,就写这么多。下次有空再扯一下设计模式之接口乱用。以博主懒散的更新的速度,不知道是哪个朝代咯。
as3设计模式乱用之工厂模式的更多相关文章
- java设计模式-----1、简单工厂模式
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,简单来说 ...
- headfirst设计模式(5)—工厂模式体系分析及抽象工厂模式
先编一个这么久不写的理由 上周我终于鼓起勇气翻开了headfirst设计模式这本书,看看自己下一个设计模式要写个啥,然后,我终于知道我为啥这么久都没写设计模式了,headfirst的这个抽象工厂模式, ...
- Java设计模式(1)工厂模式(Factory模式)
工厂模式定义:提供创建对象的接口. 为何使用工厂模式 工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见. 为什么工厂模式是如此常用?因 ...
- 设计模式之单例模式与工厂模式的Python实现(二)
2. 工厂模式 工厂模式是创建型设计模式的一种.核心的思想是,通过传递给类或函数某种产品的信息来创建产品并返回.当我们想得到产品a对象,只需把产品a的名字传递给工厂函数就能得到产品a对象.而核心思想的 ...
- 重学 Java 设计模式:实战抽象工厂模式
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!
- Java设计模式(5:设计模式的分类及工厂模式详解)
一.设计模式的分类 总的来说,设计模式可以分为三大类:创建型模式.结构型模式.行为型模式,具体如下图: 二.工厂模式 工厂模式分为简单工厂模式.工厂方法模式和抽象工厂模式.其中简单工厂模式并不属于23 ...
- C#设计模式系列:简单工厂模式(Simple Factory)
1. 简单工厂模式简介 1.1 定义 简单工厂模式定义一个Factory类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类. 简单工厂模式只需要一个Factory类. 简单工厂模式又 ...
- Net设计模式实例之简单工厂模式(Simple Factory Pattern)
一.简单工厂模式简介(Bref Introduction) 简单工厂模式(Simple Factory Pattern)的优点是,工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类, ...
- 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则
加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...
随机推荐
- React routerV4 笔记
React routerV4 笔记 一.基础路由示例 import React from 'react' import { BrowserRouter as Router, Route, Li ...
- springboot——数据层访问搭建 集成Duid连接池
springboot中默认是使用的tomcat的连接池,如果我们想要第三方的连接池,我们这么配置呢? 首先在application.yml文件中注释掉之前数据库的配置,重新用druid的方式配置: # ...
- $.queue() 与 $.dequeue() -- 队列
JQuery 运用队列为动画模块服务,但好像它应该有更多用处,我觉得的,那试试就知道咯. 简单的来讲,它就是形成队列和出列, 也就因此可以进行很有规律的回调和延时了呀(暂停感觉有难度),当然这就是后面 ...
- Nginx配置中last和break及permanent和redirect的区别
一.不写last和break 流程就是依次执行这些rewrite rewrite break - url重写后,直接使用当前资源,不再执行location里余下的语句,完成本次请求,地址栏url不变 ...
- 前端常用js脚本
常用js整理 //获取Url中的参数值 function getQueryString(name) { var reg = new RegExp("(^|&)" + nam ...
- Unity发布安卓后,安卓输入键盘字体白色
项目里需要用到显示手机电池电量的,但是又不想写安卓,倒jar包,还要做配置,还要写IOS,好麻烦的说.一查,unity后期版本有这个API,索性就升级高版本的了.但是遇到个小问题,那就是安卓输入的时候 ...
- python脚本发送电子邮件
#!/usr/bin/pythonimport smtplibimport stringHOST='smtp.qq.com'#HOST='mail.qq.com'SUBJECT='Test email ...
- Linux 配置 SSL 证书
完整的 SSL 证书分为四个部分: CA 根证书 (root CA) 中级证书 (Intermediate Certificate) 域名证书 证书密钥 (仅由您持有) 以 COMODO Positi ...
- 提高MySQL效率与性能的技巧
为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的.当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存 ...
- 解决fasterxml中string字符串转对象json格式错误问题
软件152 尹以操 springboot中jackson使用的包是fasterxml的.可以通过如下代码,将一个形如json格式string转为一个java对象: com.fasterxml.jack ...