如何在静态上下文中使用generics类和特定对象?

我会尽力解释。

我使用Play Framework 2,我会做很多CRUD操作。 其中一些将是identitcal,所以我想KISS和DRY所以起初我正在考虑一个包含listdetailscreateupdatedelete方法的抽象类,使用generics对象,并通过指定哪个扩展这个类要使用的对象(型号和表格):

 public abstract class CrudController extends Controller { protected static Model.Finder finder = null; protected static Form form = null; public static Result list() { // some code here } public static Result details(Long id) { // some code here } public static Result create() { // some code here } public static Result update(Long id) { // some code here } public static Result delete(Long id) { // some code here } } 

还有一个将使用CRUD的类:

 public class Cities extends CrudController { protected static Model.Finder finder = City.find; protected static Form form = form(City.class); // I can override a method in order to change it's behavior : public static Result list() { // some different code here, like adding some where condition } } 

如果我不在静态环境中,这将起作用。

但既然如此,我该怎么办?

这可以使用委托来实现:定义包含CRUD动作逻辑的常规Java类:

 public class Crud { private final Model.Finder find; private final Form form; public Crud(Model.Finder find, Form form) { this.find = find; this.form = form; } public Result list() { return ok(Json.toJson(find.all())); } public Result create() { Form createForm = form.bindFromRequest(); if (createForm.hasErrors()) { return badRequest(); } else { createForm.get().save(); return ok(); } } public Result read(Long id) { T t = find.byId(id); if (t == null) { return notFound(); } return ok(Json.toJson(t)); } // … same for update and delete } 

然后,您可以定义一个Play控制器,其中包含一个包含Crud实例的静态字段:

 public class Cities extends Controller { public final static Crud crud = new Crud(City.find, form(City.class)); } 

而且你差不多完成了:你只需要为Crud动作定义路线:

 GET / controllers.Cities.crud.list() POST / controllers.Cities.crud.create() GET /:id controllers.Cities.crud.read(id: Long) 

注意:此示例为brevety生成JSON响应,但可以呈现HTML模板。 但是,由于Play 2模板是静态类型的,因此您需要将所有这些模板作为Crud类的参数传递。

(免责声明:我对playframework没有经验。)

以下想法可能会有所帮助:

 public interface IOpImplementation { public static Result list(); public static Result details(Long id); public static Result create(); public static Result update(Long id); public static Result delete(Long id); } public abstract class CrudController extends Controller { protected static Model.Finder finder = null; protected static Form form = null; protected static IOpImplementation impl; public static Result list() { return impl.list(); } public static Result details(Long id) { return impl.details(id); } // other operations defined the same way } public class Cities extends CrudController { public static Cities() { impl = new CitiesImpl(); } } 

这样您就可以创建实现的层次结构。

(这必须是一些奇特的设计模式,但我不知道ATM的名称。)