- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要一个类来标识要执行的网络连接类型。
网络加入可以是 Domain
加入 Workgroup
加入。
在加入Workgroup
的情况下,我只需要知道要加入的工作组的Name
。
在 Domain
加入的情况下,我需要知道要加入的域的 Name
以及 Username
和 要使用的密码
(让我们忽略这里所有关于安全的顾虑,这是一个场景)。
然后我想为它创建一个类似于此的 WPF UI:
http://documents.weber.edu/ctctools/sccm/images/osdnotes/9.png
如果用户选择 Workgroup
加入,GUI 的凭据部分将被禁用,而当他们选择 Domain
加入时,GUI 的凭据部分将被禁用(关于名称也是如此要加入的实际工作组/域)。
而且我希望能够序列化/反序列化这些数据(再次忽略安全问题,这是一个场景)。
在我看来,我有两个选择:
选项 1
创建类似于以下的解决方案:
enum JoinType
{
Domain,
Workgroup
}
class NetworkJoin
{
JoinType JoinType {get; set;}
string Name {get;set;}
string Username {get;set;}
SecureString Password {get;set;}
void Join()
{
// Join code for domain + workgroup
}
}
这将使我能够轻松地执行 TextBoxUsername.IsEnabled = ViewModel.NetworkJoin.JoinType == JoinType.Domain
。
但是,因为类实例是序列化/反序列化的,所以它允许此类的实例具有 JoinType = JoinType.Workgroup
以及具有 Username
/Password
并且这是一个假设(尽管是合乎逻辑的)网络加入是基于对 JoinType
的检查(而不是说,if (Username == null) {//工作组加入 }
)
这让我想到了选项 2
选项 2
类似于:
interface INetworkJoin
{
string Name {get;set;}
void Join();
}
class DomainJoin : INetworkJoin
{
string Name {get;set;}
string Username {get;set;}
SecureString {get;set;}
void Join()
{
// Domain join code
}
}
class WorkgroupJoin : INetworkJoin
{
string Name {get;set;}
void Join()
{
// Workgroup join code
}
}
现在您不可能创建具有错误属性的对象或任何关于将执行哪种类型的连接的假设,因为我们传递的参数不明确。
事实上,通常这会是一个更好的解决方案。除了将它绑定(bind)到 UI。
我的 ViewModel 基本上会有一个 INetworkJoin NetworkJoin,这意味着我的 View 只会看到一个 INetworkJoin。它需要知道它的具体类型以确定是否显示/不显示凭据对象,它需要将用户名文本框绑定(bind)到用户名属性(INetworkJoin 没有...) , 密码等也一样
总结
如果感觉这两种解决方案都不合适。第一个提供不明确的连接,第二个需要找出接口(interface)的具体类型,以及访问仅在具体类型中可用的属性。
我想一定有比这两个更好的解决方案,但这真的是我能想到的。
如有任何帮助,我们将不胜感激。
最佳答案
您应该有单独的域模型和 View 模型。 View 模型通常还实现 INotifyPropertyChanged
并具有其他属性,例如启用/禁用按钮等。
领域模型:
abstract class NetworkJoin
{
public string Name { get; set; }
}
class WorkgroupJoin : NetworkJoin
{
}
class DomainJoin : NetworkJoin
{
public string Username { get; set; }
public SecureString Password { get; set; }
}
查看模型(为了简单起见,我没有显示 INotifyPropertyChanged
实现。对 Name
、Username
和 Password< 的更改
必须触发 OnPropertyChanged(nameof(IsOkButtonEnabled))
:
class NetworkJoinViewModel
{
private const int MinPasswordLength = 8;
public JoinType JoinType { get; set; }
public string Name { get; set; }
public string Username { get; set; }
public SecureString Password { get; set; }
public bool IsOkButtonEnabled
{
get {
switch (JoinType) {
case JoinType.Domain:
return
!String.IsNullOrEmpty(Name) &&
!String.IsNullOrEmpty(Username) &&
Password != null && Password.Length >= MinPasswordLength;
case JoinType.Workgroup:
return !String.IsNullOrEmpty(Name);
default:
return false;
}
}
}
public bool IsLoginEnabled => JoinType == JoinType.Domain; // For password an username textboxes.
public void Join()
{
switch (JoinType) { /* ... */ }
}
public NetworkJoin ToDomainModel() {
switch (JoinType) {
case JoinType.Domain:
return new DomainJoin {
Name = Name,
Username = Username,
Password = Password
};
case JoinType.Workgroup:
return new WorkgroupJoin {
Name = Name
};
default:
return null;
}
}
}
最后是 View 模型工厂(因为我不想向域模型添加 ToViewModel
方法。域模型不应该知道 View 模型的详细信息):
static class NetworkJoinViewModelFactory
{
public static NetworkJoinViewModel Create(NetworkJoin networkJoin)
{
switch (networkJoin) {
case WorkgroupJoin workgroupJoin:
return new NetworkJoinViewModel {
JoinType = JoinType.Workgroup,
Name = workgroupJoin.Name
};
case DomainJoin domainJoin:
return new NetworkJoinViewModel {
JoinType = JoinType.Domain,
Name = domainJoin.Name,
Username = domainJoin.Username,
Password = domainJoin.Password
};
default:
return null;
}
}
}
关于c# - 类设计悖论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53523359/
我有一些第三方类(class)。其精简版(为了简洁起见)功能如下: 提供两个类 ClassA 和 ClassB 供外部使用。这些类中的每一个类都与其他类完全无关(这意味着它们没有共同的祖先)。 有一个
我正在尝试在用户单击时为一个 div 设置动画,以便当前“主”div 移出视野,另一个 div 移入窗口,以便用户可以看到有关该事物的更多详细信息他们点击了。 我面临的问题是,我实现的用于将用户带回主
我有 3 个名为Discipline、DisciplineMembership、DisciplineManagement 的实体: 一个学科有多个学科成员 一个学科有多个学科管理 Discipline
在 Ruby 中,我们有 'bang' 方法 capitalize! 如果没有对字符串进行任何更改,它会返回一个 nil 的奇怪行为。 这意味着我无法将此命令与其他命令链接在一起,因为如果它返回 ni
人们已经无数次证明,yield return 比 list 慢。 示例:Is 'yield return' slower than "old school" return? 然而,当我尝试使用基准测试
列表基准:大小=1000,运行=50000,总时间=19.5 秒 var list = new List(Size); for (int i = 0; i { c = 0; for (i
我需要对 Paradox 数据库执行查询。有一个表,其中包含带有西里尔文字的数据,我正在尝试在这样的查询中使用西里尔文字参数: select * from AccessZone zn where zn
我是一名优秀的程序员,十分优秀!