软件设计原则-单一置原则讲解以及代码示例

简介: 单一职责原则(Single Responsibility Principle,SRP)是面向对象设计中的一个重要原则,提倡将一个类或模块只负责一个职责或功能。它最早由Robert C. Martin在其《敏捷软件开发:原则、模式与实践》一书中提出。单一职责原则的核心思想是:一个类或模块应该只有一个引起它变化的原因。也就是说,每个类或模块都应该只有一个职责或功能,并且该职责或功能应该在该类或模块内部封装起来,而不是分散到多个类或模块中。

单一职责原则

一,介绍

1.前言

单一职责原则(Single Responsibility Principle,SRP)是面向对象设计中的一个重要原则,提倡将一个类或模块只负责一个职责或功能。它最早由Robert C. Martin在其《敏捷软件开发:原则、模式与实践》一书中提出。

单一职责原则的核心思想是:一个类或模块应该只有一个引起它变化的原因。也就是说,每个类或模块都应该只有一个职责或功能,并且该职责或功能应该在该类或模块内部封装起来,而不是分散到多个类或模块中。

2.何时使用单一职责原则

    1. 类或模块具有多个不相关的功能:如果一个类或模块负责处理多个不相关的功能,那么就应该将其拆分为多个单一职责的类或模块。每个类或模块只负责一个相关的功能,这样可以提高代码的可读性、可维护性和可复用性。
    2. 类或模块随着需求变化而频繁修改:如果一个类或模块因为不同的需求变化而频繁地修改,那么就应该考虑是否存在职责过重的问题。通过将不同的职责分离到不同的类或模块中,可以降低修改的风险和影响范围。
    3. 类或模块存在复杂的条件判断语句:如果一个类或模块中存在大量的条件判断语句,用于处理不同的职责,那么就应该思考是否可以通过单一职责原则来简化代码逻辑。将不同的职责封装到不同的类或模块中,可以使得代码更加清晰和易于理解。
    4. 类或模块的功能过于庞杂:如果一个类或模块的功能过于庞杂,难以在设计、实现和测试过程中进行有效的管理和控制,那么就应该考虑使用单一职责原则。将不同的功能拆分成独立的类或模块,有助于提高代码的可扩展性和可维护性。

    二,代码示例

    为了更好地理解单一职责原则,我们可以通过一个例子来说明:

    假设我们正在开发一个图形界面程序,需要实现一个菜单栏。我们可以设计一个名为`MenuBar`的类来表示菜单栏,如下所示:

    class MenuBar {
        private List<Menu> menus;
        public void addMenu(Menu menu) {
            // 添加菜单到菜单栏
        }
        public void removeMenu(Menu menu) {
            // 从菜单栏中删除菜单
        }
        public void redraw() {
            // 重绘菜单栏
        }
    }

    image.gif

     

    在这个设计中,`MenuBar`类承担了太多的职责,包括管理菜单项、处理菜单项的添加和删除、以及重绘菜单栏等。这导致`MenuBar`类的代码变得复杂难以维护,并且容易引起不必要的修改。

    为了符合单一职责原则,我们可以将菜单项的管理功能从`MenuBar`类中分离出来,创建一个名为`MenuManager`的类来管理菜单项:


     

    class MenuManager {
        private List<Menu> menus;
        public void addMenu(Menu menu) {
            // 添加菜单到菜单栏
        }
        public void removeMenu(Menu menu) {
            // 从菜单栏中删除菜单
        }
    }
    class MenuBar {
        private MenuManager menuManager;
        public MenuBar() {
            this.menuManager = new MenuManager();
        }
        public void redraw() {
            // 重绘菜单栏
        }
        public void addMenu(Menu menu) {
            menuManager.addMenu(menu);
        }
        public void removeMenu(Menu menu) {
            menuManager.removeMenu(menu);
        }
    }

    image.gif

    这样一来,`MenuBar`类只负责菜单栏的绘制和显示,而菜单项的管理由`MenuManager`类来负责。这种设计能够降低`MenuBar`类的复杂度和耦合度,提高代码的可读性和可维护性。

    总结起来,单一职责原则要求我们在设计类或模块时,应该将不同的功能或职责分别放到不同的类或模块中,以降低类或模块的复杂度和耦合度,提高代码的可读性和可维护性。通过符合单一职责原则,我们可以更好地组织和管理代码,使其更加灵活和易于扩展。

    三,优缺点

    单一职责原则(Single Responsibility Principle,SRP)是面向对象设计中的一个重要原则,强调一个类或模块应该只有一个职责。下面是单一职责原则的优点和缺点:

    优点:

    1. 高内聚性:通过将不同的职责分离到不同的类或模块中,可以使得每个类或模块都有一个明确的目标和职责。这提高了代码的内聚性,使得类或模块更加独立、清晰且易于理解。

    2. 可读性和可维护性:每个类或模块只负责一个特定的职责,使得代码结构更加简洁明了。这使得阅读、理解和修改代码变得更加容易,提高了代码的可读性和可维护性。

    3. 可复用性:因为每个类或模块的职责更加清晰,它们可以更容易地被其他部分复用。当需要某个特定功能时,可以直接使用单一职责原则下的类或模块,而无需关注其它不相关的功能。

    4. 单元测试的便捷性:每个类或模块只负责一个职责,这使得编写和执行单元测试变得更加简单。可以针对每个类或模块进行独立的测试,验证其功能是否正常。

    缺点:

    1. 类的数量增加:通过遵循单一职责原则,一个系统中可能会出现更多的类或模块。这可能会增加代码的总体数量,使得代码结构更加复杂。

    2. 需要精细划分职责:为了满足单一职责原则,需要对问题领域进行深入的理解和分析,以便正确划分职责。如果划分不当,可能导致类的职责过于细碎,增加了代码的繁琐性。

    3. 代码维护的成本增加:当一个需求或变更影响到多个相关类或模块时,需要对多个单一职责的类或模块进行修改。这可能增加代码维护的成本和工作量。

    总之,单一职责原则可以提高代码的可读性、可维护性和可复用性,使得代码更加模块化和灵活。但需要注意划分职责时的精确性和合理性,并权衡增加类数量和代码维护成本之间的关系。在实际应用中,根据具体情况选择是否采用单一职责原则,综合考虑利弊。

    目录
    相关文章
    |
    6月前
    |
    程序员
    编程原则和模式
    编程原则和模式
    |
    7月前
    软件设计原则-合成复用原则讲解以及代码示例
    合成复用原则(Composition/Aggregation Reuse Principle,CARP)是面向对象设计的一种重要原则,也被称为组合/聚合复用原则。它强调通过组合(Composition)或聚合(Aggregation)关系来达到代码复用的目的,而不是通过继承关系。
    92 0
    |
    10月前
    |
    设计模式 Java uml
    你的职责链模式符合五大原则吗?-系统学习九
    工作之余对于用到的设计模式进行总结再梳理,发现职责链模式的妙处以及五大原则的指导下更能发挥职责链模式的优势于是乎便有了这篇博文的诞生
    |
    设计模式 Java 程序员
    设计模式概念目的及七大原则基本介绍
    设计模式概念目的及七大原则基本介绍
    |
    设计模式 测试技术 程序员
    代码的简单设计五原则
    代码的简单设计五原则
    33036 1
    |
    设计模式 关系型数据库
    组件构建原则(五):稳定抽象原则
    组件构建原则(五):稳定抽象原则
    526 0
    |
    监控 程序员 测试技术
    组件构建原则(三):无依赖环原则
    组件构建原则(三):无依赖环原则
    444 0
    |
    设计模式 安全 Python
    设计模式中应遵循的基本原则
    设计模式中应遵循的基本原则
    180 0
    |
    SQL 程序员 测试技术
    本着什么原则,才能写出优秀的代码? (一)
    本着什么原则,才能写出优秀的代码? (一)
    134 0
    本着什么原则,才能写出优秀的代码? (一)
    |
    设计模式 前端开发 关系型数据库
    本着什么原则,才能写出优秀的代码? (二)
    本着什么原则,才能写出优秀的代码? (二)
    178 0
    本着什么原则,才能写出优秀的代码? (二)