- 浏览: 229336 次
- 性别:
- 来自: 上海
最新评论
-
iwindyforest:
pinocchio2mx 写道iwindyforest 写道H ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
nng119:
找不到设备的安装信息 这个问题怎么解决的?
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
pinocchio2mx:
iwindyforest 写道Hi pinocchio2mx ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
iwindyforest:
Hi pinocchio2mx 兄弟, 这个镜像是好的, 我安 ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite -
pinocchio2mx:
蛋疼啊,折腾一晚上还没搞定!网上的教程没一篇靠谱的,摸摸索索到 ...
VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite
多态 Polymorphism
Problem:
How to handle alternative based on types? 如何处理基于变化的类型?
How to create pluggable software components? 如何创建可插拔的组建?
Alternatives based on type Conditional variation is a fundamental theme in programs. If a program is designed using if-then-else or case statement conditional logic, then if a new variation arises, it requires modification of the case logic often in many places. This approach makes it difficult to easily extend a program with new variations because changes tend to be required in several places wherever the conditional logic exists.
Pluggable software components Viewing components in client-server relationships, how can you replace one server component with another, without affecting the client?
基于类型条件变化的选择是程序设计的一个基本主题. 如果一个程序是基于if-then-else 或者 case 条件逻辑设计的, 那么如果一个新的变化出现了, 它需要改动条件语句的好几个地方. 这种方法使得程序在应对新的改变的时候变得困难因为每次新改变都需要在原有逻辑的基础上改动数个地方.
可插拔程序组件主要负责监视客户端服务器之间组件的关系, 如何在不影响客户端的情况下替换服务器的组件.
Solution
When related alternatives or behaviors vary by type (class),
Assign responsibility for the hehaviorousing polymorphic operations to the types for which the behavior varies.
当有关的选择或行为由类型改变时, 针对行为多态的操作给行为发生变化的类型分配责任.
Guideline
Unleass there is a default behavior in the superclass, declare a polymorphic operation in the super class to be abstract.
除非在超类中具有默认的行为, 否则将超类中的多态方法声明为abstract.
When to design with interfaces?
Polymorphism implies the presence of abstract superclasses or interfaces in most OO languages. When should you consider using an interface? The gerenral answer is to introduce one when you want to support polymorphism without being committed to a particular class hierarchy. If an abstract superclass AC is used without an interface, any new polymorphic solution must be a subclass of AC, which is very limited in single-inheritance languages such as java or c#. As a rule-of-thumb, if there is a class hierarchy with an abstract superclass C1, consider making an interface I1 that corresponds to the public methods signatures of C1, and then declare C1 to implement the I1 interface. Then, even if there is no immediate motivation to avoid subclassing under C1 for a new polymorphic solution, there is a flexible evolution point for unknown future cases.
多态意味着大部分OO语言中要使用抽象超类或接口. 何时应该考虑使用接口呢? 普遍的答案是, 当你想要支持多态但是又不想约束于特定的类层次结构时, 可以使用接口. 如果使用了抽象超类AC而不是接口, 那么任何新的多态方案都必须是AC的子类, 这对于Java或C#等单根继承的语言来说十分局限. 经验的做法是, 如果有一个具有抽象超类C1的类层次结构, 可以考虑对应于C1的公共方法特征标记来定义接口I1, 然后声明C1来实现接口I1.这样, 对于新的多态方案, 几时没有避免使用C1子类的直接动机, 也能够获得灵活的进化点, 用来应对将来未知的情况.
Benefits
l Extensions required for new variations are easy to add.
l New implementions can be introduced without affecting clients.
纯虚构 Pure Fabrication
Problem
What object should have the responsbility, when you do not want to violate high cohesion and low coupling, or other goals, but solutions offered by Expert(for example) are not appropriate?
当你并不想违背高内聚和低耦合或其他目标, 但是基于专家模式所提供的方案又不合适是, 那些对象应该承担这一职责?
Object-oriented designs are sometimes characterized by implementing as software classes representations of concepts in the real-world problem domain to lower representational gap; For example a Sale and Customer class. However, there are many situtations in which assigning responsiblities only to domain layer software classes leads to problems in terms of poor cohesion or coupling, or low reuse potentional.
面向对象设计有时会被描述为: 实现软件类, 使其表示真实世界问题领域的概念, 以降低表示差异, 例如Sale和Customer类. 然而, 在很多情况下, 只对领域层对象分配职责会导致不良内聚或耦合, 或者会降低复用潜力.
Solution
Assign a highly cohesive set of responsbilities to an atificial or convenience class that does not represent a problem domain concept. Something made up, to support high cohesion, low coupling, and reuse.
对人为制造的类分配一组高内聚的职责, 该类并不代表问题领域的概念-虚构的事物, 用以支持高内聚, 低耦合和复用.
Such a class is a Fabrication of the imagination. Ideally, the responsibilities assigned to this fabrication support high cohesion and low coupling, so the design of the fabrication is very clean, or pure, hence a pure fabrication.
这种类是凭空虚构的, 理想情况下, 分配给这种虚构物的职责要支持高内聚和低耦合, 使这种虚构物清晰或纯粹, 因此称为虚构物.
Finally, in english pure fabrication is an idiom that means making something up, which we do when we are desperate!
最后, 在英文中, 纯虚构这一习语的含义是: 当我们穷途末路时所捏造的事物.
A reasonable solution is to create a new class that is solely responsible for saving objects in some kind of persistent storage medium, such as a relational database; Call it the PersistentStorage. This class is pure fabrication figment of imagination.
合理的方案是创建一个新类,使其独自负责在某种持久性存储介质(例如关系数据库)中保存对象, 对该类命门为PersistentStorage. 该类是纯虚构的臆想之物.
In a real persistent framework, more than a single pure fabrication class is ultimately necessary to create a reasonable design. This object will be a front-end façade on to a number of back-end help classes.
在实际的持久层框架中, 为了创建合理设计, 最终会需要不止一个纯虚构类. 该对象将成为针对大量后台帮助者类的前台外观.
Notice the name: PersistentStorage. This is an understandable concept, yet the name or concept ‘Persistent Storage’is not something one would find in the domain model. And if a designer asked a business-person in a store, ‘Do you work with persistent storage object?’, They would not understand. They understand to concepts such as ‘sale’ and ‘payment’. PersistentStorage is not a domain concept, but something made up or fabricated for the convenience of the software developer.
注意其名称:PersistentStorage. 虽然这个概念是可以被理解的, 但是我们却无法在领域模型中找到这个名称或”持久性存储”的概念. 并且如果开发者询问商店的业务人员:”你使用持久性存储对象吗?”, 他们不会理解. 他们能够理解诸如”销售”和”支付”的概念.而PersistenceStorage并不是领域概念, 它只是为了便于软件开发而凭空捏造或虚构的概念.
Note that, as with all the GRASP patterns, the emphasis is on where responsibilities should be placed. In this example, the responsibilities are shifted from the Sale class(motivated by Expert) to a Pure Fabrication.
需要注意的是, 在所有GRASP模式中, 强调的是责任应该分配给谁. 在这个例子中, 责任从Sale类转到了一个纯虚构类上.
As a final comment worth reiteration: Sometimes a solution offered by Information Expert is not desirable. Even though the object is a candidate for the responsibility by virtue of having much of the information related to the responsbility, in other words, its choice leads to a poor design, usually due to problems in cohesion or coupling.
作为最后一个值得反复强调的评论: 有时信息专家提供的解决方法是不可取的.尽管这样的对象作为一个候选拥有很多同责任相关的信息, 但另一方面, 这个选择通常会因为内聚和耦合方面的问题会导致一个糟糕的设计.
Benefits
High Cohesion is surpported because responsibilities are factored in to a fine-grained class that only focuses on a very specific set of related tasks.
支持高内聚,因为职责被解析为细粒度的类, 这种类只着重于极为特定的一组相关任务.
Reuse Potential may increase because of the presence of fine-grained Pure Fabrication classes whose responsibilities have applicability in other applications.
增加了潜在的复用性, 因为细粒度纯虚构类的职责适用于其它应用.
Taboo
Behavioral decomposition into Pure Fabrication objects is sometimes overused by those new to object design and more familiar with decomposing or organizing software in terms of functions. To exaggerate,functions just become objects. There is nothing inherently wrong with creating ‘function’ or ‘algorithm’ objects, but it needs to be balanced with the ability to design with representational decomposition, such as the ability to apply Information Expert so that a representional class such as Sale also has responsibilities. Information Expert supports the goal of co-locating responsibilities with the objects that know the information needed for those responsibilities, which tends to support lower coupling. If overused, Pure Fabrication could lead to too many behavior objects that have responsibilities not co-located with the information required for their fulfillment, which can adversely affect coupling. The usual symptom is that most of the data inside the objects is being passed to other objects to reason with it.
那些对象设计初学者和更熟悉以功能组织和分解软件的人有时会滥用行为分析及纯虚构对象. 夸张的是, 功能正好变成了对象. 创建”功能”或”算法”对象本身并没有错, 但是这需要平衡于表示解析设计的能力(例如应用信息专家的能力), 这样便能够使诸如Sale等表示类同样具有职责. 信息专家所支持的目标是, 将职责与这些职责所需信息结合起来赋予同一个对象, 以实现对低耦合的支持. 如果滥用纯虚构, 会导致大量行为对象, 其职责与执行职责所需的信息并没有结合起来, 这样会对耦合产生不良影响, 其通常征兆是, 对象内的大部分数据被传递给其它对象用以处理.
间接实现 Indirection
Problem
Where to assign a responsibility, to avoid direct coupling between two(or more) things? How to decouple objects so that low coupling is surpported and reuse potential remains higher?
为了避免多个组件之间直接耦合, 应该如何分配职责? 如何解耦以使之支持低耦合且保持高的复用性潜力?
Solution
Assign the responsibility to an intermediate object to mediate between other components or services so that they are not directly coupled.
将责任给在不同的组建或服务之间的中间件, 以使各组件时间不是直接耦合关联.
The intermediary creates an indirection between the other components.
中间件构成了组件间的间接性.
PersistentStorage
The Pure Fabrication example of decoupling the Sale from the relational database services through the introduction of a PersistentStorage class is also an example of assigning responsibilities to support Indirection. The PersistentStorage acts as a intermediary between the Sale and the database.
在纯虚构的例子中通过引入PersistentStorage类来实现对Sale类关系数据库间的解耦. 这也是一个通过将职责分配给中间件达到间接实现的例子. PersistentStorage在这里就扮演了一个Sale类和数据库之间的中间件角色.
Benefits
Lower coupling between components.
降低组件间的耦合性.
防止变异Protected Variations
Problem
How to design objects, subsystems, and systems so that the variations or instability in these elements does not have an undesirable impact on other elements?
如何设计对象,子系统, 系统, 时它们之间的变化和不稳定性不会对其他组件产生不良影响?
Solution
Identify points of predicted variation or instability; assign responsibilities to create a stable interface around them.
识别预计变化和不稳定之处, 将职责分配给在这些变化之外层的稳定接口上.
Nothe: The term ‘interface’ is used in the broadest sense of an access view; it does not literally only mean something like a Java interface.
提示: 术语”接口”在这里指的是一个更宽泛的含义, 它不是仅仅指在Java或C#语言中专有的那些.
Mechanisms Motivated by Protected Variations
Protected Variations is a root principle motivating most of the mechanisms and patterns in programming and design to provide flexibility and protection from variations. Variations in data, behavior, hardware, software components, operating systems, and more.
防止变异是一个根本原则, 它促成了促成了大部分的编程机制和设计模式, 用来提供灵活性和房子变化. 这些变化包括数据, 行为, 硬件, 软件组件, 操作系统, 等等…
Liskov Substitution Principle(LSP)
LSP formalizes the principle of protection against variations in different implementations of an interface, or subclass extensions of a superclass.
LSP为实现了某个接口或一个类的子类来达到防止变异的效果提供了原则.
The LSP can be paraphrased as follows:
LSP可以用如下定义来解释:
Subtypes must be substitutable for their base types.
子类型对于基础类型来说必须是可替换的.
What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.
LSP可以简单的解释为: 如果对于类型S的每个对象O1存在类型T的对象O2, 那么对于所有定义了T的程序P来说, 当用O1替换O2并且S为T的子类型时, P的行为不会发生改变.
A Simple Example of a Violation of the LSP
package com.cyh.sample.lsp;
enum ShapeType {
SQUARE, CICLE
}
abstract class Shape {
private ShapeType shapeType;
Shape(ShapeType shapeType) {
this.shapeType = shapeType;
}
ShapeType getShapeType() {
return shapeType;
}
void setShapeType(ShapeType shapeType) {
this.shapeType = shapeType;
}
}
class Cicle extends Shape {
int center, radius;
Cicle(ShapeType shapeType) {
super(shapeType);
}
void draw() {
System.out.println("draw cicle in Cicle class.");
}
}
class Square extends Shape {
int coordinate, sideWidth;
Square(ShapeType shapeType) {
super(shapeType);
}
void draw() {
System.out.println("draw cicle in Square class.");
}
}
public class DrawTest {
public DrawTest(Shape shape) {
this.drawShape(shape);
}
void drawShape(Shape shape) {
String shapeType = shape.getShapeType().toString();
if (ShapeType.CICLE.toString().equals(shapeType)) {
((Cicle) shape).draw();
} else if (ShapeType.SQUARE.toString().equals(shapeType)) {
((Square) shape).draw();
}
}
public static void main(String[] args) {
new DrawTest(new Square(ShapeType.SQUARE));
}
}
Consider Joe the Engineer. Joe has studied object-oriented technology and has come to the conclusion that the overhead of polymorphism is too high to pay. Therefore, he defined class Shape without any virtual functions. The classes Square and Circle derive from Shape and have Draw() functions, but they dont overide a function in Shape. Since Cicle and Square are not substitutable for Shape, DrawShape must inspect its incoming Shape, determine its type, and then call the appropriate Draw() function.
The fact that Square and Circle cannot be substituted for Shape is a violation of the LSP. This violation forced the violation of the OCP by drawShape(). Thus, a violation of LSP is a latent violation of OCP.
Square and Rectangle, a More Subtle Violation
package com.cyh.sample.lsp;
public class AreaTest {
private int getArea(Rectangle rectangle) {
int width = rectangle.getWidth();
int height = rectangle.getHeight();
return width * height;
}
}
class Rectangle {
private int pointX, pointY;
private int width, height;
int getHeight() {
return height;
}
void setHeight(int height) {
this.height = height;
}
int getWidth() {
return width;
}
void setWidth(int width) {
this.width = width;
}
}
class Square extends Rectangle {
void setWidth(int width) {
super.setWidth(width);
super.setHeight(width);
}
void setHeight(int height) {
super.setHeight(height);
super.setHeight(height);
}
}
Square and Rectangle now appear to work. No matter what you do to a Square object, it will remain a mathematical rectangle. Moreover, you can pass a Square into a function that accepts a pointer or reference to a Rectangle, and the Square will still act like a square and will remain consistent.
Thus, we might conclude that the design is now self-consistent and correct. However, this conclusion would be amiss. A design that is self-consistent is not necessarily consistent with all its users! Consisder the following function:
private int calcArea(Rectangle rectangle) {
int width = rectangle.setWidth(4);
int height = rectangle.setHeight(5);
assert(r.getArea() == 20);
}
This function invokes the setWidth() and setHeight() memebers of what it believes to be a Rectangle. The function works just fine for a Rectangle, but it declares an assertion error if passed a Square. So here is the real problem: The author of calcArea() assumed that changing the width of Rectangle leaves its height unchanged.
Function clacArea() shows that there exist functions that take pointers or references to Rectangle objects, but that can not operate properly on Square objects. Since, for these functions, Square is not substitutable for Rectangle, the relationship between Square and Rectangle violates the LSP.
Open-Closed Principle
The Open-Closed Principle(OCP), described by Bertrand Meyer, is essentially equivalent to the PV pattern and to Information Hiding. A definition of OCP is:
Modules should both open(for extension; adaptable) and closed(the module is close for modification the ways that affect clients).
OCP and PV are essentially two expressions of the same principle, with different emphasis: protection at variation and evolution points. In OCP, module includes all discrete software elements, including methods, classes, subsystems, applications, and so forth.
发表评论
-
One of the Best Bits of Programming Advice I ever Got
2011-11-28 20:31 1350from: http://objology.blogspot. ... -
通用职责分配软件模式(GRASP)学习笔记(一)
2009-08-31 09:52 2528通用职责分配软件模式 General Responsibil ... -
代理模式学习笔记
2009-08-10 13:42 1174Proxy Pattern Intent Pro ... -
讨论一下CQS (命令-查询 分离)原则
2008-12-24 17:50 1552看Craig Larman的书, 里面 ... -
实现自己的可重用拦截器机制
2008-08-30 17:06 3672AOP技术是spring框架的一个重要特征。通过该特性能够在函 ... -
学习设计模式之State
2008-07-08 01:22 2456发现问题: 大家在Coding ...
相关推荐
介绍部分关于GRASP模式的知识 GRASP是General Responsibility Assignment Software Pattern(通用指责分配软件模式)的缩写。
GRASP模式,这个模式出自《UML和模式应用》,GRASP是General Responsibility Assignment Software Pattern(通用责任分配软件模式)的缩写
GRASP模式,OO原则和设计模式的基础,原创不易,请珍惜下载
,在这门课的理论课上,我对对象设计和职责分配的基本原则有了一定的了解老师为我们讲述了设计类的模式,让我们对于项目的整体构思有了一定的思维方法,在实验课上,老师为我们准备了很多实验,绘画用例图、类图、...
GRASP\GRASP_source.rar
GRASP(空间回归分析与预测工具学习)
GRSP培训软件,十分珍贵,有例子,有基础介绍,非常实用,是天线仿真的必备软件之一
GRASP更多具有职责的对象ppt课件.ppt
为了改善GRASP的局限性,提出了一种能解决含有伪布尔(PB)和合取范式(CNF)混合约束问题的新的混合算法(H-GRASP)。该新算法采用了切削平面技术来提取PB约束条件之间的推论,并把它结合到普通的蕴涵图中,分析...
讲解:GRASP (职责分配原则),GRASP是学习使用设计模式的基础;讲解:设计原则,设计原则是设计模式的灵魂。
第17章grasp基于职责设计对象.pptx
管家婆原版7.2安装包7.2安装包7.2安装包
4.2.3组合模式实例之杀毒软件 4.2.4装饰模式实例之界面显示构件库 4.2.5外观模式实例之文件加密 4.2.6享元模式实例之围棋棋子 4.2.7代理模式实例之日志记录代理 4.3实训练习 第5章行为型模式实训 5.1知识...
GRASP72GREEN+备份.zip
一般的管家婆软件在数据库记录超过2万条就开始报错,需要修复,我这个是一点问题都没有的。稍候我将把之前错误修复的程序放上来,供大家参考。资源名称:管家婆7.1错误修复程序
Grasp 是一个用于公共核心课堂的开源学习管理系统。 Grasp 的主要目标是利用技术无缝融入课堂并改善师生之间的交流。入门先决条件带有 Rails 的 Ruby 2.0+ Ruby 和 PhantomJS 的安装超出了本自述文件的范围。依赖...
NULL 博文链接:https://wuaner.iteye.com/blog/587112
软件需求分析课件:Chap 7-GRASP.ppt
GRASP实验室飞控技术:We study the problem of designing dynamically feasible trajectories and controllers that drive a quadrotor to a desired state in state space. We focus on the development of a ...