高效团队的 CheckList

http://www.infoq.com/cn/news/2010/03/most-effective-team-structure

  1. 团队的结构是否强调自身的长处,支撑短处,而且支持、激励团队成员?团队某个成员的弱点应该可以被其他成员的优势所补足。
  2. 团队结构是否将必须同时属于两个团队的人员数目降到最低(而且避免有人同时属于三个团队)?试图同时着手多个并行项目、或是多个任务,都会损害进度。
  3. 团队结构是否能将团队保持在一起的时间延至最长?应该更倾向于让成员能够在长期内保持在一起的团队设计,这能让团队的感觉和联系保持长久。
  4. 组件团队的结构是不是只在有限而且易于处理的情况下使用?团队应该是功能团队,围绕着端到端交付可工作功能的方式构建。
  5. 是不是两个pizza这样的食物数量足够多数团队食用?大多数设计良好的团队应该有7±2个人。
  6. 团队结构能够将团队之间的沟通路径数目最小化?如果在待开发应用中做一个小更改,就会带来大量团队之间的沟通,那么就得好好看看团队结构了。
  7. 现有结构是否鼓励团队沟通?如果换个结构,团队就不愿意这么做?高效的团队设计鼓励团队或个人之间的沟通,可能他们本来不想这么做。
  8. 团队设计是否支持对于责任的明确理解?结构应该推进共享所有权和共同成功的理念。
  9. 团队成员是否可以对团队设计提出建议?他们应该感到这是他们构建起来的团队。

 

十条敏捷失败之路

http://www.infoq.com/cn/articles/successfully-fail-agility

改变敏捷团队的构成

http://www.infoq.com/cn/news/2013/12/change-composition-teams

谷歌和它的完美团队

http://www.infoq.com/cn/news/2016/10/box-security-governance

组织自组织团队

http://www.infoq.com/cn/news/2010/05/organizing-selforganizing-teams

业务分析师在敏捷项目中的作用

http://www.infoq.com/cn/articles/agile-business-analyst-role

代码审查的价值——为何做、何时做、如何做?

http://www.infoq.com/cn/news/2013/11/code-review-why-when-how

系统边界如何定义

主要是参考文献。

一、参考 wiki 关于系统的定义中对边界的定义

https://en.wikipedia.org/wiki/System

系统理论将世界视为一个相互关联的零件的复杂系统。 一个系统通过定义其边界来定义; 这意味着选择哪些实体在系统内部并且哪些是环境的外部。 可以对系统进行简化的表示(模型),以便理解它并预测或影响其未来的行为。 这些模型可以定义系统的结构和行为。
Systems theory views the world as a complex system of interconnected parts. One scopes a system by defining its boundary; this means choosing which entities are inside the system and which are outside—part of the environment. One can make simplified representations (models) of the system in order to understand it and to predict or impact its future behavior. These models may define the structure and behavior of the system.

二、参考一篇文献,提到了将系统作为对象来类比,从而定义它的边界

http://www.mcs.vuw.ac.nz/research/object/Papers/euc-html/node9.html

确定系统边界

根据我们的经验,确定需求的一个主要问题是区分系统应该做什么和不应该做什么。通常很难对这一边界做出决定,但是通常很难与所有相关人员,分析人员和利益相关者沟通这个问题。我们发现,应用在设计中熟悉的方法是非常有帮助的。我们将系统呈现为一个“黑盒子”,有一个明确的边界,描述了系统的基本用例责任的行为。

我们可以将系统视为单个系统对象,具有一组任何对象的职责,以及尚未考虑的实现。 Jacobson [17]提出了一个类似的想法,但是它在不同的方向。在基本用例中,我们可以使用职责来帮助确定系统的边界。如果系统像一个单一的对象,那么用例就像这个对象的方法。它们允许访问系统行为,并且不能进行其他访问。用例中的交互类似于方法参数和返回值,但是以顺序方式管理。

