1

I have a system in which I will perform queries to a database. I want Query1, Query2 and Query3 to use the same methods in their way to the data source layer.

To do that I would like to make something similar to Strategy or Template Patterns, where I have a part of the code which is a default behavior for all queries (getting to the database layer, connection, executing the query and so on) and a variable part (building the query itself).

I think this idea is good and feasible. I would receive a parameter from the client specifying the query to be built, build it and run. The only question is: given this parameter, how can I decide which method to call to build the query? This is my current solution: (is this solution a pattern?)

public Query QueryFactory(string queryIdentifier){
   if(queryIdentifier == "query1")
      return BuildQuery1();
   else if(queryIdentifier == "query2")
      return BuildQuery2(); 
}

It works, but I don't think this is "pretty enough", I would like something nicer. It would be perfect if it didn't require the developer to add a new if statement when he created a new query. Is there any way to improve this if/else chain? And to make this decision automatic?

Edit: The problem I want to solve is: I have queries that are going to be called against a database. I want to have the same flow so I don't have duplicated code for the queries that do not have any business logic applied to it (ex: get all users, get all students, and so on)

5
  • This smells suspiciously like Second-System Effect. Can you be a little more specific about the particular problem that you are trying to solve? Commented Apr 15, 2014 at 23:10
  • Sure, I have queries that are going to be called against a database. I want to have the same flow for the queries that do not have any business logic applied to it (ex: get all users, get all students, and so on)
    – JSBach
    Commented Apr 15, 2014 at 23:12
  • 1
    Normally that's done with a Repository object. You have CRUD methods for each domain object (users, classes, etc). Sometimes those CRUD methods are code-genned. Occasionally, someone will use a Generic Repository, which see. BTW, Student is just a special case of User. Commented Apr 15, 2014 at 23:16
  • 2
    Sounds like you've got a standard FactoryMethod pattern. I don't see anything wrong with that (though, I usually prefer to us enums and a switch to identify which object to return). Commented Apr 15, 2014 at 23:17
  • If you can do meta-programming, then dynamically create an instance of the class, otherwise a switch statement could be prettier comparing to if/else statements -- and slightly faster. Also you didn't clearly mention what languages you're using. Your question could have different answers in different languages.
    – Mahdi
    Commented Apr 16, 2014 at 6:25

1 Answer 1

2

As Steve Evers states, using an enumeration as a key and either a Class to instantiate (or an instance of Query pre-built) to return. If you don't like the if/else pattern, I know Java has Map implementations, of which the EnumMap would be a good fit (where it optimizes the utilization of Enumerations as the key values in the map.

Then your code looks something like

public Query QueryFactory(QueryType type){
   return localMap.get(type);
}

With the assumption that you define an enumeration named QueryType, and your localMap contains the appropriate Query instances for each type.

If you didn't want to pre-instantiate the queries, the code would use the map to store the Class, which would allow the object to be instantiated then and there

public Query QueryFactory(QueryType type){
   Class queryClass = localMap.get(type);
   return (Query) queryClass.newInstance();
}

Again, this is all using Java as an example. Just realized you didn't mention which language. But it can be cleaned up the way it sounds like you would prefer.

1
  • Yes, I used string in my example for sake of simplicity, but the idea is to use an ENUM. Java is OK, the important is the concept, not the implementation. Thanks a lot :)
    – JSBach
    Commented Apr 16, 2014 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.