vendredi 6 février 2015

Open closed principle vs abstraction leaking (Java enums)


In Java, an enum is not a plain replacement for a number (like in C/C++), but a family of objects which can have properties. For instance



public enum Order {
NAME("Ordering by name"),
SURNAME("Ordering by surname");

private String comment;

private Order(String comment) {
this.comment = comment;
}

public String getComment() {
return this.comment;
}
}


And then, I could do:



System.out.println(Order.NAME.getComment());


Now, imagine I define an API like:



public interface MyApi {
public List<People> getAllPeople(Order order);
}


I can do several things in the implementation:




  • A switch with the enum, defining the ORDER BY clause as needed for each value.




  • Add a new parameter to the enum:




    • an extreme example would be, with SQL, NAME("Ordering by Name", " ORDER BY peo_name") 1, and just do


      if (order != null) { sql += order.getOrderClause(); }




    • Using JPA, I would use the property and not the column name, so I could do `NAME("Ordering by Name", "name") 2 and do


      if (order != null) {jpql += " ORDER BY p." + order.getOrderAttribute(); }






On the plus side, I find it as the most straightforward way of implementing the Open/Closed principle (if I add a new ordering criteria, I just need to add the respective enum instance). On the less positive way, I am exposing internal details of my server to the client (although the client is not able to "inject" a different value to profit from it).


What kind of problems can I expect from this breach of abstraction? Is it worth it the simplicity of coding? There is any -hopefully- simple3 way to improve this design (the JPA one)?


1 peo_name being the name of the column in the DB.


2 name would be an attribute of People, that is, there exists a getName() method in People.


3 One alternative I can think of would be using a new enum, Order2, as part of the API, and then link each instance of such enum to one instance of Order, but I think it is complicated and somewhat breaks the open/closed principle (to add a sorting criteria I would need to modify both Order and Order2).





Aucun commentaire:

Enregistrer un commentaire