说起软件设计其实是一个高度,深邃的事情。能登高一览纵山小,俯仰天地那是大师的境界。我等则在路上。。。
一个复杂的设计,是由具体的类和对象组成。先有类,才有类与类之间的关系。
GRASP就是如何设计指导我们设计好类的原则。
1.Information Expert (信息专家)
信息专家模式是面向对象设计的最基本原则,是我们平时使用最多,应该跟我们的思想融为一体的原则。也就是说,我们设计对象(类)的时候,如果某个类拥有完成某个职责所需要的所有信息,那么这个职责就应该分配给这个类来实现。这时,这个类就是相对于这个职责的信息专家。
2.Creator (创造者)
实际应用中,符合下列任一条件的时候,都应该由类A来创建类B,这时A是B的创建者:
a.A是B的聚合
b.A是B的容器
c.A持有初始化B的信息(数据)
d.A记录B的实例
e.A频繁使用B
如果一个类创建了另一个类,那么这两个类之间就有了耦合,也可以说产生了依赖关系。依赖或耦合本身是没有错误的,但是它们带来的问题就是在以后的维护中会产生连锁反应,而必要的耦合是逃不掉的,我们能做的就是正确地创建耦合关系,不要随便建立类之间的依赖关系,那么该如何去做呢?就是要遵守创建者模式规定的基本原则,凡是不符合以上条件的情况,都不能随便用A创建B。
3.Low coupling (低耦合)
低耦合模式的意思就是要我们尽可能地减少类之间的连接。
其作用非常重要:
a.低耦合降低了因一个类的变化而影响其他类的范围。
b.低耦合使类更容易理解,因为类会变得简单,更内聚。
下面这些情况会造成类A、B之间的耦合:
a.A是B的属性
b.A调用B的实例的方法
c.A的方法中引用了B,例如B是A方法的返回值或参数。
d.A是B的子类,或者A实现了B
关于低耦合,还有下面一些基本原则:
a.Don’t Talk to Strangers原则:
意思就是说,不需要通信的两个对象之间,不要进行无谓的连接,连接了就有可能产生问题,不连接就一了百了啦!
b.如果A已经和B有连接,如果分配A的职责给B不合适的话(违反信息专家模式),那么就把B的职责分配给A。
c. 两个不同模块的内部类之间不能直接连接,否则必招报应!嘿!
4.High cohesion (高内聚)
高内聚的意思是给类尽量分配内聚的职责,也可以说成是功能性内聚的职责。即功能性紧密相关的职责应该放在一个类里,并共同完成有限的功能,那么就是高内聚合。这样更有利于类的理解和重用,也便于类的维护。
高内聚也可以说是一种隔离,就想人体由很多独立的细胞组成,大厦由很多砖头、钢筋、混凝土组成,每一个部分(类)都有自己独立的职责和特性,每一个部分内部发生了问题,也不会影响其他部分,因为高内聚的对象之间是隔离开的。
5.Controller (控制器)
用来接收和处理系统事件的职责,一般应该分配给一个能够代表整个系统的类,这样的类通常被命名为“XX处理器”、“XX协调器”或者“XX会话”。
关于控制器类,有如下原则:
a. 系统事件的接收与处理通常由一个高级类来代替。
b. 一个子系统会有很多控制器类,分别处理不同的事务。
6.Polymorphism (多态)
这里的多态跟OO三大基本特征之一的“多态”是一个意思。
7. Pure Fabrication (纯虚构)
这里的纯虚构跟我们常说的纯虚构函数意思相近。高内聚低耦合,是系统设计的终极目标,但是内聚和耦合永远都是矛盾对立的。高内聚以为这拆分出更多数量的类,但是对象之间需要协作来完成任务,这又造成了高耦合,反过来亦然。该如何解决这个矛盾呢,这个时候就需要纯虚构模式,由一个纯虚构的类来协调内聚和耦合,可以在一定程度上解决上述问题。
8. Indirection (间接)
“间接”顾名思义,就是这个事不能直接来办,需要绕个弯才行。绕个弯的好处就是,本来直接会连接在一起的对象彼此隔离开了,一个的变动不会影响另一个。就想我在前面的低耦合模式里说的一样,“两个不同模块的内部类之间不能直接连接”,但是我们可以通过中间类来间接连接两个不同的模块,这样对于这两个模块来说,他们之间仍然是没有耦合/依赖关系的。
9.Protected Variations (受保护变化)
预先找出不稳定的变化点,使用统一的接口封装起来,如果未来发生变化的时候,可以通过接口扩展新的功能,而不需要去修改原来旧的实现。也可以把这个模式理解为OCP(开闭原则)原则,就是说一个软件实体应当对扩展开发,对修改关闭。在设计一个模块的时候,要保证这个模块可以在不需要被修改的前提下可以得到扩展。这样做的好处就是通过扩展给系统提供了新的职责,以满足新的需求,同时又没有改变系统原来的功能。关于OCP原则,后面还会有单独的论述。
S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则(Programming Priciple)的首字母缩写。
SRP The Single Responsibility Principle 单一责任原则
OCP The Open Closed Principle 开放封闭原则
LSP The Liskov Substitution Principle 里氏替换原则
ISP The Interface Segregation Principle 接口分离原则
DIP The Dependency Inversion Principle 依赖倒置原则
1. 单一责任原则(SRP)
当需要修改某个类的时候原因有且只有一个。换句话说就是让一个类只做一种类型责任,当这个类需要承当其他类型的责任的时候,就需要分解这个类。 类被修改的几率很大,因此应该专注于单一的功能。如果你把多个功能放在同一个类中,功能之间就形成了关联,改变其中一个功能,有可能中止另一个功能,这时就需要新一轮的测试来避免可能出现的问题,非常耗时耗力。
2. 开放封闭原则(OCP)
软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。这个原则是诸多面向对象编程原则中最抽象、最难理解的一个。
(1)通过增加代码来扩展功能,而不是修改已经存在的代码。
(2)若客户模块和服务模块遵循同一个接口来设计,则客户模块可以不关心服务模块的类型,服务模块可以方便扩展服务(代码)。
(3)OCP支持替换的服务,而不用修改客户模块。
3. 里氏替换原则(LSP)
当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系
客户模块不应关心服务模块的是如何工作的;同样的接口模块之间,可以在不知道服务模块代码的情况下,进行替换。即接口或父类出现的地方,实现接口的类或子类可以代入。
4. 接口分离原则(ISP)
不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好。
客户模块不应该依赖大的接口,应该裁减为小的接口给客户模块使用,以减少依赖性。如Java中一个类实现多个接口,不同的接口给不用的客户模块使用,而不是提供给客户模块一个大的接口。
5. 依赖注入或倒置原则(DIP)
1. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象
2. 抽象不应该依赖于细节,细节应该依赖于抽象
这个设计原则的亮点在于任何被DI框架注入的类很容易用mock对象进行测试和维护,因为对象创建代码集中在框架中,客户端代码也不混乱。有很多方式可以实现依赖倒置,比如像AspectJ等的AOP(Aspect Oriented programming)框架使用的字节码技术,或Spring框架使用的代理等。
(1).高层模块不要依赖低层模块;
(2).高层和低层模块都要依赖于抽象;
(3).抽象不要依赖于具体实现;
(4).具体实现要依赖于抽象;
(5).抽象和接口使模块之间的依赖分离。
设计模式就是场景的解决方案,也是上面原则的具体体现
创建型
1. Factory Method(工厂方法)
2. Abstract Factory(抽象工厂)
3. Builder(建造者)
4. Prototype(原型)
5. Singleton(单例)
结构型
6. Adapter Class/Object(适配器)
7. Bridge(桥接)
8. Composite(组合)
9. Decorator(装饰)
10. Facade(外观)
11. Flyweight(享元)
12. Proxy(代理)
行为型
13. Interpreter(解释器)
14. Template Method(模板方法)
15. Chain of Responsibility(责任链)
16. Command(命令)
17. Iterator(迭代器)
18. Mediator(中介者)
19. Memento(备忘录)
20. Observer(观察者)
21. State(状态)
22. Strategy(策略)
23. Visitor(访问者)
分享到:
相关推荐
该资源涵盖了软件设计模式的基础知识,包括软件设计模式的概述、UML中的类图、面向对象的设计原则、单例模式、原型模式等。 软件设计模式概述 软件设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码...
在软件工程领域,设计模式是一种被广泛认可的、在特定情境下解决常见问题的模板,能够提供一种通用的设计语言,使得团队成员之间的沟通更为高效。JAVA作为一门广泛使用的编程语言,其设计模式不仅为开发者提供了解决...
除了上述的经典设计模式外,还有一个非常重要的概念叫做GRASP(General Responsibility Assignment Software Patterns),即通用职责分配软件模式。GRASP包含了九种模式,用于指导对象的设计和职责分配。GRASP模式在...
因为设计模式提供了一套通用的设计语言,使得团队成员能够更加清晰地描述问题和解决方案,从而提高开发效率和软件质量。 总之,《C#面向对象设计模式纵横谈(1):面向对象设计模式与原则.zip》为我们提供了一个全面...
在软件开发领域,设计模式和原则是至关重要的概念,它们为开发者提供了可重用的解决方案,以应对常见的设计问题。本文将深入探讨GRASP(一般 Responsibility Assignment Software Patterns,职责分配原则)以及设计...
### 软件体系结构与设计模式复习指南 ...通过以上内容的介绍,我们可以看出面向对象设计原则和设计模式对于构建高质量的软件系统至关重要。理解和应用这些原则及模式可以帮助开发者编写出更加灵活、可维护的代码。
本书不仅介绍了设计模式的具体应用,还深入探讨了设计模式背后的思想和原则,强调了模式的应用并非一成不变,而是需要根据实际情况灵活调整。此外,书中还提到了设计模式社区的发展历程及其对未来软件工程领域的影响...
设计模式的应用不仅仅局限于Java,它们是面向对象编程语言通用的原则和技巧。通过学习设计模式,开发者可以提高代码的可读性,减少代码冗余,提升软件的可维护性和可扩展性。设计模式也是面试中常见的考察点,熟练...
此外,还需要关注设计原则,如开闭原则、依赖倒置原则、里氏替换原则、接口隔离原则和迪米特法则,这些都是设计模式背后的指导思想。 总的来说,《软件秘籍--设计模式那点事》的随书光盘是一个宝贵的学习资源,它...
软件设计模式总复习的知识点非常丰富,涵盖了软件设计目标、面向对象的原则、设计原则和设计模式等多个方面。 一、软件设计目标 软件设计目标主要包含以下几个方面: 1. 正确性:软件的功能需求能否得到正确实现。...
设计模式并不是具体的代码或库,而是一种通用解决方案的描述,适用于面向对象编程中遇到的各种复杂设计问题。这些模式经过时间的考验,已被证明是有效的,并且在不同的项目和团队之间可以重复使用,从而提高代码的...
设计模式是解决特定问题的通用解决方案。它们为常见的编程难题提供了经过验证的结构和方法。例如: - **工厂模式(Factory Pattern):**提供了一个创建对象的接口,但允许子类决定实例化哪一个类。 - **策略模式...
设计模式是用来解决特定类型问题的一种通用解决方案。题目中的第一个选项“同一问题的不同表现形式”(A) 描述了设计模式的主要应用场景之一。设计模式帮助开发者处理常见的软件设计难题,确保代码的可读性、可维护性...
设计模式是软件工程中的一种重要概念,它...通过学习和应用设计模式,可以提升软件的质量,降低维护成本,同时也为团队间的沟通提供了通用的语言。所以,深入理解和熟练运用设计模式是每个专业程序员必备的技能之一。
在软件开发过程中,设计模式是一种经过验证的、通用的解决方案,用于解决常见设计问题和挑战。这些模式来自于实际经验,是软件工程领域的宝贵财富。"软件开发设计模式"这一主题涵盖了多个方面,包括面向对象设计、...
1. **设计模式的基本概念**:首先,会介绍设计模式的概念,它是经验的总结,一种解决特定问题的通用可重用方案。设计模式并不直接提供代码,而是提供一种理解和解决问题的方法论。 2. **面向对象设计原则**:包括...
设计模式是软件开发中的一种重要概念,它是经过时间验证并被广泛接受的解决方案模板,...同时,设计模式也反映了面向对象设计的原则,如单一职责原则、开闭原则、里氏替换原则等,这些都是软件设计中的重要指导思想。