在具体情况下制定方法来做区别

本文关键字:方法 区别 情况下 | 更新日期: 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角色。

我非常推荐你看这个视频,它讲的是如何将关注点划分为块而不是层