我们发现用例图有助于加强这个想法。我们使用一种形式的用例图,如在UML [23]中,显示了actor(作为stick figure)和它们与用例(作为椭圆)的参与。我们还显式地显示了系统边界,描述为围绕用例的框,用在演员和用例跨过边界之间的线,如图gif所示。这清楚地分离了演员的意图和系统的责任。 Jacobsen [17]使用了在用例图中显示系统边界的惯例,但通常不会使用UML或Rational Unified Process [16]。我们发现它是值得的,与系统作为一个对象的想法一致,并有助于解决有关确定系统责任的边界的问题。

Determining the System Boundary

In our experience, a major issue in determining requirements is distinguishing what the system should do from what it should not do. It often difficult to make decisions about this boundary, but it is also often difficult to communicate about this issue with all the people involved, analysts and stakeholders. We have found that it is very helpful to apply an approach familiar in design. We present the system as a black-box”, with an explicit boundary, describing the behavior of the system by essential use case responsibilities.

We can regard the system as a single system object, with a set of responsibilities like any object, and an implementation not yet under consideration. Jacobson [17] proposes a similar idea, but takes it in a different direction. With essential use cases, we can use the responsibilities to help determine the boundary of the system. If the system is like a single object, then the use cases are like methods of this object. They allow access to the system behavior, and no other access is possible. The interaction in a use case resembles method parameters and return values, but managed in a sequential way.

We have found use case diagrams useful in reinforcing this idea. We use a form of the use case diagram that, as in UML [23], shows actors (as stick figures) and their involvement with use cases (as ellipses). We also explicitly show the system boundary, depicted as a box surrounding the use cases, with the lines between the actors and the use cases crossing the boundary, as shown in figure gif. This clearly separates the actor’s intention from the system’s responsibility. This convention of showing the system boundary in use case diagrams was used by Jacobsen [17] but does not typically feature in use of UML or in the Rational Unified Process [16]. We have found it worthwhile, consistent with the idea of the system as an object, and helpful in resolving issues about determining the boundary of system responsibilities.

Template Method Pattern(模版方法模式)

1336965093_1048

在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是某些更细节步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关。

在这种情况下,在一个方法中定义一个的算法的骨架,而将一些步骤的实现延迟到子类中,我们称这个方法为:模版方法。

模式结构

抽象类(AbstractClass):定义抽象的原始操作(primitive operation),具体的子类将重定义它们以实现一个算法;实现一个模板方法,在其中定义一个算法的骨架,算法中会去调用原始操作。

具体子类(ConcreteClass):实现原始操作以完成算法中与特定子类相关的步骤。

模式分析

1)是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系;
2)基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一;
3)其关键点是将通用算法封装在抽象基类中,并将不同的算法细节放到子类中实现。

模式优点

1)在一个类中形式化地定义算法,而由它的子类实现细节的处理;
2)是一种代码复用的基本技术。它们提取了类库中的公共行为;
3)形成一种反向的控制结构,通过对子类的扩展增加新的行为,符合“开放封闭原则”。

模式缺点

继承的强制性约束关系也让模版方法模式有不足的地方,我们可以看到对于各个 ConcreteClass 类中的实现的原始方法 Primitive() 是不能被别的类复用的。假设我们要创建一个 AbstractClass 的变体 AnotherAbstractClass,并且两者只是通用算法不一样,其原始操作想复用 AbstractClass 的子类的实现。但是这是不可能实现的,因为 ConcreteClass 继承自 AbstractClass,也就继承了 AbstractClass 的通用算法,AnotherAbstractClass 是复用不了 ConcreteClass 的实现,因为后者不是继承自前者。

适用环境

1)一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2)各子类中公共的行为被提取出来并集中到一个公共父类中以避免代码重复。
3)控制子类扩展。模板方法只在特定点调用原始操作 ,这样就只允许在这些点进行扩展。

相关模式

策略模式:策略模式解决的是和模版方法模式类似的问题,但是策略模式是将逻辑(算法)封装到一个类中,并采取组合(委托)的方式解决这个问题。

实际应用

Zendframework 1.* 中的 Controller 就是用模版方法模式实现的:

父类中的构造函数、dispatch() 都是模版方法,而 init()、preDispatch()、postDispatch() 这些钩子方法就是供子类扩展的。

 

参考:
wiki/Template_method_pattern
http://blog.csdn.net/hguisu/article/details/7564039
http://www.cnblogs.com/phinecos/archive/2006/10/10/524745.html