博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小酌重构系列[12]——去除上帝类
阅读量:5755 次
发布时间:2019-06-18

本文共 2490 字,大约阅读时间需要 8 分钟。

关于上帝类

神说:“要有光”,就有了光。——《圣经》。上帝要是会写程序,他写的类一定是“上帝类”。程序员不是上帝,不要妄想成为上帝,但程序员可以写出“上帝类”。上帝是唯一的,上帝的光芒照耀人间,上帝是很爱面子的,他知道程序员写了“上帝类”,抢了他的风头,于是他降下神罚要惩戒程序员。——既然你写了“上帝类”,那么就将你流放到艰难地修改和痛苦的维护的炼狱中,在地狱之火中永久地熬炼。

你看,上帝也是有脾气的,你做了什么他都知道,你不能抢他的风头,否则你就要付出代价,受到相应的惩罚。为息帝怒,咱们还是老老实实地编写一些“小类”吧。

有些开发者为了贪图简便,看到一个现成的类,也不管这个类是做什么的,需要追加功能时,就向这个类里面添加功能代码。久而久之,使得一些类变成了“上帝类”。什么是“上帝类”?上帝类也叫万能类,意指做了太多“事情”的类。在开发基于WebForms的应用程序时,Page页面的后置代码中包含了访问数据库、处理业务逻辑、绑定页面数据、页面事件处理等这些事情,这就是上帝类的一个举证(可能很多人都这么干过)。

上帝类的优缺点

优点

“存在即合理”——上帝类比较适用于一些较小的、稳定的应用开发场景,即那些业务逻辑不复杂、也不需要太多维护的应用程序。

比如:一些小工具的开发,不需要过多地考虑类的粒度和职责划分,楼主博客中用的Windows Live Writer代码高亮插件就是这么做的。

缺点

上帝类的缺点是显而易见的,上帝类的颗粒度较大,它缺乏可读性、可扩展性和可维护性。

上帝类违反了“SRP原则”,上帝类担任的职责太多了,该做的和不该做的它都做了。
同时也违反了“OCP原则”,上帝类功能之间的耦合性太高了,因此不具备可扩展性,当需求变化时,可能会涉及到大量代码的修改。

“SRP原则”和“OCP原则”的我就不再赘述了,想了解这两个原则,请参考该系列的另外两篇文章:和。

示例

重构前

下面这个CustomerService类,定义了5个方法:

  • CalculateOrderDiscount()方法:结合客户信息,计算订单的折扣
  • CustomerIsValid()方法:结合订单信息,判断客户是否有效
  • GatherOrderErrors()方法:结合订单的商品信息和客户信息,收集订单错误信息
  • Register()方法:注册客户信息
  • ForgotPassword()方法:处理客户忘记密码
public class CustomerService{    public decimal CalculateOrderDiscount(IEnumerable
products, Customer customer) { // do work } public bool CustomerIsValid(Customer customer, Order order) { // do work } public IEnumerable
GatherOrderErrors(IEnumerable
products, Customer customer) { // do work } public void Register(Customer customer) { // do work } public void ForgotPassword(Customer customer) { // do work }}

在业务上,这些方法多少和Customer是有一些关联的。但这不意味着,只要是和Customer相关的方法都要放到CustomerService中。

这个类还可以在职责上做一些划分,粒度可以控制的在细一些。

重构后

重构后,我们按职责将CustomerService拆分为了CustomerOrderServiceCustomerRegistrationService

public class CustomerOrderService{    public decimal CalculateOrderDiscount(IEnumerable
products, Customer customer) { // do work } public bool CustomerIsValid(Customer customer, Order order) { // do work } public IEnumerable
GatherOrderErrors(IEnumerable
products, Customer customer) { // do work }}public class CustomerRegistrationService{ public void Register(Customer customer) { // do work } public void ForgotPassword(Customer customer) { // do work }}

拆分后,我们可以看到:

  • 这两个类的语义和它们的命名以及定义在其中的方法都是契合的。
  • 类的粒度变小了,代码的可读性增强了,并且有利于将来的扩展、维护、修改。

在开发过程中,我们应该保持一个良好的习惯,为类中追加功能时,尽量确认好类的职责,并控制好类的粒度,这有益于代码的可读性、扩展性、维护和修改,这样就不会被上帝发现了。

关注keepfool

转载地址:http://xfckx.baihongyu.com/

你可能感兴趣的文章
罗森伯格助力2011年中国智能建筑技术发展应用论坛哈尔滨站
查看>>
网络割接
查看>>
windows server 2016 活动目录(二)
查看>>
openstack G版 修改vm的flavor级别
查看>>
python_控制台输出带颜色的文字方法
查看>>
java泛型中特殊符号的含义
查看>>
一秒 解决 ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql 问题
查看>>
Android组件化最佳实践 ARetrofit原理
查看>>
舍弃浮躁, 50条重要的C++学习建议
查看>>
同步手绘板——将View的内容映射成Bitmap转图片导出
查看>>
【Android游戏开发之十】(优化处理)详细剖析Android Traceview 效率检视工具!分析程序运行速度!并讲解两种创建SDcard方式!...
查看>>
微信小程序之wx.navigateback往回携带参数
查看>>
陌陌和请吃饭之类的应用,你要是能玩转,那就厉害了
查看>>
递归的运行机制简单理解
查看>>
汉字转阿斯克马值
查看>>
Java 栈与堆简介
查看>>
【supervisord】部署单进程服务的利器
查看>>
zabbix oracle监控插件orabbix部署安装
查看>>
python3 通过qq 服务器 发送邮件
查看>>
java 多线程踩过的坑
查看>>