07
May
2011

背着自行车爬山……

标签: 骑行
03
Oct
2010

细说用例图中的关系

UML的用例图(Usecase Diagram)是一种很好的捕获需求的方法(比起古老的CRC),但在实际运用中却很少有人 真正能正确地使用它们。这次我要讲的是用例图中include、extend、generalizaion与association四种常见关系的用法......

阅读全文>>

02
Sep
2010

使用Command与Factory模式消除业务代码中的if,else语句

商业软件的一个特点就是拥有众多的业务逻辑,在进行一次操作时都会检查若干业务约束(如是否已登录等)。一般的方式就是采用 大量的if+else进行判断。

if (condition) {
    // do something
    return false;
} else if (condition) {
    // do something
    return false;
} else if ...
return true;

这样的问题在于,代码非常庞大,且难于理解,更不要谈复用了。这里我介绍一种采用Command与Factory模式的解决方案。

首先介绍一下我的设计,UML Class Diagram如下:

屏幕截图 2023-11-02 143358.png

首先应该注意的是,每个业务约束(Constraint,以下简称C)都对应一个对应的处理(Handle,以下简称H),我把它们称为业务约束单元,所有业务约束单元共同构成了一个约束集 A={{C1,H1},{C2,H2}....},这样,对次对一个业务操作的限制判断使变成一个有序集的遍历过程,形象地说,就像一个pipeline,每个业务约束也就是里面的valve,只要一个valve失败,就不能达到终点 执行相应的业务操作,同时还要执行对应的H。因此,上面中你能看见名为“*pipeline”和“*valve”的类,它们就是对应的集与单元。

但是每种约束单元都有自己固有的C与H,需要进行动态方法调用,这里我使用了Command模式(实际上就是利用了OO的多态性), 在图中可以看见名为BizCrstValve的接口(Interface)与其下属的实现方式,也就是说,程序只管调用BizCrstValve里的canPass与doHandle方法,具体怎么实现,是由接口的实现类来确定的,程序要做的就是像 接口发送一个命令而已(就是为什么叫Command模式的原因)。这样,我们可以把所的valve都存在一个List里面,然后对其遍历,调用每个valve的canPass与doHandle命令,如果某一个valve的canPass返回 为false,则执行它的doHandle命令。

public Result perform() {
  for (BizCsrtValve valve : valves) {
   if (!valve.canPass(params)) {
    return valve.doHandle(params);
   }
  }
  return new Result(true);
}
随着valves的遍历,业务约束还在一个一个地查检,一但有一个业务逻辑失败,对应的操作就会激活。

这里再说一下 BizCrstTypeEnum,由于我们已经将一个业务约束的C与其H封闭在一个 valve 中,那么它们完全就是高度可复用的了,因此, 可以给每个 valve 对应一杖举变量,这种我们就可以通过枚举变量来获得对应的 valve 了。如下:
BizCsrtTypeEnum.GOLD_USER_ONLY.getValve();
每个valve有自身的检测与处理机制,如下:
@Override
 public boolean canPass(Map<string, object=""> params) {
  try {
   int userID = (Integer) params.get(GoldUserOnlyValve.PARAM_USER_ID);
   if (userID == 12)
    return true;
   else
    return false;
  } catch (Exception e) {
   return false;
  }
 }
 @Override
 public Result doHandle(Map<string, object=""> params) {
  Result rs = new Result(false);
  rs.setBlockedValveType(BizCsrtTypeEnum.GOLD_USER_ONLY);
  
  return rs;
 }
在这里,枚举变量还有另外一个作用,那就是显示valve的错误信息,一个业务约束失败了我们总得给用户一个原因吧。

好了,现在还存在一个问题,那就是有线约束的H需要参数,而且,可能存在这么一种情况,那就是几个约束可能使用相同的参数, 如果每次都交给约束自己去生成的话,那岂不是太浪费了?明明可以复用的嘛。那我的方案就是在遍历所有valve前将所有valve需要的参数放入到一个map里面(你要调用你自己知道,你理所当然知道所有valve 需要哪些参数)。问题在于每个valve如何从map里面取出自己想要的参数?这里我认为,每个valve最了解自己需要什么参数,因此,每个valve有责任告诉调用着自己需要什么参数,正因为此,你才能在上面的 UML图里看见GoldUserOnlyValve这个类中存在一个PARAM_USER_ID的static变量,它表示这个valve需要一个名为user Id的变量,要使用“userID”来进行映射,如下

params.put(GoldUserOnlyValve.PARAM_USER_ID, 11);

在类图里还有一个名为Result的类,他的作用是存储一些valve失败时的信息,里面有个map,目前没有什么作用。

最后,总的流程如下:

屏幕截图 2023-11-02 144028.png

现在,你再也不用写文章开头的那种代码了,只需要:


BizCsrtPipleline bp = new BizCsrtPipleline(params, BizCsrtTypeEnum.NEED_LOGIN.getValve(),
    BizCsrtTypeEnum.GOLD_USER_ONLY.getValve());
  Result result = bp.perform();
