阐述一下ecshop各模块的功能_谈谈代码的模块化

3d6c1189c357b51202f392b020a8c149.png

我们总是说要写模块化的代码。但是到底什么是模块化的代码?怎样写模块化的代码?这两个问题不解决,模块化就不接地气、无法落地。

这篇谈谈我对代码模块化的一些思考。

模块化是什么?

代码分割

可能在很多人的理解中,要「模块化」就要分割代码。于是他们会把项目分成很多个文件,甚至分割成很多个版本仓库(repository)。但实际上,这种分割只是手段,而不是目的。如果把这种手段错误地当做是目的,那可能不会带来什么好处,反而会带来很多麻烦。

例如说,我曾经参与过一个项目的开发。对于运行在网络通信框架上的业务逻辑插件,人们为之写了一个基类,命名为 PluginBase。而后,人们把它单独拉出去,作为一个单独的版本仓库。在实际编写插件时,再通过二进制依赖的方式,将 PluginBase 的共享对象(.so)动态链接到进程中去。这种做法其实完全没必要,就属于典型的错把手段当目的。PluginBase 与 PluginFooBar 在逻辑上的结合是很紧密的——基类和派生类,因此将它们分开不合适。打个比方,在开发 PluginFooBar 时,我们可能发现之前在设计 PluginBase 时不够完善,需要再添加一个接口。此时,我们就需要:

  • 修改 PluginBase 的代码;
  • 编译之后发版;
  • 在 PluginFooBar 的版本仓库中修改依赖配置;
  • 编译 PluginFooBar;
  • 将新版本的 libPluginBase.so 和 libPluginFooBar.so 都拷贝到执行环境。

而如果我们能发现 PluginBase 和 PluginFooBar 在逻辑上结合很紧密,而不把它们分开在两个版本仓库中,这样的修改就简单多了:

  • 修改 PluginBase 的代码;
  • 编译;
  • 将新版本的 libPlugins.so 拷贝到执行环境。

按逻辑分块

如此我们可以发现,所谓模块化,分割是手段而非目的。那么究竟要怎么模块化呢?上面的讨论已经提到了一点——跟逻辑相关。这里继续讨论。

要搞清楚模块化,首先要搞清楚什么是模块。模块其实是一个逻辑层面的定义。它是说:如果一个东西,它有定义良好的输入和输出,那么它就是一个模块。再详细说一点,这里所谓的「定义良好」有两个方面需要定义:一方面指输入和输出的格式,一方面指输入和输出的含义。

因此,只要一个东西的行为,在逻辑上满足这个阐述,那么它就是一个模块。例如一块电路板是一个模块;因为它接受固定格式的输入,根据固定逻辑产出输出。又例如一个定义良好的函数是一个模块;因为它接受固定格式的输入(函数参数),根据固定逻辑产出输出。

回到上一小节举的例子。PluginBase 在逻辑上并没有良好的输入和输出——它是基类,通常实际功能由子类完成。因此,强行把它提出去单独管理是不合适的。

怎样写模块化的代码?

具体到写代码时,模块化这个命题主要就落在如何设计函数上了——毕竟,在代码的世界里,函数是最小的模块单元。这里提炼一些实践中的经验。

单一职责

设计函数时,最好让函数的职责足够简单,只有一个。

为什么这么说呢?我们可以考虑一下,如果一个函数既可以做这个,又可以做那个,这种函数需要怎样设计?显然,函数需要根据某些变量的值,或者某种条件,来选择走哪个逻辑分支。比如可能有如下代码:

复制

// bool flag;void foo() { if (flag == true) { bar_a(); baz_a(); } else { bar_b(); baz_b(); } qux();}

变量 flag 用来表示影响函数行为的外部因素。函数 foo 内,根据 flag 取值的不同,会走不同的分支。这种设计看起来不错。比如,有人可能会认为它节省了代码行数,写起来爽快。但是实际上这个函数的行为某种程度上就不是良定义的了——它取决于一个外部变量。试想,一个刚接手这段代码的人,调用 foo 函数,TA 就必须不断去追踪 flag 变量代表的外部环境。如果你觉得追踪某个变量还算好的话,可以试想一下如果这个变量代表「打印机有没有连上」这种在代码中完全不可控的外部因素会怎样。

对于这种代码,就不如把两种不同情形分开,写成这样:

复制

// bool flag;void foo_a() { bar_a(); baz_a(); quz();}void foo_b() { bar_b(); baz_b(); quz();}/*if (flag == true) { foo_a();} else { foo_b();}*/

如此一来,foo_a 和 foo_b 的职责都很明确,接手维护的人再也不会疑惑函数的行为了。

输入决定(input dominated)

