在具体情况下制定方法来做区别
本文关键字:方法 区别 情况下 | 更新日期: 2023-09-27 18:19:09
在命名空间com.example.website.domain.model
中,我有Project
类,参见代码:
public class Project
{
private string Name;
private int Status = 0;
... And much more attributes ....
public Project(string name) {
Name = name;
}
public void Publish()
{
Status = 1;
}
public bool IsPublished()
{
return Status == 1;
}
public void ChangeName(string newName)
{
if (IsPublished()) throw new InvalidOperationException("Not allow to change name after published");
Name = newName;
}
public string GetName()
{
return Name;
}
... And much more method ...
}
通常情况下,如果项目尚未发布,用户可以更改项目名称。
我必须创建能够更改名称甚至项目已发布的管理页面。我考虑在Project
中加入新的方法,即public void AdminChangeName(string name)
。但我认为Project
不应该在管理部分(命名空间)之外暴露这种方法。我想调用相同的方法与相同的签名没有验证。
定义动态多态性的唯一方法(这是您所需要的)是创建某种组合。也就是说,你必须在一些新的类中提取检查逻辑。
让我们看一些例子。
1。
//in domain namespace
public interface INameChangeStrategy {
public void ChangeName(Project project, string name);
}
//in general use namespace
public class DefaultNameChangeStrategy : INameChangeStrategy {
public void ChangeName(Project project, string name) {
if (project.IsPublished()) throw new InvalidOperationException("Not allow to change name after published");
project.setName(name);
}
}
//in admin use namespace
public class AdminNameChangeStrategy : INameChangeStrategy {
public void ChangeName(Project project, string name) {
project.setName(name);
}
}
如您所见,这个问题违反了封装。项目本身'信任'策略,并打开其name属性以直接更改(method . setname(…))。此外,您必须根据使用上下文正确配置策略-是否管理。
2。
另一个相同的解决方案-在Project类中添加策略:
具有类似
的接口public interface INameChangeCheckStrategy {
public CanChangeName(Project project, string name);
}
//in general use namespace
public class DefaultNameChangeCheckStrategy : INameChangeCheckStrategy {
public void ChangeName(Project project, string name) {
if (project.IsPublished()) throw new InvalidOperationException("Not allow to change name after published");
//other check logic, i.e. regex match
}
}
public class Project
{
private INameChangeCheckStrategy _nameChangeAbilityStrategy;
...
public void ChangeName(string newName)
{
_nameChangeAbilityStrategy.CanChangeName(this, newName);
name = newName;
}
}
在这种情况下,封装保持在更高的级别。
最重要的是策略实现在运行时必须是每个请求实例,因此项目实例必须根据请求正确初始化。
只有admin角色可以在发布后更改名称?如果答案是肯定的,下面是我的答案:
您正在混合关注,权限或角色验证属于应用程序关注而不属于您的域(在本例中是Project
类)。
因此,您不应该为相同的操作使用不同的方法,相反,在更改名称之前,您应该验证项目是否已发布并且用户具有admin角色。
我非常推荐你看这个视频,它讲的是如何将关注点划分为块而不是层