我将从影响实施的问题开始:
如果问题 1的答案是“是”并且很难分离两个职责,那么将 UI 逻辑添加到Task可以简单地完成很多事情。
如果问题 2的答案是肯定的,那么使用经典的模型/视图分离将使编写新任务更容易,因为您只需将任务逻辑添加到Task类。
您可以拥有一个TasksHUD类,该类负责处理TaskUI类的列表。每个 TaskUI类都将有一个与之关联的Task并处理此特定任务的 UI 和表示逻辑的呈现。
这样,您的TasksHUD类将管理列表向用户显示的方式,而每个列表条目将由TaskUI类处理。任务演示代码将被重用。
任务将仅负责执行、更改其状态以及任务必须在您的应用程序中执行的其他操作(如果您提供更多详细信息,我可以提供更详细且可能更准确的描述),而呈现任务的责任将给一个TaskUI。
这样,如果您需要更改任务呈现方式的逻辑,则只需更改TaskUI类。
您可以编写任意数量的任务,而无需为这些任务编写与 UI 相关的代码。
如果您需要更改Task类,您可能需要也可能不需要更改TaskUI类,因为依赖关系从TaskUI变为Task。有些更改会影响 UI,有些则不会。
如果问题 3的答案是肯定的,那么:
您可以将处理其 UI 的责任添加到Task。这样,由于它们在同一个班级中,因此更改它们会更容易。这里的一个问题是Task类可以扩展为具有多个职责。还共享类似任务的渲染代码等。
在这种情况下,您可以在两个类Task和TaskUI中将Task与其 UI 分离,但您需要在应用程序中使用一种机制,将特定的Task类与其TaskUI类相关联。这可能会导致更多的类和可能不想管理的复杂性。从长远来看,它可能会节省您的时间(主要是为了避免错误)。
这是一个伪代码示例:
interface TaskObserver {
void onTaskChanged(t);
}
interface TaskUI {
void render();
}
interface TaskUIFactory {
register(TaskUIFactoryRegistry registry);
TaskUI create(Task task);
}
interface Task {
TaskStatus status;
execute();
addEventListener(TaskObserver o);
}
class TaskA : Task {
// implementation.....
}
class TaskA_UI : TaskUI, TaskObserver {
TaskA mTask;
TaskA_UI(TaskA task) {
mTask = task;
mTask.addEventListener(this);
}
render() {
// rendering goes here
}
onTaskChanged(t) {
// raise an event or signal to the TaskHUD that a refresh is needed
}
}
class TaskA_UIFactory : TaskUIFactory {
void register(TaskUIFactoryRegistry registry) {
registry.Register(typeof(TaskA), this);
}
TaskUI createUI(Task task) {
return new TaskA_UI((TaskA)task);
}
}
添加任务后,您的 TasksHUD 可以使用 TaskUIFactoryRegistry 来获取将创建 TaskUI 的 TaskUIFactory。
以下是一些讨论此类问题的资源,您可以查看这些资源: