Let me introduce my situation:
I have Java EE application and in one package, I want to have classes which will act primarily as cache for some data from database, for example:
- class that will hold all articles for our website
- class that will hold all categories
- etc.
Every class should have some update()
method, which will update data for that class from database and also some other methods for data manipulation specific for that data type.
Now, I would like to call update()
method for all class instances (there will be exactly one class instance for every class) from one place.
What is the best design?
-
This sounds like it might work with the visitor pattern: en.wikipedia.org/wiki/Visitor_pattern or maybe the Strategy pattern, used here: stackoverflow.com/questions/985960/… as an alternative to the visitor patternFrustratedWithFormsDesigner– FrustratedWithFormsDesigner2013年10月21日 14:09:28 +00:00Commented Oct 21, 2013 at 14:09
-
Inheriting from a class or from an abstract class (with the common methods in it) might be a good solution.codeKaichu– codeKaichu2013年10月21日 14:10:08 +00:00Commented Oct 21, 2013 at 14:10
-
2@FrustratedWithFormsDesigner - or both. Visitor visits each object in a composite structure and calls a method (update?). Strategy implements the logic of what update does.Matthew Flynn– Matthew Flynn2013年10月21日 16:04:05 +00:00Commented Oct 21, 2013 at 16:04
2 Answers 2
You should seriously consider using the observer pattern and, rather than calling an Update method which iterates through a list of objects that need an Update, you simply call an event to which all of your objects are subscribed for as long as they are valid to be updated?
-
observer pattern seems to me like the most elegant solution from the class design point of view, but our cache is not updated very often (mabye few times a week), how big is performance hit?betatester07– betatester072013年10月21日 21:01:17 +00:00Commented Oct 21, 2013 at 21:01
-
@betatester07: There shouldn't be a performance hit. If anything, it'll probably be slightly optimised by the framework. But feel free to profile it and be sure.pdr– pdr2013年10月21日 23:25:15 +00:00Commented Oct 21, 2013 at 23:25
-
thanks. maybe, one more question - what is best approach to access other methods on one of my cache objects?betatester07– betatester072013年10月30日 11:59:24 +00:00Commented Oct 30, 2013 at 11:59
-
@betatester07: Not understanding your question, sorry. But it sounds unrelated to the original question, so I'd suggest raising it separately, rather than making this conversational.pdr– pdr2013年10月30日 18:02:34 +00:00Commented Oct 30, 2013 at 18:02
-
yes, you are right, I will open new question.betatester07– betatester072013年10月31日 20:09:15 +00:00Commented Oct 31, 2013 at 20:09
While you might be tempted to create an abstract class or interface. I would strongly advise against that approach.
Reasons Against Interfaces
- You'll end up with two classes that do a lot of the same work.
- It defines a contract but doesn't improve cohesion of code.
Reasons Against Abstraction
- You'll end up with 3 classes. The base class and 2 implementing classes.
- Most of the abstract methods will be public. Abstraction works best when the scope of the re-used methods are protected. This makes it clear that the abstract class is truly there to assist inherited classes.
Recommended Approach
- Define a sealed caching class that doesn't care when it caches. Create a class called
DatabaseCacher
that knows how to keepICachable
objects in memory. Articles
andCategories
then implement theICachable
interface.
DatabaseCacher
should be used to modify the properties of ICachable
. Don't implement any setter methods on your ICachable
objects. Instead, create a generic setter method on DatabaseCacher
that takes the name of the property as a parameter with it's value. This allows you to localize all caching and write operations of those objects.
I would avoid using a property change event listening approach. As it creates a large number of binding between only two entities (DatabaseCacher
and ICachable
objects). Property change listeners work best when the connection is ambiguous.
-
2Your reasons against interfaces don't make any sense, especially considering your recommended approach, which is to define an interface (ICachable).Matthew Flynn– Matthew Flynn2013年10月21日 15:59:35 +00:00Commented Oct 21, 2013 at 15:59
-
@MatthewFlynn I was referring to creating multiple caching objects that implement an interface. Sorry if that wasn't clear.Reactgular– Reactgular2013年10月21日 16:30:25 +00:00Commented Oct 21, 2013 at 16:30
-
what do you mean by "sealed caching class that doesn't care when it caches"?betatester07– betatester072013年10月21日 19:24:33 +00:00Commented Oct 21, 2013 at 19:24
-
@betatester07
sealed
as in not abstract, and caching as in it stores the objects in a collection to be reused later.Reactgular– Reactgular2013年10月21日 19:27:41 +00:00Commented Oct 21, 2013 at 19:27
Explore related questions
See similar questions with these tags.