热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我想要一个单独的设计方案。-Iwantadesignalternativetoasingleton

Irealizethereismuchdiscussionaboutsingletonsandwhythatarebad.Thatisnotwhatthisques

I realize there is much discussion about singletons and why that are bad. That is not what this question is about. I understand the drawbacks to singletons.

我意识到有很多关于单身人士的讨论,为什么这很糟糕。这不是这个问题的实质。我理解单身人士的缺点。

I have a scenario where using a singleton is easy and appears to make sense. However, I want an alternative that will accomplish what I need without a lot of overhead.

我有这样一个场景:使用单例对象很容易,并且看起来很有意义。然而,我想要一个替代方案,它可以在不需要大量开销的情况下完成我所需要的工作。

Our application is designed as a client that typically runs on laptops in the field and communicates with a back end server. We have a status bar at the bottom of the main application. It contains a few text areas that show various statues and information as well as several icons. The icons change their image to indicate their state. Such as a GPS icon that indicates if it is connected or not as well as error state.

我们的应用程序被设计成一个客户端,通常在该领域的笔记本电脑上运行,并与后端服务器通信。在主应用程序的底部有一个状态栏。它包含一些文本区域,显示各种雕像和信息以及一些图标。图标会改变它们的图像来表示它们的状态。例如一个GPS图标,指示它是否连接以及错误状态。

Our main class is called MobileMain. It owns the status bar area and is responsible for creating it. We then have a StatusBarManager class. The StatusBarManager is currently a static class, but could also be a singleton. Here is the start of the class.

我们的主要课程叫MobileMain。它拥有状态栏区域并负责创建它。然后我们有一个StatusBarManager课程。StatusBarManager目前是一个静态类,但也可以是一个单例类。这是课程的开始。

public static class StatusBarManager
{
    static ScreenStatusBar StatusBar;