设计函数时,尽可能使函数的行为完全由其输入参数决定。特别地,尽可能不要让函数的行为受到全局变量、类的成员变量的取值影响。某种意义上,这和「可重入」的概念比较像。

这一点应该比较好理解。如果一个函数的行为取决于入参之外的因素,那么相当于这个函数在参数之外还有其他输入。显然,这和「输入良定义」是矛盾的。特别地,如果一个类的成员函数的行为依赖类的成员变量的取值,那么使用这个成员函数时,我们就不得不胆战心惊,逐个推演其他的成员函数有可能在某些情况下修改这些成员变量的值。

自我限制

这部分完全是经验之谈。

写代码的时候,可以做一些自我限制。例如说:不写超过 50 行的代码;不超过 5 行的通用功能也要拉出去做工具函数。

人总是爱偷懒的。因此,写代码写 high 的时候,往往就会忘记很多最佳实践。因此,给自己做一些自我限制,有一些强迫症还是很有必要的。据我自己的经验,超过 50 行的代码,往往就会把逻辑写得像面条一样,同时输入和输出的定义就不那么明朗了。因此 50 行虽然没有什么别的意义,但是仅仅将它作为是一个强迫症式的自我限制也是不错的。当然,你可以根据你的习惯,调整这个限制的大小。

来源:Liam Huang / https://liam.page/2018/12/12/writing-modular-codes/ ,只作分享,不作任何商业用途,版权归原作者所有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
“小京东”是商之翼的一款高端产品,它立足于ECSHOP,却彻底颠覆了ECSHOP的原始功能打造出的一款B2B2C模式的综合性商城系统。“小京东”分为经典版和加盟连锁版(多区域多仓库)两个版本,您可以根据您的业务需求进行选择。 对比V2.0新增功能简介: 网站生成纯静态 本次小京东v4.2支持网页生成纯静态,而以往的V2和V3不具备此功能,网页生成静态页面既可以大大降低服务器的负担,也能提高网站的安全系数和用户的浏览速度;静态页更容易被收录,有利于提高网站的排名。 商家入驻支持个人和企业 小京东V4.1对入驻流程进行了升级,入驻流程简单快捷。在同类产品中他们只实现了一种企业入驻类型,而我们的小京东却实现了两种入驻类型,即:个人入驻和企业入驻。 强大的预售功能(随便撸独家) 支持商家自定义预售商品的库存;可自由选择预售商品是需要支付定金,还是必须全款支付,两种支付模式任您选择;自定义预售商品的阶梯价格;自定义预售活动的开始、结束时间,自定义尾款支付的开始、结束时间,自定义预售商品的发货时间。充分满足有预售需求的商家。 商家版手机端(随便撸独家) 商家可以把商城管理移动到手机上,随时随地了解商城的动态,随时随地管理订单(处理发货、退货等)、了解库存、查看佣金等。页面结构逻辑清晰,风格效果清新简洁,浏览感受舒适、流畅,“简约而不简单”的设计风格给您不一样的视觉盛宴。 成功对接扫码枪(随便撸独家) 小京东V4.1完美对接扫码枪,可帮助买家(批发商)批量扫货购物;还可帮助商家快速入库、出库商品。智能扫码枪,你值得拥有! 顶级频道升级 小京东V4.1对顶级频道页面进行了升级,拥有两套小清新模板,可进行自由切换,页面依旧美丽大方、上档次!还可自定义上传二次开发的顶级频道模板,自己的风格自己决定! CMS文章频道 小京东V4.1支持文章频道展示,平台方可自定义文章展示模块。该文章频道页面美观大方,模板丰富,页面排版合理,充分利用了页面空间。同时,文章频道页面为客户创造了及时了解商城动态的平台。其次,文章资讯页最重要的作用是它会让搜索引擎更多的收录您的网页,提高网站访问量!! 更加完美的团购活动 小京东V4.0团购页面升级,不仅支持团购商品按照分类筛选而且支持商品根据上架时间、最后更新时间、销量、价格、折扣等进行排序,让客户在最短的时间里找到最中意的商品。 强大的搜索功能 小京东V4.0对搜索进行了升级,支持全文索引、支持模糊搜索、分词搜索。实现快速建立索引,提高了查询速度,通过索引很大程度上降低了数据库的负载,通过智能分词更准确的查到结果。更快(查询速度)、更准(查询结果)、更稳(降低负载) 。 即时通讯(随便撸独家) 商之翼采用OpenFire搭建高效率的即时通讯服务器,结合PHP与Javascri-pt的技术实现:桌面版客户端+Web版用户端,方便用户与商家即时沟通。因其强大的开源社区,便于二次开发,更可为用户和商家自定义开发桌面版客户端。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值