How to use generic class with specific objects in a static context?

前端 未结 2 930
难免孤独
难免孤独 2020-12-25 08:30

I\'m gonna try to explain at my best.

I use Play Framework 2, and I will do a lot of CRUD actions. Some of them will be identitcal, so I\'d like to KISS and DRY so a

相关标签:
2条回答
  • 2020-12-25 09:14

    (Disclaimer: I have no experience with playframework.)

    The following idea might help:

    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<Long, Model> finder = null;
        protected static Form<Model> 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();
        }
    
    }
    

    This way you can create a hierarchy of implementations.

    (This must be some fancy-named design pattern, but I don't know the name ATM.)

    0 讨论(0)
  • 2020-12-25 09:17

    This can be achieved using delegation: define a regular Java class containing the CRUD actions logic:

    public class Crud<T extends Model> {
    
        private final Model.Finder<Long, T> find;
        private final Form<T> form;
    
        public Crud(Model.Finder<Long, T> find, Form<T> form) {
            this.find = find;
            this.form = form;
        }
    
        public Result list() {
            return ok(Json.toJson(find.all()));
        }
    
        public Result create() {
            Form<T> 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
    }
    

    Then you can define a Play controller having a static field containing an instance of Crud<City>:

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

    And you’re almost done: you just need to define the routes for the Crud actions:

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

    Note: this example produces JSON responses for brevety but it’s possible to render HTML templates. However, since Play 2 templates are statically typed you’ll need to pass all of them as parameters of the Crud class.

    0 讨论(0)
提交回复
热议问题