    /// 
    /// Creates the status bar that it manages and returns it.
    /// 
    public static ScreenStatusBar CreateStatusBar()
    {
        StatusBar = new ScreenStatusBar();
        return StatusBar;
    }

The MobileMain asks the StatusBarManager for a StatusBar. It then uses the StatusBar. No other classes see the StatusBar, just the StatusBarManager.

手机管理员向StatusBarManager要一个StatusBar。然后它使用StatusBar。没有其他类看到StatusBar,只有StatusBarManager。

Updates to the status bar can come from pretty much anywhere in the application. There are around 20 classes that can update the text areas on the status bar and additional classes that update the icon states.

状态栏的更新几乎可以来自应用程序中的任何地方。有大约20个类可以更新状态栏上的文本区域,还有其他类可以更新图标状态。

There will only every be one StatusBar and one StatusBarManager.

只有一个StatusBar和一个StatusBarManager。

Any suggestions for a better implemention?

有什么建议可以更好的实施吗?

Some thoughts that I had:

我有一些想法:

Make the StatusBarManager an instance class. In my MobileMain class hold onto a static public instance of the StatusBarManager class. Then to do status bar updates you would call MobileMain.StatusBarManager.SetInformationText or some other method of the manager. The StatusBarManager would not be a singleton, but the MobileMain would only be creating a static instance of it. The issue here is that MobileMain now has a StatusBar and a StatusBarManager, which just manages the StatusBar it owns. Still also have a globally avaialble static instance to the StatusBarManager, just a different owner.

使StatusBarManager成为一个实例类。在我的MobileMain类中,保持StatusBarManager类的静态公共实例。然后进行状态栏更新,您可以调用MobileMain.StatusBarManager。SetInformationText或管理器的其他方法。StatusBarManager不是单例的,但是MobileMain只会创建它的静态实例。这里的问题是,MobileMain现在有一个StatusBar和StatusBarManager,它只管理它拥有的StatusBar。对于StatusBarManager仍然有一个全局通用的静态实例,只是不同的所有者。

Another idea was to use something like an EventEggregator class. I've never used one, but have read about them. I guess the concept is that it would be a globally available class. In each class that wants to update the status bar it would publish a StatusBarUpdate event. The StatusBarManager would be the only classes subscribing to the StatusBarUpdate event, and receive all of the notifications. I've read though that can end up with leaks with this approach if you are not carefull with unsubscribing from events when cleaning up objects. Is this approach worth looking into?

另一个想法是使用类似于EventEggregator类的东西。我从未用过,但读过有关它们的书。我想这个概念是它是一个全局可用的类。在每个想要更新状态栏的类中,都会发布一个StatusBarUpdate事件。StatusBarManager将是订阅StatusBarUpdate事件的惟一类,并接收所有通知。我读到过,如果您在清理对象时没有从事件中取消订阅,那么这种方法可能会导致泄漏。这种方法值得研究吗?

5 个解决方案

#1


2  

Having a StatusBar class or a StatusBarManager class or not is not a big deal. But having many classes in your app know about StatusBars and StatusBarManagers is a bad idea, it will cause strong coupling, and some day probably pain.

是否有StatusBar类或StatusBarManager类并不是什么大问题。但是在你的应用程序中有很多类知道statusbar和StatusBarManagers是一个坏主意,它会导致强耦合,并且有一天可能会很痛苦。

How?

如何?

Imagine that the components that currently report status to a status bar have to be reused in another app that - uses a text console to report status? - reports status to multiple places? or - doesn't report status at all!

假设当前向状态栏报告状态的组件必须在另一个使用文本控制台报告状态的应用程序中重用?-向多个地方报告状态?或者根本不报告状态!

Best alternative: -Event listening. Expose a Status Changed event on your class (you can use a callback), or perhaps on an existing shared resource that your classes have in common. Other parties, like your status bar, can subscribe to the event. And should unsubscribe whenever the subscription is no longer needed/valid, to prevent leaks, as you mention!

最好的选择:事件监听。在类中公开一个状态更改事件(可以使用回调),或者可能是在您的类共有的现有共享资源上。其他的团体,比如你的状态栏,可以订阅这个活动。并且当订阅不再需要/有效时应该取消订阅,以防止泄漏,正如您所提到的!

-Since you've tagged WPF, for WPF, having a dependency property 'StatusText', might seem like another tempting option, with this approach when you have multiple status properties, you need a way of figuring out which one is telling you the most interesting status that needs to be displayed on your status bar now! Which could be a binding, multibinding (blech, complexity), or dependency property changed event handler.

因为你标记WPF为WPF,依赖房地产“StatusText”,似乎是另一个诱人的选择,使用这种方法,当你有多个状态属性,您需要一种方法找出哪一个是告诉你最有趣的地位在你现在的状态栏需要显示的!可以是绑定、多绑定(blech、复杂性)或依赖属性更改的事件处理程序。

However - I would advise you to keep DependencyObjects and DependencyProperties limited to your UI layer as much as possible. The reason is that they rely implicitly on a Dispatcher on the UI thread, and so can't be adapted easily for non-UI chores.

但是——我建议您尽可能将DependencyObjects和DependencyProperties限制在UI层中。原因是它们隐式地依赖于UI线程上的分派器,因此不能轻松地适应非UI事务。

Since there are many different parts of your app you may also possibly find it's reasonable to have a combination of both of these, using some one place and some another.

由于你的应用有很多不同的部分,你可能也会发现把这两个部分结合在一起是合理的,使用不同的地方。

#2


3  

I prefere Static classes that hold your objects. So the amount of objects you can access is restircted by the interface your static class offers. Static is not bad as long as your application still scales.

我喜欢包含对象的静态类。因此,可以访问的对象数量由静态类提供的接口重新激发。只要您的应用程序还在扩展,静态也不是坏事。

Another good alternative to singletons is the Monostate pattern, where you have a class that implements private static fields to represent "singleton" behavior.

单例的另一种很好的替代方法是单状态模式,其中有一个实现私有静态字段来表示“单例”行为的类。

See:
Monostate
Monostate vs. Singleton

参见:单态单态和单态

UPDATE: It often helps me to keep a REST like api in mind, even for internal program structures. Having one class that is updated from everywhere and sends notices to everybody is hard to control in respect to raise conditions and infinity loops (Update -> Event -> Update -> ...)

更新:它经常帮助我记住api,即使是内部程序结构。对于提高条件和无限循环(Update -> Event -> Update ->…)来说,拥有一个从各处更新并向每个人发送通知的类是很难控制的。

Build an (static or not) Status bar interface that you can access where you need it. Through a Static class where you get access to your Status bar interface or by dependency injection if you use such techniques (not recommended for smaller projects). Every call to your status bar interface has to be independent from any events that might be raised by the Status bar to avoid further issues with raise conditions. Think of the status bar interface like a website that can be called from other parts of the program to push and pull information.

构建一个状态栏接口,您可以在需要时访问它。通过静态类,您可以访问状态栏接口或依赖注入,如果您使用这些技术(不推荐用于较小的项目)。对状态栏接口的每次调用都必须独立于状态栏可能引发的任何事件,以避免引发条件的进一步问题。想象一下状态栏界面,就像一个网站,可以从程序的其他部分调用,以推动和拉动信息。

#3


1  

You could simply use the Observer pattern and add the StatusBar as a listener to your 20 objects. This will eliminate the singletons and better follow SRP and DIP, but you will have to consider whether it is worth the effort. A singleton may be better if the indirection adds too much complexity and dependency injection is not possible.

您可以简单地使用Observer模式,并将StatusBar添加为您的20个对象的侦听器。这将消除单例,并更好地遵循SRP和DIP,但是您必须考虑这样做是否值得。如果单向添加过多的复杂性和依赖注入是不可能的,那么单例可能会更好。

public class StatusBar implements StatusListener {
}

public interface StatusListener {
   public statusChanged(String newStatus)
}

#4


0  

Classes will depend implicitly on any use singleton and explicitly to any parameters in the constructor. I would suggest adding an interface to the singleton, so just the methods needed would be exposed to the classes using the IStatusBar. This is more code, but will ease unit testing.

类将隐式地依赖于任何单例使用,并显式地依赖于构造函数中的任何参数。我建议向singleton添加一个接口,这样只需使用IStatusBar将所需的方法公开给类。这是更多的代码,但是可以简化单元测试。

#5


-1  

It's hard to give advice without knowing more of your application's architecture, but perhaps you should consider dependency injection. For example, pass a StatusBar instance to the constructor of each class that directly uses it.

如果不了解应用程序的架构,就很难给出建议,但也许您应该考虑依赖项注入。例如,将StatusBar实例传递给直接使用它的每个类的构造函数。


推荐阅读
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 当使用 `new` 表达式(即通过 `new` 动态创建对象)时,会发生两件事:首先,内存被分配用于存储新对象;其次,该对象的构造函数被调用以初始化对象。为了确保资源管理的一致性和避免内存泄漏,建议在使用 `new` 和 `delete` 时保持形式一致。例如,如果使用 `new[]` 分配数组,则应使用 `delete[]` 来释放内存;同样,如果使用 `new` 分配单个对象,则应使用 `delete` 来释放内存。这种一致性有助于防止常见的编程错误,提高代码的健壮性和可维护性。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • Unity与MySQL连接过程中出现的新挑战及解决方案探析 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
  • 使用 `git stash` 可以将当前未提交的修改保存到一个临时存储区,以便在后续恢复工作目录时使用。例如,在处理中间状态时,可以通过 `git stash` 命令将当前的所有未提交更改推送到一个新的储藏中,从而保持工作目录的整洁。此外,本文还将详细介绍如何解决 `git stash pop` 时可能出现的冲突问题,帮助用户高效地管理代码变更。 ... [详细]
author-avatar
米米丫头2502860283
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有