有条件地限制财产访问

发布于 2024-10-06 21:28:07 字数 2124 浏览 2 评论 0原文

是否有更好的方法来限制对职业和雇主属性的访问?

这个类只是为了收集一个人(潜在客户)的就业信息而设计的。就业状态可以是受雇、自雇、失业、退休等...

我只希望此类用户能够在该人确实受雇的情况下设置雇主和职业。

public class EmploymentInformation
{
    private const string _EmploymentStatusNotEmployedMessage = "Employment status is not set to employed";

    private string _occupation;

    private Company _employer;

    /// <summary>The person's employment status<example>Employed</example></summary>
    public EmploymentStatus EmploymentStatus { get; set; }

    /// <summary>The person's occupation<example>Web Developer</example></summary>
    public string Occupation
    {
        get
        {
            if (IsEmployed)
            {
                return _occupation;
            }
            throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
        }

        set
        {
            if (IsEmployed)
            {
                _occupation = value;
            }
            throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
        }
    }

    /// <summary>The person's employer</summary>
    public Company Employer
    {
        get
        {
            if (IsEmployed)
            {
                return _employer;
            }
            throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
        }

        set
        {
            if (IsEmployed)
            {
                _employer = value;
            }
            throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
        }
    }

    private bool IsEmployed
    {
        get
        {
            return EmploymentStatus == EmploymentStatus.Employed 
                || EmploymentStatus == EmploymentStatus.SelfEmployed;
        }
    }

    /// <summary>
    /// Constructor for EmploymentInformation
    /// </summary>
    /// <param name="employmentStatus">The person's employment status</param>
    public EmploymentInformation(EmploymentStatus employmentStatus)
    {
        EmploymentStatus = employmentStatus;
    }
}

Is there a better way to limit access to the Occupation and Employer properties?

This class is simply designed to collect a person's (potential customer's) employment information. EmploymentStatus can be Employed, SelfEmployed, Unemployed, Retired, etc...

I only want users of this class to be able to set Employer and Occupation if the person is indeed employed.

public class EmploymentInformation
{
    private const string _EmploymentStatusNotEmployedMessage = "Employment status is not set to employed";

    private string _occupation;

    private Company _employer;

    /// <summary>The person's employment status<example>Employed</example></summary>
    public EmploymentStatus EmploymentStatus { get; set; }

    /// <summary>The person's occupation<example>Web Developer</example></summary>
    public string Occupation
    {
        get
        {
            if (IsEmployed)
            {
                return _occupation;
            }
            throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
        }

        set
        {
            if (IsEmployed)
            {
                _occupation = value;
            }
            throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
        }
    }

    /// <summary>The person's employer</summary>
    public Company Employer
    {
        get
        {
            if (IsEmployed)
            {
                return _employer;
            }
            throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
        }

        set
        {
            if (IsEmployed)
            {
                _employer = value;
            }
            throw new ApplicationException(_EmploymentStatusNotEmployedMessage);
        }
    }

    private bool IsEmployed
    {
        get
        {
            return EmploymentStatus == EmploymentStatus.Employed 
                || EmploymentStatus == EmploymentStatus.SelfEmployed;
        }
    }

