LaraStore商城系统优化:商品分类模型的优化 2017-01-05


LaraStore的第一版,当时有4-6位程序员参与其中。所以部分模型中的代码风格不太统一,在经过2016年的整理优化和调整后,我们的代码风格基本保持一致了。

模型是MVC框架中 M的部分,也就是数据库对象映射的部分。在所有模型的设计中,最容易犯的一个错误就是:把所有业务逻辑所需的函数全部写模型里面。

这样做有什么问题呢?最大的问题是:模型会越来越臃肿,这样会大大降低项目的可维护性,而且会随着业务逻辑的变化,模型里面的代码会经常需要改来改去,这样意味着 控制器的部分 也要做调整,模板视图的部分也要做调整?正所谓,牵一发而动全身!!!最后陷入不断修改的死循环中。


大致的问题就是上图所示。如何解决?

经常有人问题 “laravel优雅在哪里?” 那我在这里简单的回答下,laravel和LaraStore优雅在哪里!

【1】简洁的代码

   要做到简洁,非常不容易!不优雅的模型和控制器里面写满了业务逻辑!!

   代码的重复和堆砌,同一个功能,在A控制器里面写了,在B控制器中又重复写一遍。

   简洁的代码,如果能用最少的代码实现同一个功能,那就不需要多写一行代码!

   功能模块,一次书写,处处可用!

【2】架构逻辑清晰

   清晰的架构,当你想要去调整某一个模块的时候,你可以快速定位到这个模块,而不需要满世界去搜索!

  就好像盖房子一样,有一个清晰的设计图纸,不管这个房子是1层,还是100层,只要严格按照图纸来施工,迭代,最终都可以成功完成!

 【3】语义化的代码

   函数命名非常重要,一部分培训学校出来的程序员喜欢用汉语拼音来命名函数,这是非常可怕的一件事情。

   比如: 商品分类模型  Category   而不是shangpingfenlei ,

//正确的打开方式
$category  = Category::find(1);

//不优雅的命名
$fenlei    = FenLei::find(1);
不好意思 ,时间长了后 ,我不知道 fenlei 到低是“分类”还是 “分内” 或者是其他。。。

所以,程序员学好英语非常重要,不光是函数的命名,很多优秀的编程技术书籍大部分是英文原版的比较多。

下面我们说回来,在LaraStore的研发过程中, 我们是如何优化模型的!
我们以商品分类模型为例子来说明下。

软件研发的过程,其实和装修房子非常相似!如果我们现在要装修一套房子,具体要做哪些事情?

我们可以把“装修房子”这个看似比较大的内容,慢慢拆分成一个一个的小任务和小模块

【1】刷墙

【2】铺地板

【3】做防水

【4】布线

【5】按灯泡

【6】买电器

【7】买家具

然后,我们分别安排7个人去完成这7项任务即可。

每个小功能模块都只实现一个简单的功能,这就是原始模块。也可以叫这样的功能模块为“原子模块”。

同样,我们这里 商品分类模型要实现哪些功能呢?

我们可以来看看



当然我们获取到一个 商品分类模型的时候,我们可以通过模型快速的获取到这个模型相关的数据。

//获取到模型
$cat  = Category::find($id);

//商品分类下的商品列表
$cat->goods_list();

//商品分类下的价格区间
$cat->price();

//商品分类下的属性筛选列表
$cat->attr()

//商品分类下的品牌列表
$cat->brand_list()

注:上面的数据已经包含了 该分类和该分类所有子类的数据


这样就非常简单和直观,获取到了一个商品分类模型,就很自然就获取了相关的其他数据!而且这些数据默认已经开启了redis的缓存。

显然这些业务逻辑,是不能直接写入到模型文件里面的。

对模型的优化和设计,大致有如下方法。


【1】模型原始文件,只包含基本的定义文件和关联关系。

<?php

namespace App\Models;

use Baum\Node as Node;
use LaraStore\Repository\Category\BaseRepository;
use LaraStore\Repository\Category\StaticRepository;

/*
|-------------------------------------------------------------------------------
|
| 分类模型 继承于baum 无限套嵌集合
|
|-------------------------------------------------------------------------------
*/
class Category extends Node{

    use BaseRepository,StaticRepository;
    protected $table = 'category';
    
    protected $fillable = ['..'];
 }

模型文件里面 不要写任何业务逻辑


【2】使用trait方式 平行的扩展

trait方法  可以让对象线性的继承方法和属性。写在trait里面的方法,可以直接让继承trait的对象使用。

use BaseRepository,StaticRepository;

//分类模型 继承成了2个 Repository的方法

我们可以把简单的业务逻辑写到Repository里面


【3】使用Presenter来扩展模型

再看看 presenter里面的定义部分

这样 我们可以把部分业务逻辑写到 presenter里面来。

$cat->presenter()->goods_list();
//获取商品分类列表

$cat->presenter()->brand_list();
//获取品牌列表


【3】进一步扩展presenter

我们可以把一些其他的功能模块,注入到 presenter里面。

在CategoryPresenter里面,可以进一步注入其他功能模块


这样,模型的结构就非常清晰了。我们再来总结一下

【1】模型定义文件只做定义和配置,不写任何业务逻辑

【2】trait方法,线性扩展业务逻辑

【3】注入presenter类 扩展业务逻辑

【4】在presenter类中,再次注入其他功能模块类

基本就是这些。当然如果你的业务逻辑比较简单,也可以酌情考虑2和3.


参考链接

laracasts

本文章为 LaravelStore官网原创 转载请注明出处。谢谢合作!