代码的坏味道(二)——为什么建议使用模型来替换枚举?

这篇具有很好参考价值的文章主要介绍了代码的坏味道(二)——为什么建议使用模型来替换枚举?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为什么建议使用对象来替换枚举?

在设计模型时,我们经常会使用枚举来定义类型,比如说,一个员工类 Employee,他有职级,比如P6/P7。顺着这个思路,设计一个 Level 类型的枚举:

class Employee {
      private String name;
      /**
       * 薪水
       */
      private int salary;
      /**
       * 工龄
       */
      private int workAge;
      /**
       * 职级
       */
      private Level level;
  }

  enum Level {
      P6, P7;
  }

假设哪天悲催的打工人毕业了,需要计算赔偿金,简单算法赔偿金=工资*工龄

   class EmployeeService {
        public int calculateIndemnity(int employeeId) {
            Employee employee=getEmployeeById(employeeId);
            return employee.workAge * employee.salary;
        }
   }

后来,随着这块业务逻辑的演进,其实公司是家具备人文关怀的好公司,再原有基础上,按照职级再额外补发一定的金额:

public int calculateIndemnity(int employeeId) {
    Employee employee = getEmployeeById(employeeId);
    switch (employee.level) {
        case P6:
            return employee.workAge * employee.salary + 10000;
        break;
        case P7:
            return employee.workAge * employee.salary + 20000;
        break;
        default:
            throw new UnsupportedOperationException("");
    }
}

当然,这段逻辑可能被重复定义,有可能散落在各个Service。
这里就出现了「代码的坏味道」
新的枚举值出现怎么办?
显然,添加一个新的枚举值是非常痛苦的,特别通过 switch 来控制流程,需要每一处都修改枚举,这也不符合开闭原则。而且,即使不修改,默认的防御性手段也会让那个新的枚举值将会抛出一个异常。

为什么会出现这种问题?
是因为我们定义的枚举是简单类型,无状态。

这个时候,需要用重新去审视模型,这也是为什么 DDD 是用来解决「大泥球」代码的利器。
一种好的实现方式是枚举升级为枚举类,通过设计「值对象」来重新建模员工等级:

abstract class EmployeeLevel {
    public static final EmployeeLevel P_6 = new P6EmployeeLevel(6, "资深开发");
    public static final EmployeeLevel P_7 = new P7EmployeeLevel(7, "技术专家");

    private int levle;
    private String desc;

    public EmployeeLevel(int levle, String desc) {
        this.levle = levle;
        this.desc = desc;
    }

    abstract int bouns();
}
class P6EmployeeLevel extends EmployeeLevel {
    public P6EmployeeLevel(int level, String desc) {
        super(level, desc);
    }

    @Override
    int bouns() {
        return 10000;
    }
}

static class P7EmployeeLevel extends EmployeeLevel {
    public P7EmployeeLevel(int level, String desc) {
        super(level, desc);
    }

    @Override
    int bouns() {
        return 20000;
    }
}

你看,这里叫「EmployeeLevel」,不是原先的「Level」,这名字可不是瞎取的。
这里,我把 EmployeeLevel 视为值类型,因为:
● 不可变的
● 不具备唯一性
通过升级之后的模型,可以把员工视为一个领域实体 Employee:

class Employee {
    private String name;
    /**
     * 薪水
     */
    private int salary;
    /**
     * 工龄
     */
    private int workAge;
    /**
     * 职级
     */
    private EmployeeLevel employeeLevel;

    public int calculateIndemnity() {
        return this.workAge * this.salary + employeeLevel.bouns();
    }
}

可以看到,计算赔偿金已经完全内聚到 Employee 实体中,我们设计领域实体的一个准则是:必须是稳定的,要符合高内聚,同时对扩展是开放的,对修改是关闭的。你看,哪天 P8 被裁了,calculateIndemnity 是一致的算法。
当然,并不是强求你把所有的枚举都替换成类模型来定义,这不是绝对的。还是要按照具体的业务逻辑来处理。文章来源地址https://www.toymoban.com/news/detail-476242.html

