2010-12-10 2 views
2

Есть ли лучший способ ограничить доступ к свойствам Занятости и Работодателя?Условные ограничения доступа к объекту

Этот класс предназначен для сбора информации о занятости человека (потенциального клиента). EmploymentStatus может быть занятым, самозанятым, безработным, пенсионером и т. Д.

Я хочу, чтобы пользователи этого класса могли устанавливать Работодатель и Занятость, если человек действительно занят.

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; 
    } 
} 
+0

Почему «Род занятий» и «Работодатель» просто не возвращают «нуль»? И почему вы проверяете «IsEmployed» при настройке одного из свойств? Разве это не остановит безработного от когда-либо нанятого? – batwad 2010-12-10 15:05:02

ответ

1

Во-первых, почему можно построить объект EmploymentInformation, если нет Employer?

Насколько это возможно, вы не должны позволять создавать объект в недопустимом состоянии. Вы можете выразить эти ограничения в конструкторе вашего объекта либо с помощью Guard Clauses, либо Code Contracts.

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

Во-вторых, вы можете использовать Null Object шаблон, так что вы не должны бросать исключения. Просто создайте соответствующий класс для 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. 


    } 
+0

В перечислении EmploymentStatus также содержатся значения для Unemployed, Student, Retired и т. Д. ... Я собираюсь изучить применение Code Contracts, хотя, спасибо! – Danny 2010-12-10 15:01:17

0

У меня не было опыта в этом, но где-то я бы подумал, что поиск находится в Code Contracts.

Посмотрите на эти ссылки:

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

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

Вы можете украсить свои свойства с "требованиями" подходящими для вашего приложения. Выглядит здорово, и, похоже, он частично интегрирован в среду IDE.

2

Что-нибудь случилось с просто возвращение null, если значение не установлено? Это довольно распространенная практика. Если Employer не существует, это значение равно null. Почему это null может не иметь значения. Кроме того, необходимо установить статус занятости в пределах самого класса самого класса.

+0

Я бы сказал, что он должен вернуть компанию типа Unemployed. Если вам действительно нужно знать, действительно ли Employee действительно безработный, просто проверьте тип Unemployed. – 2010-12-10 15:01:30

+2

@macke Если он не работает в компании, у него нет компании; обертывание объяснения в «специальном» объекте компании - это то, что я предпочитаю избегать. – 2010-12-10 15:03:58

+0

Я не знаю, я бы сказал, что все компании являются «особыми», а безработный сотрудник находится в компании других безработных. Принимая это событие дальше, я предлагаю, чтобы Лицо перестало быть сотрудником, если он был безработным. Хотя я обычно больше предпочитаю нулевые/пустые объекты вместо использования специального типа null, всякий раз, когда я сталкиваюсь с такой ситуацией, я начинаю думать, что, возможно, модель неправильна, а не язык ограничен, но я не могу сказать наверняка, потому что я не знаю, что хорошо. – 2010-12-10 22:05:28

0

Это выглядит неправильно с логической точки зрения.

Объект называется «EmploymentInformation» и имеет свойство, называемое «EmploymentStatus»

Это, кажется, либо разрешить для ситуаций, когда employmentinformation занимается активными или term'd сотрудниками; или, чтобы учесть историю занятости.

Если кто-либо из них правдивый, то мне кажется, что вы можете иметь занятия, но по какой-то причине у вас есть EmploymentStatus с чем-то вроде «NotEmployed».

В конце концов, давайте посмотрим, что запись изначально создана там, где используется EmploymentStatus. Затем позже статус будет изменен на «NotEmployed». В следующий раз, когда вы загружаете объект, вы потеряете данные.

2

Принуждение разработчиков к настройке свойств в определенном порядке является опасным дизайном: это делает интерфейс вводящим в заблуждение и поощряет ошибки.

Вместо рассмотреть вопрос о внесении 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; } 
1

новый ответ:

Учитывая, что объект является строго для хранения данных о пользователях Текущий статус Принятие на работу, это все-таки не так.

Как @Jeff Sternal сказал, что вы не должны принуждать Dev's назначать параметры на основе определенного порядка. Если объект должен быть сериализован/десериализован, вы можете столкнуться с большим количеством ошибок.

Вместо этого вы должны предоставить функцию проверки. Что-то вроде bool IsValid(); Когда этот метод вызывается, выполните проверку бизнес-логики, чтобы гарантировать, что объект находится в приемлемом состоянии. Вы могли бы просто вернуть false, если нет, выставить исключение (просьба не делать этого) или отправить код статуса обратно, почему объект в настоящий момент не действителен.

Как правило, вы бросаете данные в объект ТОГДА вы проверяете объект до настойчивости. Вышесказанное является всего лишь одним из способов сделать это. Другие включают в себя библиотеку Business Logic, которая полностью отделяет логику от классов данных (лично я никогда не понимал, почему вы это сделаете, но многие люди клянутся этим).

0

Если вы были строгими, вы можете утверждать, что у безработного нет занятия или работодателя, поэтому объект лица не должен обладать этими свойствами. Это приводит к чему-то подобному.

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; } 
} 
Смежные вопросы