是否有一种设计模式来收集和聚合信息并最终报告?

发布于 2024-10-12 22:20:16 字数 219 浏览 2 评论 0原文

我正在开发带有用户界面的桌面软件。该软件允许用户执行某些操作。现在,该软件需要跟踪用户随着时间的推移所做的某些事情。最后,当时机成熟时,该软件应该发布它随着时间的推移积累的信息。我想知道什么设计模式适合这种情况。

我曾经使用静态类和静态字符串字段来积累零散的信息,最后发送该字符串来报告状态。但我又遇到了类似的情况,我认为我可以做得比在整个代码中调用这个静态字段更好。

有没有相关的设计模式?

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 scenario.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清秋悲枫 2024-10-19 22:20:16

这里期待简单的答案(没有模式)。

您可以 EventEmitter.emit() 为您希望在应用程序中跟踪的每个有趣的(在每个有趣的地方)事物(无论出于什么目的)创建一个 EventEventCollector 负责跟踪发出的所有事件。在适当的时候,EventReporter将根据EventCollector收集和存储的Eventsgenerate()生成一个Report。以下是我看到的课程。

EventEmitter

  • eager(Event e)

EventEventCollectorEventReporterReportgenerateReport

对于简单的用例,

(

  • )

您可以忽略EventCollector,并可以使用Java Collection(如果您想保留事件发生的顺序等,请使用List)。

  1. 对于简单的场景使用静态支架没有什么问题。有时简单的事情对我们程序员来说看起来很可疑;-)
  2. 事件不再是字符串。它们本身就是抽象的。
  3. 单一职责原则:每个类做一件逻辑上的事情并且可以独立测试
  4. 简单易懂

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).

  1. There is nothing wrong in using a static holder for your simple scenario. Sometime simple things look suspicious to us programmer's ;-)
  2. Events are no longer Strings. They are abstractions on their own.
  3. Single Responsibility Principle: Each class doing one logical thing and can be tested independently
  4. Simple and easy to understand
呆橘 2024-10-19 22:20:16

如果你不想耦合你的类,那么单例是最好的选择。根据您使用的编程语言,您必须以不同的方式实现此模式

据我了解,您希望在应用程序的不同层之间共享信息。正如您上面所描述的那样,单例就可以了。

任何不同的解决方案都会大大增加类的耦合度。因此,单例模式是最佳选择。

编辑:既然你让我思考,为什么我会投反对票,我会将我的答案更改为:使用依赖注入代替。阅读本文,您就会明白原因:http://sites.google.com /site/steveyegge2/singleton-considered-stupid (至少我做到了),并获得有关如何执行此操作的提示。

嘿,SO,你在正确的时间让我摆脱了 Singleton 滥用的黑暗道路。

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.

玩物 2024-10-19 22:20:16

好的,我会尝试一个。虽然我喜欢@Pangea 的答案。有很多其他模式可以用来实现这一目标。

怎么样:

使用 MVC 模式 让您的用户更改您的数据。
它的工作原理如下:我是一个用户,通过 MVC 的 V,我操纵 GUI。当 GUI 中发生事情时,C(控制器)会获取信息。主要是通过事件。他是跟踪事件发生的人,没有其他人。然后M(模型)通过控制器更新。因此控制器包含某人可以执行的每一个操作。控制器将以正确的格式将来自 GUI 的信息传递给模型。

该模型知道如何更新自身,并将响应(例如通过事件)视图已更改。 (NotifyObserver())。

当时间到了,你想发布你的信息。您可以简单地创建另一个视图(这就是 MVC 模式的有趣之处)并以您想要的方式显示信息。因此 GUI 将与其他部分完全分开。

这就是模式的一部分

现在,如果我们想撤消操作并重做(不知道您是否想要)。我们可以简单地检查命令模式。这将允许您通过命令指定用户操作。该命令可以执行和撤消特定操作。这两种模式可以轻松地合并到一个应用程序中。

我希望我的回答足以满足您的需求。我已经准备好回答有关这两种模式的任何问题!

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!

白色秋天 2024-10-19 22:20:16

好吧,您面临的问题是一种常见问题,但要如此考虑,您的问题需要考虑得更广泛。好吧,我解释一下自己。

收集元素并在某个时刻通过清空集合将它们释放到某个端点是一个可以通过非常简单的方式或通过更精细的解决方案来面对的问题。

您可能使用了这个解决方案(用 c# 编写):

public class MyClass {
   private static Stack<Object> collection;
   ...
   MyClass() {}
   ...
   public void InsertElement(Object el) {}
   public Object[] RemoveAll() {}
}

这样您就可以轻松地在此类中放置和检索元素。当然,从编程最佳实践的角度来看,这不是一个很好的解决方案,因为您无法达到可扩展性、灵活性、可维护性和效率。

可以使用迭代器模式来获得功能齐全的集合(可迭代),并且还可以清空元素并在清除之前返回它们:

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() {}
}

但迭代器不是您想要的对象(注意:迭代器是一种模式,但在这种情况下不是您想要的)。

可以考虑基于事件的方法。您会看到,使用回调模式可以让您定义一个事件,该事件在触发时会导致您的集合被释放并返回所有元素。

public class MyCLass {
   ...
   ... event ...
   ...
   MyCLass() {}
   ...
   public Object[] RemoveAll() {}
}

定义一个指向函数的指针(在 c# 中为委托)并在其上定义一个事件,当您的应用程序需要释放集合时,会引发事件,并在事件触发时自动调用正确的释放函数。

好吧,对于你的情况,我会说得很简单。请更改方法,因为在类中使用静态元素是不正确的。静态元素是能够在所有类中持久存在的元素,并保证所有实例化的类将相同的值视为一种共享内存或更好的类状态!在你的情况下,只需保留一个元素集合并在一个简单的类中处理它,正如我在这里向你展示的那样:

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;
   }
}

正如你所看到的,没有使用特殊模式,因为我认为这样做会太过分......我向你报告了一些例子可能的模式,因为我不确定您是否想要一个强大的应用程序,或者只是一个解决您的问题的解决方案,而不考虑可扩展性、灵活性等。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文