美文网首页
搬砖方法论:Single Responsibility Prin

搬砖方法论:Single Responsibility Prin

作者: su9257_海澜 | 来源:发表于2021-03-13 17:06 被阅读0次

    差异的源头

    前言:语言本身是一件非常不稳定的表达工具,这也是为什么我们在沟通中需要观察对方的表情、肢体动作、给予的隐喻、提供的图像来进一步确定对方想表达的意思,加之语言的使用者和接收者因文化、职业、经历等不确定因素的影响,又会造成相同的语句表达出不同含义,这让语言的精确性再次下降。

    只有这些?

    当我们用搜索引擎搜索 SRP原则或单一职责原则关键字,定义中使用频率最多的一句话就是:一个类应该只有一个发生变化的原因。

    这不仅让读者陷入思索,其中所描述的原因到底是什么?是否可量化?

    以量取胜

    为了进一步解释这个"原因",我们对其定义丰富一下:

    • 一个类应该只有一个发生变化的原因。
    • 每一个类都应该对程序功能的一个部分负责,此时它应该封装。该模块、类或函数的所有服务都应该与该职责紧密结合。
    • 将因相同原因而发生变化的事物聚集在一起。分开由于不同原因而改变的事物。

    以上的三条定义说的都是一件事:单一职责原则。
    这也能看出,这个发生变化的"原因"是基于一个集合。如果每个函数只做一件事是一个机器的零件,那单一职责中的"职责"也就是所说的“原因”就是这些零件组合起来的功能。

    确定单一

    既然我们已经从概念上统一了职责到底是什么,那么下一步就是从量化的角度确定如何保证职责单一。

    分为如下三步

    • 建模
    • 编码对应的类(笔者开始阶段常用伪代码代替)
    • 将对应的类拆分为多个类直到不能拆分

    建模:可以理解为对应需求的梳理和拆分,最终抽象(总结)出这个职责核心是做什么的,要依赖于哪些其他的职责。

    应用

    我们可以举个例子来说明,我们要做一个菜单界面功能,一般我们会这么写

    public class MenuPanel
    {
        public MenuPanel()
        {
            var menuData = GetMenuData();
            SetMenuDataAndUpdate(menuData);
        }
    
        public string GetMenuData()
        {
            // do something...
            return default;
        }
    
        public void SetMenuDataAndUpdate(string temp)
        {
            // do something...
        }
    }
    

    在这个MenuPanel类中负责显示Menu这个菜单界面,但是这个MenuPanel真的是仅仅负责显示吗?答案是否定的。

    当得到策划需求的时候,可按照【确定单一】里面所说的3步骤进行如下操作

    建模

    • 根据数据库的数据显示对应的菜单。
    • 数据方面需要:请求-验证-解析-整合-筛选等操作。相当于上述代码GetMenuData()函数。
    • UI方面需要:接收数据-数据分类填充-适配布局-注册响应事件等操作。相当于上述代码SetMenuDataAndUpdate()函数。
    • 将上面数据与UI进行衔接操作。相当于上述代码MenuPanel()

    拆分对应的类直到不能再拆分

    • 数据处理一个类
    • UI显示一个类
    • 数据与UI衔接一个类

    经过拆分后的代码

    public class ServerData
    {
        public string GetNeedData()
        {
            /*
             * 请求 函数
             * 验证 函数
             * 解析 函数
             * 整合 函数
             * 筛选 函数
             */
            return default;
        }
    
    }
    
    public class MenuPanel
    {
        private string m_NeedData;
        public MenuPanel(string needData)
        {
            m_NeedData = needData;
        }
    
        public void UpdateMenu()
        {
            // do something...
        }
    }
    
    public class EnterMenuPanelCommand
    {
        public void Excute()
        {
            var serverData = new ServerData();
            var needData = serverData.GetNeedData();
            //TODO:正常情况下不应该直接传入基本类型,应该传入对应的自定义类,为了示例简单暂且代替
            var menuPanel = new MenuPanel(needData);
            menuPanel.UpdateMenu();
        }
    }
    

    经过一系列的操作我们得到三个职责:数据处理、UI刷新、数据与UI衔接三个职责。这样每一个类当职责变化,即只有一个发生变化原因时,我们才需要更改对应的类。

    总结

    SRP原则并不是彻底消灭腐朽代码的银弹,它只是降低出现代码坏的味道的几率,提高代码整洁的系数。SRP原则是一个指导性建议,并非强制要求,也切勿生搬硬套。


    更多文章详见主页:www.aihailan.com

    相关文章

      网友评论

          本文标题:搬砖方法论:Single Responsibility Prin

          本文链接:https://www.haomeiwen.com/subject/xisxcltx.html