1、一组用例实例,每个实例是系统所执行的一系列活动,以此产生对特定参与者具有价值的可观察结果。   2、关注系统的用户或参与者来编写需求,询问其目标和典型情况。   3、关注理解参与者所考虑的有价值结果。
1、黑盒用例是最常用的和推荐使用的类型。它不对系统内部的工作、构件或设计进行描述。   2、黑盒用例以职责来描述系统,这是面向对象思想中普遍统一的隐喻主题-软件元素具有职责,并与其他具有职责的元素进行协作。   3、黑盒用例定义系统职责,可以规定系统必须做什么,而不必关心系统如何去做。   4、分析与设计的区别,就在于”什么“和”如何“。   5、在分析中应避免进行”如何“的决策,而是规定系统的外部行为。   6、在设计过程中,创建满足该规则说明的解决方 ...
1、应该编写简洁的用例,删除“噪音”词汇。   2、即使是一些细微之处也会积累为繁琐。
1、通过对目标层次的研究,系统分析员会发现与实现机制无关的目标。   2、这种对根源目标的发现过程能够扩展视野,以促成新的和改进的解决方案。   3、摈除用户界面于思考范围之外,集中于意图。   4、以本质风格编写用例,摈除用户界面并且关注参与者的意图。   5、具体风格的用例编写方式,不适合于早期的需求分析工作,应该避免。
1、业务活动与规则对于一个领域来说与其涉及的实体同样重要。   2、领域也会包含各种类别的概念。对知识的消化要能够产生出反映这种理解的模型。   3、超越实体与值之上的变化可能会对知识消化产生剧烈的影响,因为业务规则之间可能存在不一致。   4、领域专家通过与软件专家的密切合作,进行知识消化,才使得规则明晰化。   5、提炼隐藏概念,将业务规则可以放到一个领域对象中。   6、任何业务专家都不可能阅读代码来检对规则。   7、一个非业务人员的技术人员,要将需求文档与代码联系起来是很困难的。   8 ...
1、如果一个数组中的各个元素代表了不同的东西,考虑用Object来代替数组。   2、数组应该只用于容纳一组相似对象。   3、如果一个数组容纳了不同对象,会给array用户带来麻烦。
1、重要的研发成果常常产自类比。通过把你不太理解的东西和你较为理解、十分类似的东西进行比较,你可以对这些不太理解的东西产生更深刻的理解。这种使用隐喻的方法叫做“建模”。   2、软件隐喻不会告诉你到哪里去找答案,仅告诉你该如何找到答案。隐喻的作用更像启示,而不是算法。   3、“增量的”、“迭代的”、“自适应的”、“演进的”,以增量的方式进行设计、编码和测试,是目前已知的最强有力的软件开发概念。   4、进行增量开发时,我们先做出软件 ...
1、高效的建模人员就是知识的消化器。   2、知识消化并不是一个孤立的行动,它由开发团队与领域专家共同合作,由开发人员领导。   3、老式的瀑布方法中,业务专家与分析人员会谈,分析人员提取摘要,进行抽象后将结果转达给程序员,由程序员进行编码。这种方法并不成功,因为没有反馈机制。   4、优秀的程序员会自然地开始进行抽象来开发一个模型。   5、在团队成员一起讨论模型的过程中,他们之间的交互也会发生变化。模型的不断精化使得开发人员不断学习他们所需要的重要业务原理。领域专家通过提炼他们认为必须的知识来精化他们的理解。   6、程 ...
1. 模型与实现相互绑定。未经加工的原型建立了早期必需的联系,在随后的迭代中始终对它进行维护和完善。   2. 基于模型生成了一种语言。随着项目的进行,我们中的每个人都可以自如地使用来自模型的术语,将它们组织成与模型结构一致的句子,不需翻译,也不会引起歧义。   3. 开发了一个包含丰富知识的模型。对象都具有行为和一些强制性的规则。模型并不仅仅是一个数据方案,它是解决一个复杂问题必不可缺的。它捕获了各种类型的知识。   4. 提炼模型。在模型变得更加完善的过程中,一些重要的概念被加入其中。同样重要的是,如果概念被证明没有用处或并不重要,则应该丢弃。如果 ...
1、用例、UML图等保证不会是完美的。它们可能会遗漏关键信息或者包含错误陈述。解决方案并不是以瀑布的态度试图近乎完美地记录规格说明并且在开始阶段就完成此项工作。   2、编写用例的折中方案是介于瀑布和即兴编程之间的迭代和进化式开发。   3、以增量式进化、验证用例和其他模型,并且通过及早的编程和测试加以明确。   4、如果在第一次开发迭代之前,小组就视图详尽地编写所有或大部分用例时,此时要意识到你已经走入歧途了。反之,则恭喜你!
考 虑以下场景:浏览网页时,浏览器了5个线程下载网页中的图片文件,由于图片大小、网站访问速度等诸多因素的影响,完成图片下载的时间就会有很大的不同。如果先下载完成的图片就会被先显示到界面上,反之,后下载的图片就后显示。 Java的并发库 的CompletionService 可 以满足这种场景要求。该接口有两个重要方法:submit()和take()。submit用于提交一个runnable或者callable,一般会提 交给一个线程池处理;而take就是取出已经执行完毕runnable或者callable实例的Future对象,如果没有满足要求的,就等待了。 Completi ...
在 实际应用中,有时候需要多个线程同时工作以完成同一件事情,而且在完成过程中,往往会等待其他线程都完成某一阶段后再执行,等所有线程都到达某一个阶段后再统一执行。 比如有几个旅行团需要途经深圳、广州、韶关、长沙最后到达武汉。旅行团中有自驾游的,有徒步的,有乘坐旅游大巴的;这些旅行团同时出发,并且每到一个目的地,都要等待其他旅行团到达此地后再同时出发,直到都到达终点站武汉。 这时候CyclicBarrier 就可以派上用场。CyclicBarrier最重要的属性就是参与者个数,另外最要方法是await()。当所有线程都调用了await()后,就表示这些线程都可以继续执行,否则就会等待。 ...
Lock 接口 ReentrantLock 是 Lock 的具体类, Lock 提供了以下一些方法: lock(): 请求锁定,如果锁已被别的线程锁定,调用此方法的线程被阻断进入等待状态。 tryLock() :如果锁没被别的线程锁定,进入锁定状态,并返回 true 。若锁已被锁定,返回 false ,不进入等待状态。此方法还可带时间参数,如果锁在方法执行时已被锁定,线程将继续等待规定的时间,若还不行才返回 false 。 unlock() :取消锁定,需要注意的是 Lock 不会自动取消,编程时必须手 ...
*1: 定义了几个任务 *2: 初始了任务执行工具。任务的执行框架将会在后面解释。 *3: 执行任务,任务启动时返回了一个 Future 对象,如果想得到任务执行的结果或者是异常可对这个 Future 对象进行操作。 Future 所含的值必须跟 Callable 所含的值对映,比如说例子中 Future 对印 Callable *4: 任务 1 正常执行完毕, future1.get() 会返回线程的值 *5: 任务 2 在进行一个死循环,调用 future2.cancel(true) 来中止此 ...
Java自 1995 年面世以来得到了广泛得一个运用,但是对多线程编程的支持 Java 很长时间一直停留在初级阶段。在 Java 5.0 之前 Java 里的多线程编程主要是通过 Thread 类, Runnable 接口, Object 对象中的 wait() 、 notify() 、 notifyAll() 等方法和 synchronized 关键词来实现的。这些工具虽然能在大多数情况下解决对共享资源的管理和线程间的调度,但存在以下几个问题 1.   &nbs ...
本文探讨用信号量Semaphore实现互斥锁Mutex的问题     在Doug lea的那本著名的《Java并发编程—设计原则与模式》,英文名"Concurrent Programming in Java™: Design Principles and Patterns, Second Edition ",书中提到可以用信号量Semaphore实现互斥锁Mutex。虽然java中是通过synchronize关键字提供锁,并用这个基础设施实现信号量的。在有的系统中只有信号量这一原语,锁是通过信号量实现的。代码如下: ...
操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,acquire()获取一个许可,如果没有就等待,而release()释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。 Semaphore维护了当前访问的个数,提供同步机制,控制同时访问的个数。在数据结构中链表可以保存“无限”的节点,用Semaphore可以实现有限大小的链表。另外重入锁ReentrantLock也可以实现该功能,但实现上要负责些,代码也要复杂 ...
         本文是Sun官方以Blog形式发布的Java 核心技术窍门(Java C oreTechTip)中的一个。本文主要介绍了C allable及其相关接口和类的使用,篇幅不长且易于理解,故翻译在了此处,相信对于准备或刚接触java.util.concurrent的朋友会有所帮助。     自从Java平台的最开始,Runnable接口就已存在了。它允许你定义一个可由线程完成的任务。如大多数人所已知的那样,它只提供了一个run方法, 该方法既不接受任何参数,也 ...