    /// <summary>
    /// Constructor for EmploymentInformation
    /// </summary>
    /// <param name="employmentStatus">The person's employment status</param>
    public EmploymentInformation(EmploymentStatus employmentStatus)
    {
        EmploymentStatus = employmentStatus;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

网白 2024-10-13 21:28:07

如果未设置值,则简单地返回 null 是否有问题?这是相当常见的做法。如果Employer不存在,则其值为空。为什么它是 null 可能不相关。此外,还强制在班级本身的角色中设置就业状态。

Anything wrong with simply returning null if the value is not set? That's fairly common practice. If Employer does not exist it's value is null. Why it's null may not be relevant. In addition force the employment status to be set within the ctor of the class itself.

挽手叙旧 2024-10-13 21:28:07

强迫开发人员按特定顺序设置属性是一种危险的设计:它会使界面产生误导并鼓励错误。

相反,请考虑使 EmploymentInformation 对象不可变:

// Constructor for retired / unemployed people
public class EmploymentInformation(EmploymentStatus status) {}

// Constructor for self-employed people - we know their status
public class EmploymentInformation(string occupation) {}

// Constructor for people employed by others - we know their status
public class EmploymentInformation(string occupation, Company employer) {}

public bool IsEmployed { get; }
public string Occupation { get; }
public Company Employer { get; }

Forcing developers to set properties in a particular order is a dangerous design: it makes the interface misleading and encourages mistakes.

Instead, consider making EmploymentInformation objects immutable:

// Constructor for retired / unemployed people
public class EmploymentInformation(EmploymentStatus status) {}

// Constructor for self-employed people - we know their status
public class EmploymentInformation(string occupation) {}

// Constructor for people employed by others - we know their status
public class EmploymentInformation(string occupation, Company employer) {}

public bool IsEmployed { get; }
public string Occupation { get; }
public Company Employer { get; }
我也只是我 2024-10-13 21:28:07

首先,如果没有Employer,为什么可以构造一个EmploymentInformation对象呢?

尽可能不要允许在无效状态下构造对象。您可以在对象的构造函数中使用 Guard Clauses代码合同

public class EmploymentInformation
{
    public EmoloymentInformation(Employer employerInstance)
    {
        if(employerInstance == null)
            throw new ArgumentNullException();
    }

其次,您可以使用 空对象 模式,这样您就不必抛出异常。只需为 EmptyEmployer 创建适当的类并返回它们,如下所示。

        public Company Employer
            {
                get
                {
                    return IsEmployed ? _employer : Employer.Empty; 
// Employer.Empty is static property which return an instance of EmptyEmployer just like string.Empty.


    }

Firstly, why is it possible to construct an object of EmploymentInformation if there is no Employer?

As far as possible, you should not allow an object to be constructed in an invalid state. You can express these constraints in the constructor of your object either using Guard Clauses or Code Contracts.

public class EmploymentInformation
{
    public EmoloymentInformation(Employer employerInstance)
    {
        if(employerInstance == null)
            throw new ArgumentNullException();
    }

Secondly, you can use the Null Object pattern so that you don't have to throw exceptions. Just create appropriate class for EmptyEmployer and return them as shown below.

        public Company Employer
            {
                get
                {
                    return IsEmployed ? _employer : Employer.Empty; 
// Employer.Empty is static property which return an instance of EmptyEmployer just like string.Empty.


    }
缘字诀 2024-10-13 21:28:07

一个新的答案:

鉴于该对象严格保存有关用户当前就业状态的数据,它仍然是错误的。

正如 @Jeff Sternal 所说,您不应该强迫开发人员根据特定顺序分配参数。如果对象需要序列化/反序列化,您可能会遇到很多错误。

相反,您应该提供一个验证函数。类似 bool IsValid(); 当调用该方法时,执行业务逻辑验证以确保对象处于可接受的状态。如果不是,您可以让它简单地返回 false,抛出异常(请不要),或者让它发送一个状态代码来说明为什么该对象当前无效。

通常,您将数据放入对象中,然后在持久化之前验证该对象是否良好。以上只是执行此操作的一种方法。其他包括拥有一个业务逻辑库,它将逻辑与数据类完全分离(就我个人而言,我从来不明白为什么要这样做,但很多人都相信它。)。

A new answer:

Given that the object is strictly to hold data regarding the users CURRENT employement status, it's still wrong.

As @Jeff Sternal said you shouldn't force dev's to assign parameters based on a particular order. In the event the object needs to be serialized/deserialized you could end up with a lot of errors.

Instead you should provide a validation function. Something like bool IsValid(); When that method is called perform the business logic validation to ensure that the object is in an acceptable state. You could have it simply return a false if not, throw an exception (please don't), or have it send a status code back as to why the object is not currently valid.

Typically you throw data into an object THEN you validate the object is good prior to persistence. The above is just one way of doing this. Others include having a Business Logic library which separates the logic completely from the data classes (personally, I never understood why you'd do this, but a lot of people swear by it.).

舟遥客 2024-10-13 21:28:07

我在这方面没有任何经验,但我会考虑在代码合同中寻找。

查看这些链接:

http: //social.msdn.microsoft.com/Forums/en/codecontracts/thread/1ca2d371-4b85-479d-9e00-64c84e372f02

http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx

您可以使用适合您的应用程序的“要求”来装饰您的属性。使用起来看起来很酷,而且似乎已经一半集成到了 IDE 中。

I've not had any experience in this, but somewhere I would consider looking is in Code Contracts.

Have a look at these links:

http://social.msdn.microsoft.com/Forums/en/codecontracts/thread/1ca2d371-4b85-479d-9e00-64c84e372f02

http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx

You can decorate your properties with "requirements" suitable to your application. Looks cool to use, and it appears to be half integrated into the IDE.

浅忆流年 2024-10-13 21:28:07

从逻辑角度来看,这看起来是错误的。

该对象称为“EmploymentInformation”,并具有一个名为“EmploymentStatus”的属性。

这似乎允许就业信息涉及在职或任期雇员的情况;或者或者,考虑到工作经历。

如果其中任何一个为真,那么在我看来,您可以有一个职业,但无论出于何种原因,都有“未就业”之类的就业状态。

毕竟,让我们看看记录最初是在就业状态受雇的地方创建的。然后状态会更改为“NotEmployed”,下次加载对象时您将丢失数据。

This looks wrong from a logic perspective.

The object is called "EmploymentInformation" and has a property called "EmploymentStatus"

This seems to either allow for situations where the employmentinformation deals with active or term'd employees; or, to allow for employment history.

If either of those are true, then it seems to me that you can have an Occupation but have an EmploymentStatus of something like "NotEmployed" for whatever reason.

After all, let's see the record is initially created where the EmploymentStatus is employed. Then later the status is changed to "NotEmployed" The next time you go to load the object you are going to lose data.

瞄了个咪的 2024-10-13 21:28:07

如果您严格的话,您可能会认为失业者没有职业或雇主,因此个人对象不应该拥有这些属性。这会导致这样的事情。

class Person
{
    public EmploymentStatus EmploymentStatus { get; set; }
}

class EmployedPerson : Person
{
    public string Occupation { get; set; }
    public Company Employer { get; set; }
}

然而,在实践中,这种严酷的对象模型使用起来会很麻烦,因为在实例化对象之前,您需要知道某人是否受雇。在就业和失业之间进行切换也很困难,因为您必须创建一个新对象并复制所有内容。

临床上的区别并不值得。我认为,询问失业者的雇主是谁并让他们回答“我没有”比一开始就无法提出问题同样正确,而且事实上更合乎逻辑。

对我来说,这将是一个更灵活的人员类别。

class Person
{
    public Person()
    {
        this.EmploymentStatus = EmploymentStatus.Unemployed;
    }

    public void Hire(Company employer, string occupation)
    {
        this.Occupation = occupation;
        this.Employer = employer;
        this.EmploymentStatus = EmploymentStatus.Employed;
    }

    public void Fire()
    {
        this.Occupation = null;
        this.Employer = null;
        this.EmploymentStatus = EmploymentStatus.Unemployed;
    }

    public EmploymentStatus EmploymentStatus { get; private set; }
    public string Occupation { get; private set; }
    public Company Employer { get; private set; }
}

If you were being strict you might argue that an unemployed person does not have an occupation or employer, so a person object should not have these properties. That leads to something like this.

class Person
{
    public EmploymentStatus EmploymentStatus { get; set; }
}

class EmployedPerson : Person
{
    public string Occupation { get; set; }
    public Company Employer { get; set; }
}

However in practice this unforgiving object model will be cumbersome to work with as you will need to know whether or not a person is employed before you can instantiate an object. It will also be difficult to change between being employed and unemployed as you will have to create a new object and copy everything across.

The clinical distinction isn't worth it. I think it's just as correct and in fact more logical to ask an unemployed person who their employer is and for them to reply with "I haven't got one" rather than be unable to ask the question in the first place.

For me, this would be a more flexible person class.

class Person
{
    public Person()
    {
        this.EmploymentStatus = EmploymentStatus.Unemployed;
    }

    public void Hire(Company employer, string occupation)
    {
        this.Occupation = occupation;
        this.Employer = employer;
        this.EmploymentStatus = EmploymentStatus.Employed;
    }

    public void Fire()
    {
        this.Occupation = null;
        this.Employer = null;
        this.EmploymentStatus = EmploymentStatus.Unemployed;
    }

    public EmploymentStatus EmploymentStatus { get; private set; }
    public string Occupation { get; private set; }
    public Company Employer { get; private set; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文