valve的添加顺序就是你的约束检测的顺序,现在是不是清爽了许多?

21
May
2010

终局

标签: 反省

恢复出来的文章,写于2010年6月 。让我想起一句话,当你觉得自己当年傻逼的时候就是你成长了的时候。



正如有开始就会有结束一般,美丽的邂逅亦终迎来伤感的离别(呃~好肉麻)。转眼间4年的大学生涯就结束了,现在回想一下,还是有很多有意思的事。是该给4年大学生活画上句号的时候了。

虽然有些时候会发一些牢骚,但自从拿到录取通知书那天起,我的人生就与川大走在了一起。前些时候,我一寝室的同学开玩笑对我说:“不管你对川大有多大的意见与不满,你身上已经打上了川大的铬印。”当时我回道:“我就说我是个无名小本科就行了!”现在想起来确实也如我同学说的那样,没法啊。说来也搞笑,当年高考的时候下了决心不去川大,结果最后还是来了川大,说到底还是实力不够啊。

这4年,相处时间最长的还是寝室的那些哥们了,虽然时不时会闹一些矛盾,但总的来说还是一团和气。毕竟,各有各有想法。毕业了,现在大家都各奔东西了,以后见面的时间也不多了。想像一下,10多年后,看来军训时那年轻的面庞,会是什么感想呢?

说到寝室的兄弟们,我们学校是3室1厅的那种宿舍,所以有12个同学一起生活,大家都来自四面八方,却不约而同地聚在了一乞,所以还是有缘分啊!希望他们能在自己的道路上走得更高更远。

大一的时候由于对学生会充满了好奇,一口气加了两个组织,一个科技部,一个学习部。现在想起来真是无聊至极,也许是我们学校学生会太烂的原因。在我的印象里,学生会除了搬下展板,操作一下投影仪好像就没别的事。校学生会更搞笑,每学期多半只有两次会,第一次就是说新学期开始了,要有个计划什么的,第二次就是叫大家好好复习,准备考试。最无语的是,大一的时候被学长一顿忽悠,没怎么顾成绩,导致大一的成绩超烂,现在想起真是后悔莫及。我看,在中国20年内还是不要扯什么综合素质了。事实已经证明,考试牛B的才是老大~至少在保研的时候^_^

大二大三的时候由于没有组到好的队伍,本来有很多想法都没有实现,现在想起来也不怪谁,还是自己不善于组队,队伍里面的人员分布太不均衡(只有牛人,多半会打架~),好在在大三最后时期也是找到了几个伙伴。真是不容易啊。

总结一下4年的生活:

  • 写了40729 行JAVA代码
  • 写了33260 行C/C++代码
  • 写了12124 行C#代码
  • HTML,JavaScript,CSS 共25523 行
  • 通读了《过程模式(上)》、《Don't make me think》、《软件再造》、《UML用户指南》、《UML与模式应用》、《交互设计之路》、《Aspect Oriented Software Development》、《AJAX on JAVA》、《Desjgn Patterns》、《中国崛起及其战略》、《中国向赌博说不》,还有一些工具书性质的,比如《Spring in Action》就不提了,还有一些半途而废的,感觉还是少了一点。
  • 成型的软件有:基于GDI+的斗地主游戏、基于SSH的考试试卷生成系统、基于JS的SlideShow、基于MFC的邮件客户端、基于OPENGL的太阳系、可编程智能计算器、JAVA实时缩微图生成、我的个人网站第一版,我的个人网站第二版(你正在看的),基于贝叶斯的拼写检查
  • 得过3次奖学金,二次综合3等,一次单项二等。
  • 没考上理想之校,南京大学(有点不服气,可霓会再战一次)
  • 打了4年光棍
THE END


21
Jul
2009

使用PowerShell自动化您的工作

PowerShell是Microsoft推出的自动化CLI终端及其对应脚本语言,它最早出现在03年9月的开发者大会(PDC)上。PowerShell虽说是脚本语言,有点像UNIX的Bash脚本,但其远远超过Bash脚本(个人感觉),因为PowerShell是完全对向对象的,而且与.NET高度集成,也就是说你可以轻松访问.NET库。因此,使用PowerShell不仅可以自动化一些常见的过程,而且甚至可以编写.NET程序,这一点也不夸张。PowerShell的cmd-let可以轻易对PowerShell进行扩展,而且由于面向对象的原因也易于编写。


PowerShell的主界面


PowerShell最新的版本是2.0.只有Windows 7 Professional以上及Windows Server 2008 R2才附带,Windows XP SP3, Windows Server 2003 SP2,!Windows Vista SP1与Windows Server 2008您需要手动下载,其地址:http://support.microsoft.com/kb/968929,当然,你先要安装.NET。

当然,您如果想对PowerShell进行进一步的了解的话,可以去Wikipedia上的专题,地址为:http://en.wikipedia.org/wiki/Powershell。现在我们就来做一个自动清除下载文件的脚本,假设我们的下载文件都储存在“D:\tp”中。由于我们需要使用事件功妮,因此我们得给启动命令上加上“-sta”,至于为什么可以去百度一下。如下图。

