首页 > 财经旅游 > 正文

设计模式分类以及六大设计原则

2019-08-02 11:32:03   来源:东方头条   评论:0

设计模式的分类 根据其目的(模式是用来做什么的)可分为创建型(Creational),结构型(Structural)和行为型(Behavioral)三种:

创建型模式主要用于创建对象。

结构型模式主要用于处理类或对象的组合。

行为型模式主要用于描述对类或对象怎样交互和怎样分配职责。

创建型模式

抽象工厂模式(Abstract Factory)

建造者模式(Builder)

工厂方法模式(Factory Method)

原型模式(Prototype)

单例模式(Singleton)

结构型模式

适配器模式(Adapter)

桥接模式(Bridge)

组合模式(Composite)

装饰模式(Decorator)

外观模式(Facade)

享元模式(Flyweight)

代理模式(Proxy)

行为型模式

职责链模式(Chain of Responsibility)

命令模式(Command)

解释器模式(Interpreter)

迭代器模式(Iterator)

中介者模式(Mediator)

备忘录模式(Memento)

观察者模式(Observer)

状态模式(State)

策略模式(Strategy)

模板方法模式(Template Method)

访问者模式(Visitor)

根据范围(模式主要是用于处理类之间关系还是处理对象之间的关系)可分为类模式和对象模式两种:

类模式处理类和子类之间的关系,这些关系通过继承建立,在编译时刻就被确定下来,是属于静态的。

对象模式处理对象间的关系,这些关系在运行时刻变化,更具动态性。

类模式

工厂方法模式(Factory Method)

适配器模式(Adapter)

解释器模式(Interpreter)

模板方法模式(Template Method)

对象模式

抽象工厂模式(Abstract Factory)

建造者模式(Builder)

原型模式(Prototype)

单例模式(Singleton)

桥接模式(Bridge)

组合模式(Composite)

装饰模式(Decorator)

外观模式(Facade)

享元模式(Flyweight)

代理模式(Proxy)

职责链模式(Chain of Responsibility)

命令模式(Command)

迭代器模式(Iterator)

中介者模式(Mediator)

备忘录模式(Memento)

观察者模式(Observer)

状态模式(State)

策略模式(Strategy)

访问者模式(Visitor)

六大原则

总原则:开闭原则

定义:一个软件实体如类、模块或函数应该对扩展开放,对修改关闭。

简单的说就是,当一个软件实体需要扩展的时候,不要去修改原有的代码,而是去扩展原有的代码。其实开闭原则是最基础的一个原则,下面六个原则都是开闭原则的具体形态。

为什么要采用开闭原则:

1、对测试的影响:通过扩展实现变化,测试只需要对新增类进行单元测试即可,单元测试是孤立的,只需要保证新类提供的方法正确就行。而如果是修改类来实现变化,则该类相应的测试方法也都要随着重构,而且当类很复杂时难免存在遗漏情况。

2、可以提高复用性:避免以后维护人员为了修改一个微小的缺陷或增加新功能,却要在整个项目中到处查找相关的代码逐一修改。

3、提高可维护性:开发新功能时,扩展一个类往往比修改一个类更容易。

4、面向对象开发的要求

单一职责原则

定义:应该有且仅有一个原因引起类的变更。

优点:

1、类的复杂性降低。类的职责单一,复杂性自然就降低了。

2、可读性高。

3、易维护。

4、变更引起的风险降低。

难点:

1、\"职责\"和\"变化原因\"都是不可度量的,因项目、环境而异。

2、过细的划分会引起类的剧增,人为的增加系统的复杂性。

建议:

接口的设计一定要做到单一原则,类的设计尽量做到只有一个原因引起变化。

职责的划分需要根据项目和经验来权衡,既要保证职责的单一性,又要尽量避免过细的划分。

里氏替换原则

定义:所有引用基类的地方都必须能透明地使用其子类的对象。

继承的优点:

1、代码共享,提高代码的重用性。

2、提高代码的可扩展性。

3、提高产品或者项目的开放性。

继承的缺点:

1、继承是侵入式的,只要继承,就拥有了父类的属性和方法。

2、降低代码灵活性,子类拥有了父类的属性和方法,多了一些约束。

