我正在构建一个WPF MVVM应用程序,它代表一个任务管理器->添加任务并跟踪它们是否完成。
我有一个抽象类TaskBase
和两个示例任务-> ToDoTask
和Reminder
,它们都继承自TaskBase
,但有一些更多的属性。
我已经实现了一个ITaskRepository
,它保留了所有的任务,并具有获取,添加,编辑和删除任务等功能。
该应用程序的主要思想是显示任务,并有可能添加一个任务。每当用户单击Add按钮时,就会出现一个新窗口,其中包含一个ComboBox
,它绑定到一个枚举TaskType
(当前有2个值- Reminder和ToDoTask),一个ContentControl
,它绑定到一个TaskBase
类型的属性,其数据应该被填充,以及一个IRelayCommand
,它将任务添加到存储库。
目视检查:x1c 0d1x
public class AddTaskViewModel : ObservableObject
{
private TaskType selectedTaskType;
private TaskBase task;
public TaskType SelectedTaskType
{
get => selectedTaskType;
set
{
SetProperty(ref selectedTaskType, value);
switch (selectedTaskType)
{
case TaskType.ToDoTask:
Task = new ToDoTask();
break;
case TaskType.Reminder:
Task = new Reminder();
break;
}
}
}
public TaskBase Task
{
get => task;
set => SetProperty(ref task, value);
}
public IRelayCommand AddTaskCommand { get; set; }
}
AddTaskViewModel
是MainViewModel
内部的属性,AddTaskCommand
实际上是在那里设置的。
在AddTaskView.xaml
中,ContentControl
的DataContext
设置为Task
,其样式具有触发器,因此每当用户更改所选任务类型时,ContentControl
的内容就会相应更改。
一切都工作得很好,做了它应该做的事情,但我关心的是这部分代码:
public TaskType SelectedTaskType
{
get => selectedTaskType;
set
{
SetProperty(ref selectedTaskType, value);
switch (selectedTaskType)
{
case TaskType.ToDoTask:
Task = new ToDoTask();
break;
case TaskType.Reminder:
Task = new Reminder();
break;
}
}
}
我想让所有东西都尽可能地可扩展,但是如果我添加另一个类,从TaskBase
继承,并希望更快地使所有东西适应它,我还必须修改这个开关的情况(打破开放/封闭原则)。
在构建应用程序架构时,是否有更好的方法?
1条答案
按热度按时间up9lanfz1#
问题是您是基于参数创建示例的。这总是需要一种参数检查。
此模式引入了两个问题:1) 对具体类型和实现细节(如构造函数参数)的显式依赖;2) 参数类型
switch
。这两种方法都损害了可扩展性。问题 1) 通过将示例化代码移出依赖于这些新示例的类型来解决。
通常使用 Factory Method 模式或 Abstract Factory 模式。这意味着示例化被移动到类型本身或工厂。
这并不能解决问题 2):现在负责动态示例化的另一类型仍然必须检查其参数,以便决定示例化哪个类型。
问题 2) 通过引入一种哈希表来解决。
例如,将这两种解决方案组合成
TaskFactory
可以如下所示:您可以直接使用这个类,也可以将它隐藏在现有的
ITaskRepository
后面。因为已经有了一个专门的仓库类,我将扩展它的API以允许创建TaskBase
示例:ITaskRepository.cs
任务库.cs
使用示例
AddTaskViewModel.cs
App.xaml.cs