到了这里,关于代码的坏味道(二)——为什么建议使用模型来替换枚举?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 我为什么不建议使用框架默认的 DefaultMeterObservationHandler

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判。如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 issue,谢谢支持~ 另外,本文为了避免抄袭,会在不影响阅读的情

    2024年01月21日
    浏览(44)
  • Java面试题:为什么HashMap不建议使用对象作为Key?

    HashMap 是一种基于哈希表的动态数据结构,它允许使用任意不可变对象作为键(key)来存储和检索数据。然而,在某些情况下,使用对象作为 HashMap 的键可能会遇到一些问题。   首先,我们需要明确对象作为 HashMap 的键需要满足一些条件: 不可变性:对象的属性不能被修改,

    2024年04月22日
    浏览(43)
  • 为什么 IDEA 建议去掉 StringBuilder,而要使用 “+” 拼接字符串?

    作者:京东零售 姜波 来源:京东云开发者社区 各位小伙伴在字符串拼接时应该都见过下面这种提示: 内容翻译:报告StringBuffer、StringBuilder或StringJoiner的任何用法,这些用法可以用单个java.lang.String串联来替换。使用字符串串联可以使代码更短、更简单。只有当得到的串联至

    2024年02月05日
    浏览(54)
  • Java开发手册中为什么不建议在for循环中使用“+“进行字符串操作

    java开发手册中对于循环体中进行字符串的拼接要求如下: 【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。 说明:下例中,反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行 append操作, 最后通过 toString 方法返回

    2024年02月08日
    浏览(48)
  • 定期为什么不建议自动转存

    自动转存是银行一种资金周转方式,一般是指用户的定期存款到期之后,银行可自动将到期的存款本息按相同存期一并转存的行为,在存款过程中,一般不建议投资者自动转存,其主要原因如下: 1、资金支配受到限制 如果是三年期存款,投资者选择存款时自动转存,则在存

    2024年02月12日
    浏览(36)
  • 为什么编程都建议不要用拼音命名

    我们看看知乎答主举的搞笑例子,一句话全部都是shi,表达起来确实困难。 上面这个回答,一句话全部都是“shi”,表达起来确实困难。并且让人误解 那么编程都建议不要用拼音命名,主要有以下原因: 可读性差 :使用拼音命名的变量、函数名等很难被其他人理解,特别是

    2024年02月04日
    浏览(69)
  • 为什么建议同时学多门编程语言

    晨读一本名叫《4点起床》的书,书中有一段描述与最近学习编制语言时自己的感受完全一致。算是一个小经验,分享给大家。 书中有一章的标题为《同时学六国语言记起来比较快》,其中有两段描述如下: 为什么我推荐大家同时学不同的语言呢?实不相瞒,我这几年在学西

    2024年02月10日
    浏览(67)
  • 你用过猿如意吗?猿如意可以使用ChatGPT哦,这里详细介绍了猿如意的功能,为什么我建议你使用猿如意,来看看吧

    你是否还在为为每次安装IDE(集成开发工具)要去各种网站找教程而烦恼? 你是否还在为各种文本格式转换而头痛? 你是否在为斗图都不过兄弟们而卑微? 你是否在为互联网中庞大冗杂却低效的教程文档而崩溃? 你想不想有一个关于代码的模板库? 你想不想不用\\\"科技\\\"就使

    2023年04月13日
    浏览(41)
  • 为什么不建议企业用薪资系统来跟踪项目时间?

    身处在一个每分钟都很重要的世界里,企业必须勤于管理时间和工资。 虽然使用薪资系统进行时间跟踪似乎是一个实用的解决方案,但这种方法可能导致许多问题。 本文将讨论专用的时间跟踪软件对任何组织都必不可少的原因,以及依靠薪资系统进行时间管理可能产生的挑

    2024年02月12日
    浏览(41)
  • 为什么我不建议在阿里云官网报考ACP/ACE认证?

    考acp的时候刚开始以为直接在阿里云官网寻找课程备考报名就可以了,官方提供的课程应该没有问题,但是实际学习的时候发现,官方提供的内容虽然涵盖了大部分知识点,但是由于缺少对应的学习服务,学习效果上总是差强人意。 除了学习效果意外,再就是两个更重要的原

    2024年02月15日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包