3、增强了耦合性。父类的常量、变量或方法改动时,必须还要考虑子类的修改,可能会有大段代码需要重构。

里氏替换原则四层含义:

1、子类必须完全实现父类的方法

在类中调用其他类时务必使用父类或接口,如若不能,则说明类的设计已经违背LSP原则。

如果子类不能完整的实现父类的方法,或者父类的方法在子类中发生畸变,这建议断开父子继承关系,采用依赖、聚集、组合等方式代替继承。

2、子类可以有自己的特性:即子类出现的地方父类未必可以出现。

3、覆盖父类的方法时输入参数可以被放大:输入参数类型宽于父类的类型的覆盖范围,例如 hashmap -> map。

4、覆盖父类的方法时输出参数可以被缩小

依赖倒置原则

定义:

1、高层模块不应该依赖低层模块,两者都要改依赖其抽象(模块间的依赖通过抽象产生,实现类不发生直接的依赖关系)

2、抽象不应该依赖细节(接口或者抽象类不依赖实现类)

3、细节可以依赖抽象(实现类依赖接口或者抽象类)

建议:

1、每个类尽量都有接口或抽象类。

2、变量的表面类型尽量是接口或抽象类。

3、任何类都不应该从具体类派生(其实只要不是超过两层的继承都是可以忍受的)。

4、尽量不要复写基类已实现的方法。

5、结合里氏替换原则使用。

面向接口编程:

接口负责定义 public 属性和方法,并且声明与其它对象的依赖关系,抽象类负责公共构造部分的实现,实现类准确实现业务逻辑,同时在适当的时候对父类进行细化。

接口隔离原则

定义:客户端不应该依赖他不需要的接口,类之间的依赖关系应该建立在最小的接口上。

四层含义:

1、接口尽量要小,不要出现臃肿的接口。

2、接口要高内聚。

3、只提供访问者需要的方法:每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。

4、接口设计是有限度的:接口设计粒度越小,系统越灵活。但是结构会越复杂、开发难度增加,可维护性降低。

建议:

1、一个接口只服务一个子模块或者业务逻辑。

2、尽量压缩接口内的方法,保证方法都是有用的,避免臃肿。

3、已经被污染的接口尽量去修改,若变更风险大,则采用适配器模式转化处理。

4、深入了解业务逻辑,拒绝盲从。

迪克特法则(最少知道原则)

定义:一个对象应该对其他对象有最少的了解(低耦合)。

三层含义:

1、一个类只与朋友交流,不和陌生类交流,方法尽量不引入类中不存在的对象。

2、尽量不要对外暴露过多的 public 方法和非静态的 public 变量,尽量内敛。

3、自己的就是自己的。如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置在本类中。

总结:

迪米特法则的核心观念就是类间解耦,低耦合。其负面影响就是产生了大量的中转或者跳转类,导致系统复杂性提高,也为维护带来了难度。需要反复权衡,既做到结构清晰,又要高内聚低耦合。

如果一个类需要跳转两次以上才能访问到另一个类,就需要想办法重构了。

合成复用原则

定义:

是在一个新的对象里面使用一些已有的对象,使其成为新对象的一部分。新对象通过委派达到复用已有功能的效果。

优点:

使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类和集成层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。

缺点:

通过这种方式复用建造的系统会有较多的对象需要管理;为了能将多个不同的对象作为组合块来使用,必须仔细地对接口进行定义。

简单地说:尽量首先使用合成/聚合的方式,而不是使用继承。

  责任编辑:

今日推荐

习近平在第五届中国国际进口博览会开幕式上发表致辞

11月4日晚,国家主席习近平以视频方式出席在上海举行的第五届中国国际进口博览会开幕式并发表题为《共创开放繁荣的美好未来》的致辞。新华社记者 李学仁 摄[详细]

中国共产党第二十次全国代表大会闭幕会在京举行

10月22日,中国共产党第二十次全国代表大会闭幕会在北京人民大会堂举行。新华社记者 陈建力 摄[详细]

天天学习|中南海月刊(2022.09)

天天学习金色九月,喜迎丰收。9月,一个个瞬间令人难忘:主持中央深改委会议决定健全关键核心技术攻关新型举国体制;出席中央军委晋升上将军衔仪式颁发命令状;新冠肺炎疫情发生以来首次出访...[详细]