Is there a design pattern to collect and aggregate information and report it at the end?
I'm working on a desktop software with user interface. The software lets the user do certain things. Now, this software will need to keep track of certain things the user has done over time. Finally, when the time is right, this software should post the information it has accumulated over time. I'm wondering what design pattern would fit in this scenari开发者_C百科o.
I used to use a static class and a static string field to accumulate the bits and pieces of information and finally send that string to report on the state. But I'm in a similar situation again and I think I could do better than make calls to this static field throughout the code.
Is there a design pattern around this?
Expect simple answer here (no pattern).
You would EventEmitter.emit() an Event for every interesting (at every interesting place) thing that you would want to track in your application (for what ever purpose). The EventCollector is responsible for keeping track of all the events that are emitted. At the right time, the EventReporter will generate() a Report based on the Events collected and stored by EventCollector. So below are the classes I see.
EventEmitter
- emit(Event e)
Event
EventCollector
EventReporter
- Report generateReport()
You can ignore EventCollector for your simple use case and can use a Java Collection (List if you want to preserve the order the events happened etc).
- There is nothing wrong in using a static holder for your simple scenario. Sometime simple things look suspicious to us programmer's ;-)
- Events are no longer Strings. They are abstractions on their own.
- Single Responsibility Principle: Each class doing one logical thing and can be tested independently
- Simple and easy to understand
Well if you don't want to couple your classes, a Singleton is the way to go. Depending on the programming language you are working with, you'll have to implement this pattern differently
As I understand it, you want to share Information between different tiers of your application. A Singleton as you described above, would be just fine.
Any different solution would increase the coupling of your classes a lot. Therefore the Singleton pattern is the way to go.
edit: Since you got me thinking, why I'm getting downvotes, I'll change my answer to: use Dependency Injection instead. Read this, and you'll understand why: http://sites.google.com/site/steveyegge2/singleton-considered-stupid (at least I did) and also get a hint on how to do it.
Hey SO, you just brought me off the dark path of Singleton misuse just at the right time.
Ok, I'll try one to. Though I like the answer from @Pangea. There are a lot more patterns that are thinkable to do this one.
What about:
Use an MVC pattern to let your user change your data. It works like: I am a user and via the V of MVC, I manipulate the GUI. When things are happening in the GUI, the C (controller) gets the informations. Mostly via events. He is the one that keeps track of the events and no one else. Then the M (model) is updated via the controller. So the controller contains every single action that someone could do. The Controller will pass the information from the GUI in the right format to the Model.
This Model knows how to update itself and will respond (by an event for instance) to the View that it has been changed. (NotifyObserver()
).
When the time is there, and you want to post your info. You can simply create another view (thats the fun thing about the MVC pattern) and show the information in the way you want. So the GUI will be completely seperated from the rest.
So that is part one of the pattern.
Now, if we would like to undo actions and redo (don't know if you want that). We could simply check the Command pattern. This will allow you to specify user actions by means of a command. This command can do and undo a specific action. These two patterns can easily be merged in one single application.
I hope my answer is sufficient to your needs. I'm ready for any kind of question about these two patterns!
Well the problem you're facing is a sort of common issue, but to be considered so, your problem needs to think much more larger. Well, I explain myself.
Collecting elements and, at a certain point release them to some end point by emptying the collection is an issue that can be faced in a very simple way or through finer solutions.
You probably used this solution (writing in c#):
public class MyClass {
private static Stack<Object> collection;
...
MyClass() {}
...
public void InsertElement(Object el) {}
public Object[] RemoveAll() {}
}
So that you can easily put and retrieve elements in this class. Sure it is not a very good solution from the point of view of programming best practice because you do not reach scalability, flexibility, maintenance and efficiency.
An Iterator pattern can be used in order to have a full featured collection (iterable) and that also has the possibility to empty the elements and return them before clearing:
public class MyCLass : Iterable { // I do not remember the name of the interface that in C# enables a class to be iterated through the foreach statement
private Stack<Object> collection;
...
MyClass() {}
...
public Object GetElementAt(unsigned int pos) {}
public void InsertElement(Object o) {}
...
/* Members implemented from the interface */
...
public Object[] RemoveAll() {}
}
But iterating is not the object you want (watch out: Iterator is a pattern, but in this case not the one you want).
An event-based approach can be considered. You see, using a callback pattern lets you define an event that, when fired, causes your collection to be freed and all elements returned.
public class MyCLass {
...
... event ...
...
MyCLass() {}
...
public Object[] RemoveAll() {}
}
Defining a pointer to function (in c# a delegate) and defining an event on it, when your application needs to free the collection the event is raised and the correct freeing function is called automatically as the event fires.
Well, in your case I would put it simple. Please change approach because using static elements in a class as you do is not correct. Static elements are elements capable of persisting in all classes and guarantee that the same values are viewed by all instantiated classes as a sort of shared memory, or better class state!!! in your case just keep a collection of elements and handle it inside a simple class as I'm showing you here:
public class CollectionManagerWrapper {
private Stack<Element> elements; /* Element is the type you are interested in */
public String Size {
get { return this.elements.Size(); }
}
CollectionManagerWrapper() {
this.elements = new Stack<Elements>();
}
// Methods
public Element[] getAll() {
Element[] els = this.elements.ToArray();
this.elements.Clear();
return els;
}
}
As you can see no special pattern is used because I think it would be overkill doing so... I reported you some examples of possible patterns because I do not know as certain if you want or not to have a robust application or just a solution to solve your problem without minding scalability, flexibility and so on.
精彩评论