背景:我正在编写一个应用程序,其核心思想很简单--我可以通过GUI选择一个'Task‘(包括名称、执行可运行的代码、进度),启动它、停止它、启动所有的'Task’和停止所有的‘Task’。每个‘Task’必须在不同的线程上分派(长时间的操作)。
问题:如前所述,“任务”类具有启动或停止的能力。通常,我会引入一个像'TaskManager‘这样的管理类,以便真正地管理任务(假设在不同的线程上启动它们,并保留句柄以便取消它,或者监视线程数量有限的资源),但是我听说manager类型的类可能很难闻,只是实践很差。
核心问题:我真的需要那种经理课吗?
发布于 2022-04-06 22:40:32
用于管理对象集合的类没有任何问题。例如,数据库连接池是一个有效的"DbConnectionManager",因为它可以提高应用程序的响应性,同时消除开发人员的大量开销。从某种意义上说,List<T>是T类型对象的管理器,其中的对象不需要太多的监督。
然而,由于多种原因,Manager (Anti-)模式通常会得到一个恶名。
首先是命名问题。通常,通过在类名上加上"Manager“这个词的捷径,我们失去了明确描述新类的目的的机会。如果我想跟踪沥青飞机上车辆的库存,我宁愿看到ParkingLot,也不愿看到CarManager。前者更清楚地传达了类的预期用法,并提供了我在下面描述的其他好处。
第二,随着项目的发展,管理者倾向于成倍增长。对于企业和代码库本身来说都是如此。一旦你开始把一切都称为Manager,你就会发现很难停止。不久,您将需要一个ManagerManager来保持所有经理的一致。
通过从一开始就给出描述性的名称,而不是默认的泛型名称,我们大大削弱了经理对我们项目的束缚。命名良好的类并不能完全消除管理类激增的可能性,但它们肯定会有所帮助。
第三,如果我们使用描述性名称,那么坚持单一责任原则就容易多了。Dealer和ParkingLot都负责车辆管理,但我不认为停车场会卖给我任何东西。我们将有更多的类,但每个类在范围和使用上都将受到更大的限制。不幸的是,没有什么能阻止开发人员将所有这些功能和厨房水槽放入CarManager中。出于这个原因,我们应该避免使用那些给设计实践带来不良影响的名字。
说了这么多话,别忘了我说的第一句话:
如果一个类的目的是管理其他类的集合,那么它没有什么问题。
不管你叫它“经理”还是其他什么东西,你可能仍然需要一些东西来跟踪你的任务。您是否需要查询任务的状态并将其显示在UI上、打印到控制台等?然后,您需要一些东西来跟踪可用任务的列表。同样,如果这是对您有效的话,这可以是一个简单的List<Task>。
另一方面,有时我们可以通过没有一个管理器对象来跟踪一个任务集合。相反,我们可以让任务管理自己的状态。这通常是通过事件或方法回调来实现的,并且在异步编程中很有用,而当任务结束时我们不这样做。
例如,在C#中,我可以在第一次创建对象时定义TaskStarted、TaskFailed和订阅这些事件(或者当我引用对象时,但是如果没有某种类型的列表,就很难跟踪这些事件)。示例:
public class Task
{
event EventHandler TaskStarted;
event EventHandler TaskEnded;
}
// And in the wild
public void DoStartTask(object sender, EventArgs e)
{
// Do stuff
}
public void DoEndTask(object sender, EventArgs e)
{
// Remove references to event for garbage collection
((Task)sender).TaskStarted -= DoStartTask;
((Task)sender).TaskEnded -= DoEndTask;
// Do other stuff
}
Task myTask = new Task();
myTask.TaskStarted += DoStartTask;
myTask.TaskEnded += DoEndTask;
// Even if I don't add it to a list, the DoStartTask and DoEndTask will fire at the right time.当对象真正自我管理时,这种类型的类自我管理工作得最好。如果您需要查询任务列表,例如从数据源中检索它们,那么使用单个权限(即管理器)的时间可能比多个单独的自我管理任务更好。
发布于 2022-04-06 22:21:51
*Manager类的问题不在于它们本身是糟糕的实践,而是它们常常变成“上帝类”,这违反了单一的责任原则--因为没有人知道“经理”的界限是什么,所有的东西都会被抛到一起。
另一方面,组织任务的东西听起来像是你的应用程序的一个必要部分,但是试着看看你是否能把它分解得更深入,而不仅仅是一个“经理”。如果没有进一步的细节说明您想要做什么,这是有点棘手的,但是一个可能的拆分是分为两个组件:
https://softwareengineering.stackexchange.com/questions/437873
复制相似问题