在控制器中播放框架和 DRY

Posted

技术标签:

【中文标题】在控制器中播放框架和 DRY【英文标题】:Play framework and DRY in controllers 【发布时间】:2013-12-12 09:38:40 【问题描述】:

我目前正在使用 Play Framework 编写一个典型的 REST API。 Play 控制器(如您所知的静态方法)调用一些服务。 服务由 ServicesManager 提供。 代码类似于:

class RestController 
    protected static UserService userService;
    protected static void getServices() 
        userService = ServicesManager.getUserService();
    


class UserApiController extends RestController 
    public static Result createUser() 
        getServices();
        ...
        userService.createUser();
        ...
    
    public static Result updateUser(String userId) 
        getServices();
        ...
        userService.updateUser(...);
        ...
    

我的代码中有几件事困扰着我: - getServices() 用于每个控制器方法。我该如何避免呢? - 设计基于静态(由于 Play)和受保护的访问。它意味着强耦合。你同意(或不同意)这是一个相当大的设计缺陷吗?

谢谢。

【问题讨论】:

【参考方案1】:

根据您使用的 Play 版本,您可以采取一些步骤来使您的代码“更少 WET”和/或更松散耦合:

Play 2.0 及之前的版本

扩展play.GlobalSettings(如果您还没有这样做),并覆盖onStart 方法:

@Override
public void onStart(final Application app) 
    // Initialise your ServicesManager class here

接下来,我将从您的父控制器中删除 getServices() 方法:

public class RestController extends Controller 

    protected static UserService userService = ServicesManager.getUserService();

    // Other service declarations ...

这样您就不必从每个操作方法中调用getServices()

玩 2.1 以后

正如您所提到的,在早期版本的 Play 控制器类中没有实例化,动作被定义为静态方法。 Play 2.1 引入了控制器实例化的概念,让开发人员可以控制管理控制器的创建。您可以找到参考实现here,了解如何告诉 Spring 框架管理您的控制器和连接服务类。这现在有助于更松散耦合的代码。

【讨论】:

非常感谢。我去了第一个(也是更简单的)解决方案。对于那些可能想知道为什么不调用 onStart 的人:直到第一个请求才调用它...

以上是关于在控制器中播放框架和 DRY的主要内容,如果未能解决你的问题,请参考以下文章

播放框架控制器继承

在播放框架 1.2.5 中对路由不区分大小写

初始Django

MVC 验证 - 使用服务层保持 DRY - 最佳实践是啥?

在视图中呈现 JSON 数据 - 播放框架

AVPlayer 视频播放