run() 和start() 是大家都很熟悉的两个方法。把希望并行处理的代码都放在run() 中;stat() 用于自动调用run(),这是JAVA的内在机制规定的。并且run() 的访问控制符必须是public,返回值必须是void(这种说法不准确,run() 没有返回值),run()不带参数。 闲话少说,我们要讲的是join(),我们首先来看个例子: 代码: /** * @author QingHe * Creation on 2005-12-19 */ public class ThreadTest impleme ...
最 近JDK6 RC 已经发布了,而对于JDK5 的新特性还来不及使用,虽然在项目中还没有使用,但可以写一些Demo体验一下Tiger的魅力,现在的时代就是体验的时代,事事都要亲历亲为才能有发言权,怎么有点毛主席“实事求是”的感觉。 JDK5中的一个亮点就是将Doug Lea 的并发库 引入到Java标准库中。Doug Lea确实是一个牛人,能教书,能出书,能编码,不过这在国外还是比较普遍的,而国内的教授们就相差太远了。 一般的服务器都需要线程池,比如Web、FTP等服务器,不过它们一般都自己实现了线程池,比如以前介绍过的Tomcat 、Resin和 ...
并 发库中的BlockingQueue 是一个比较好玩的类,顾名思义,就是阻塞队列。该类主要提供了两个方法put()和take(),前者将一个对象放到队列中,如果队列已经满了,就等待直到有空闲节点;后者从head取一个对象,如果没有对象,就等待直到有可取的对象。 下面的例子比较简单,一个读线程,用于将要处理的文件对象添加到阻塞队列中, 另外四个写线程用于取出文件对象,为了模拟写操作耗时长的特点,特让线程睡眠一段随机长度的时间。另外,该Demo也使用到了线程池和原子整型 (AtomicInteger),AtomicInteger可以在并发情况下达到原子化更新,避免使用了synchron ...
从 名字可以看出,CountDownLatch 是一个倒数计数的锁,当倒数到0时触发事件,也就是开锁,其他人就可以进入了。在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。 CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。 一个CountDouwnLatch实例是不能重复使用的,也就是说它是一次性的,锁一经被打开就不能再关闭使用了,如果想重复使用,请考虑使用CyclicBarrier 。 下面的例子简单的说明 ...
jokermanager
搜索本博客
最近加入圈子
存档
最新评论