给启动命令加上-sta


启动自带的PowerShell ISE开发环境来进行开发。出于安全方面的考虑,现在你还不能进行本地脚本,须要更换安全级别,详见:http://technet.microsoft.com/en-us/library/ee176949.aspx。下面我讲述一下几个关键步骤,文章尾部附带有源代码,大家可以自行研究。我们设计系统会给用户一个提示,如果用户没有在规定的时间来取消,就进行清除工作,然后显示该盘的剩余空间。那么首先我们须要加载.NET的Form库。

## Load the window lib
[void] [System.Reflection.Assembly]
::LoadWithPartialName("System.Windows.Forms")
对于对用户进行提示这块,我们当然想到了最友好的气泡提示窗口。我们就要创建几个对象,依次为下载地址、所在盘、与气泡窗口,如下:
## This is the!location of your download files
unregister-event *
$fileLocation = "D:\tp"
$diskLabel = "D:"
$notification = new-object System.Windows.Forms.NotifyIcon
然后注册一个事件,来监听NotifyIcon的Click事件。
## Register a click event
register-objectevent $notification BalloonTipClicked
 -sourceIdentifier click_event
这里的register-objectevent是关键字,$notification是我们的窗口变量,BalloonTipClicked是要监听的事件,最后一个是该次监听的ID,以后会用。我们等15秒来让用户解决是否要取消本次操作。
## Wait for the onClick event
wait-event -sourceIdentifier click_event -timeout 15
然后看看消息队列是有没有我们要要的东东。
## Chech if the event occurs
$flag = get-event -sourceIdentifier click_event |
 where-object {$_.sourceIdentifier -match "click_event"}
。之后我们就可以根据〈b>flag的内容来决定是否要进行删除了。有时候我们要保留一些文件,那就把他们放在“saved”中,用以下删除命令就可以了。
rm $tp_1 -r -fo -exclude "saved"

那么最终效果就是这样的了。 Windows 7及Vista用户须要以管理员的身份运行。

当然,PowerShell的功能远不止这点而已,还有更多功能等待你去开发。

-->上例的源代码<--

附上几个关于PowerShell的网址:
TechNet:technet.microsoft.com/en-us/scriptcenter/dd742419.aspx
PowerGUI.org :http://powergui.org/index.jspa
MSDN:http:/-msdn.microsoft.com/en-us/library/cc281945.aspx

28
Feb
2007

是给交互设计下定义的时候了

近年来,随着交互设计的走红,越来越多的软件开发者嘴边挂起了“交互设计”这个东西,他们认为,交互设计就是为了提高他们所谓的“用户体验”(权威的叫法应该是“可用性”或“易用性”即Usability)。说实话,我实在忍受不了这种荒谬的事情了,所以我得向大家说明一下。

首先,我们得知道什么是“交互”。交互说白了就是指两个物体之间信息的交流,然后根据信息做出反馈。还有吗?没有了!就这么简单!那么交互设计是不是对信息之间的交流做出设计呢?不全对。因该是对可以预见的交互过程做出设计,以达到期望的目的。注意两点,一个是可预见的,也就是说这个交互过程是我们可以人为规定的,一旦我们规定好,那么就得这么做,不能出现不可预料的事情。如果你还不明白的话,我就给你举个例子。相信大家都能手机查过自己的话费吧,回想一下,你除了做出已经规定好的动作以外,你还能做什么?你能给自己的卡充钱吗?或都你给问今天的天气吗?不能,你只有几个选项:1、当前话费2、当前余额……。那么到底有几个选项那就是交互设计的工作了。你有没有想过,为什么1是当前话费,2是什么余额之类的?为什么不能2是当前话费,1是余额。二是期望的目的,目的一定是提高易用度吗?或者说一定是为了让用户用得顺手吗?我觉得那可未必,试想一下ATM机为什么要先取钱才能取卡?为什么不能先取卡再取钱?银行输密码的东西为什么要用一个罩子罩起来?你觉得那样好用吗?我非常不方便!那为什么还是要那样呢?原因很简单,安全性。因为在银行方法,安全性也比易用性重要得多!所以交互设计的目的也就自然成了安全性,能过这个,我只想说,交互设计的目的并不是一般人想象的那样只是为了提高易用性,它完全可以实现其它目的,交互设计只是一种方法而已。不过一般在电脑上它就是为了提高“易用性”。

如果大家想学习交互设计相关的知识,那可以看看Cooper写的书,其中我认为最好的当数《交互设计之路——让高科技回归人性》,真的,绝对值得你看。

06
Oct
2006

论中国人使用盗版软件

老古董了,06年写的,偶然找到……]

不用我说,今天各位使用的软件90%的都是盗版。但是你有没有想过你为什么要使用盗版软件吗?可能在90年代大家会说正版软件这么贵,有谁能买得起啊?

阅读全文>>

«... 5 6 7 8 9 10