提问:多角色项目设计中,如何防止同种功能不同和相同功能代码大量重复问题?

第一次发帖子,布局不太好,请大佬们谅解!
鄙人目前在小公司技术人员转三五个人的项目负责人,在项目设计方面有一些不太了解的地方
1、多种角色,比如普通用户,餐饮店员工,餐饮店老板,管理员等角色
2、商品信息不同角色返回的数据不同,提交的数据不同,怎么防止大量重复的代码,比如FormRequest数据验证,Policy策略验证,Observers等,如果不同角色处理方式不同,有些地方相同,有没有什么办法防止大量重复的代码

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 4

我之前写过一个内容管理相关的项目,和你拥有类似的问题,拥有多种文章的类型。每种文章都写一套增删该查,推荐,状态这些功能,感觉都是十分相同的东西,所以我就写到了同一个控制器当中,冥冥之中,感觉并不应该这么去做,但并没有想到这么做可能会存在的隐患。
说一下我的做法,有比较大的局限,路由参数必须和配置的参数名一样,所以并不太优雅,但你可以参考并指导下。formRequest的验证,也是根据模块去控制。

  1. 创建一个配置文件content.php里面写入内容,这里的news1就是遵循restful路由的名词,类似这样:
    return => ['content'   => [
        'news1'      =>  \App\Models\News1::class,
        'news2'      =>  \App\Models\News2::class,
        'news3'      =>  \App\Models\News3::class,
        'news4'      =>  \App\Models\News4::class
    ],
    ]
    路由很难看
    Route::resource(‘admin/news1’,'admin/ContentController')->name('news1');
    Route::resource(‘admin/news2’,'admin/ContentController')->name('news2');
  1. 定义所有文章类型的模型,最好继承一个接口,接口中规定必须写filter属性和一些不同模型需要用的想法,所有模型继承一个filters方法,此方法是为了更新时过滤字段用的,如下:
private filter = [‘title','content'……];
/**
* 更新时字段过滤的filters方法
*/
public function filters($data) 
{
    return array_only($data,$this->fillable);
}

3.控制器定义一个model属性,在构造函数中,通过请求的路由,确定要实例化模型,赋值给model。
在更新时,注意调用filters方法去过滤字段。

/**
     * constructor.
     */
public function __construct(Request $request)
 {
        $request['module'] = $this->getModuleName($request);
        $class = Instance::instanceClass($request['module']);
        $this->model = Instance::getInstance($class);
}

      /**
     * 获取模块名称
     *
     * @param $request
     * @return string
     */
    private function getModuleName($request)
    {
        return strToLower(explode('/',trim($request->getPathInfo(),'/'))[1]);
    }
  1. libs中写了一个类Instance,就两个方法,一个是根据传递的module参数,去获取配置中对应的类。另外个方法,实例化模型,返回对象。
4年前 评论

百分百的不重复那是不可能的,可读性和极限的抽象要做好平衡。
继续优化对于后续维护者来说成本是指数级的增加。

  1. 配置文件读,可以用 yml 之类的,需要增加一个策略类
    2,策略或代理模式

我觉得与其把功夫用在这不合适不如优化一下现有 Laravel 目录结构中不合理的地方

4年前 评论

@AbrahamGreyson 谢谢,想了挺多时间,一直想不出自己理想的方式,还是先考虑大方向好了,小功能后期review也比较简单

4年前 评论

@AbrahamGreyson 直接回复排版有点问题,

你的多种文章对应多个表,不重复可能比较麻烦

可以创建多个Requests,如:

  • Requests\NewsContent\News1Request
  • Requests\NewsContent\News2Request

rules各表自定义

统一使用change()方法来修改数据

请求参数中,可以让前端规范参数,如news_type=news1

$newsType = Str::ucfirst(Str::lower('news2'));

在控制器中,可以

$newsRequest = app()->make("App\Http\Requests\NewsContent\{$newsType}Request");

之后调用$requestRequest->change();来进行修改

来处理,阅读上应该看起来比较好

我这边现在表是同一个,和你这边的区别比较大,不同角色能修改的字段不同,验证字段的方式也不同,权限也不同,目前有思考过,但是都觉得不太理想

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!