设计模式详解

文章讨论了设计模式的重要性,包括帮助理解源代码、提高代码的重用性、可读性、可扩展性和可靠性。作者强调了设计模式中的几个基本原则,如单一职责原则、接口隔离原则和依赖倒转原则等,并通过实例说明了这些原则在实际编程中的应用和重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  秉着温水煮青蛙,优胜劣汰的思想,想换个公司提升一下技术。结果裸辞两个月了,依然没有找到工作。在几次的面试过程中感受到了自己技术的不足,于是痛定思痛,决定沉静下来好好复习总结一下以前学过的知识。为什么决定复习设计模式呢?这里就要谈到设计模式的用处,或者为什么要学习设计模式?

  • 看懂源代码:如果不懂设计模式去看Jdk、Spring、SpringMVC、IO等等等等的源码,会很迷茫,寸步难行。
  • 为了让程序有更好的代码重用性(相同功能的代码,不用多次编写)、可读性(编程规范性,便于程序员的阅读理解)、可扩展性(当需要增加新的功能时,非常方便)、可靠性(当我们增加新的功能后,对原来的功能没有影响),使程序呈现高内聚、低耦合的特性。


什么是设计模式

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。

设计模式分类

模式分类描述
创建型模式工厂模式
抽象工厂模式
单例模式
建造者模式
原型模式
结构型模式适配器模式
桥接模式
过滤器模式
组合模式
装饰器模式
外观模式
享元模式
代理模式
行为型模式责任链模式
命令模式
解释器模式
迭代器模式
中介者模式
备忘录模式
观察者模式
状态模式
空对象模式
策略模式
模板模式
访问者模式

设计模式的原则

设计模式原则,其实就是程序员在编程时,应当遵守的原则,也是设计模式的基础

1、单一职责原则

原则思想:一个方法只负责一件事情。
优点:降低类和类的耦合,提高可读性,增加可维护性和可拓展性,降低可变性的风险。
注意事项:

  • 降低类的复杂度,一个类只负责一项职责
  • 提高类的可读性,可维护性
  • 降低变更引起的风险

曾经在这个原则上吃过大亏,做一个预想单,有三种不同的预想单,但是用的是同一个service、dao、entity,通过if-else判断type字段是哪种预想单,然后处理,结果因为修改service里面其中一个预想单,导致其他预想单也报错,这就是违反了单一职责原则的后果,耦合度太高了!

2、接口隔离原则

原则思想:不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上
例如:
  接口Interface 有五个方法1、2、3、4、5,类A通过接口Interface依赖类B,类C通过接口Interface依赖类D,但是类A只需要接口的1、2、3方法,而类C只需要接口的1、4、5方法,接口Interface对于类A和类C来说不是最小接口。按隔离原则应该这样处理:
  将接口Interface拆分为独立的几个接口(这里拆分成3个接口),类A和类C分别与他们需要的接口建立依赖关系,也就是采用接口隔离原则

3、依赖倒转原则

原则思想:

  • 高层模块不应该依赖低层模块,二者都应该依赖其抽象
  • 抽象不应该依赖细节,细节应该依赖抽象
  • 依赖倒转的中心思想是面向接口编程

设计理念:相对于细节的多变性,抽象的东西要稳定的多。在Java中,抽象指的是接口或抽象类,细节就是具体的实现类
注意事项:

  • 低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性好
  • 变量的声明类型尽量是抽象类或接口,这样变量引用和实际对象间,就存在一个缓冲层,利于程序的扩展和优化
  • 继承时遵顼里氏替换原则
public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.receive(new Email());
    }
}
class Email{
    public void getInfo(){
        System.out.println("电子邮箱消息:hello!");
    }
}
class Person{
    public void receive(Email email){
        email.getInfo();
    }
}

存在问题:如果我们获取的对象是微信,短信等等,则新增类,同时Person也要新增相应的接收方法
解决思路:引入一个抽象接口IReceiver,表示接收者,这样Person类与接口IReceiver发生依赖

public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.receive(new Email());
        person.receive(new WeiXin());
    }
}
interface IReceiver{
    public void getInfo();
}
class Email implements IReceiver{
    public void getInfo(){
        System.out.println("电子邮箱消息:hello!");
    }
}
class WeiXin implements IReceiver{
    public void getInfo(){
        System.out.println("微信消息:hello!");
    }
}
class Person{
    public void receive(IReceiver iReceiver){
        iReceiver.getInfo();
    }
}

依赖关系传递的三种方式:

  • 接口传递
  • 构造方法传递
  • setter方式传递

4、里氏替换原则

原则思想:使用的基类可以在任何地方使用继承的子类,完美的替换基类。
大概意思:子类可以扩展父类的功能,但不能改变父类原有的功能。子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法,子类中可以增加自己特有的方法。
  在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法,里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合,组合,依赖来解决问题。

5、开闭原则(最基础、最重要的设计原则)

原则思想:一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。
  当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。编程中遵循其他原则,以及使用设计模式的目的就是遵循开闭原则
我的理解:在程序使用jar包的时候,jar包的提供方应该是扩展开放的,但是如果因为提供方升级修改了jar包,而导致使用其jar包的使用方也要修改代码的话,使用方就会特别难受!

6、迪米特法则

原则思想:一个对象应该对其他对象保持最小的了解
设计理念:类与类关系越密切,耦合度越大
  迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。迪米特法则还有一个简单的定义:只与直接的朋友通信
直接的朋友:我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量的类不是直接的朋友,也就是说,陌生的类不要以局部变量的形式出现在类的内部
注意事项:

  • 迪米特法则的核心是降低类之间的耦合
  • 但是要注意:由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低类间(对象间)耦合关系,并不是要求完全没有依赖关系

7、合成复用原则(有些地方没有)

原则思想:尽量使用组合/聚合的方式,而不是使用继承

  1. 聚合关系(Aggregation)体现的是A对象可以包含B对象,但B对象不是A对象的组成部分。具体表现为,如果A由B聚合成,表现为A包含有B的全局对象,但是B对象可以不在A创建的时刻创建。
  2. 组合关系(Composition):如果A由B组成,表现为A包含有B的全局对象,并且B对象在A创建的时刻创建。

人与身体的各个部位就是组合关系,身体的各个部位组成了人。人和身份证就是聚合关系,没有身份证,人也还是完整的。

设计原则核心思想

  • 找出应用中需要变化的地方,把它们独立起来,不要和那些不需要变化的代码混在一起
  • 针对接口编程,而不是针对实现编程
  • 为了交互对象之间的松耦合设计而努力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值