Я пишу класс для инкапсуляции некоторых бизнес-правил, каждое из которых представлено булевым значением. Класс будет использоваться в обработке формы InfoPath, таким образом, правила получат текущее состояние программы путем поиска значений в глобальной структуре данных XML с помощью операций XPath. Что является лучшим (самый идиоматичный) способ выставить эти правила вызывающим сторонам - свойства или открытые методы?
Назовите свойства использования
Rules rules = new Rules();
if ( rules.ProjectRequiresApproval ) {
// get approval
} else {
// skip approval
}
Назовите методы использования
Rules rules = new Rules();
if ( rules.ProjectRequiresApproval() ) {
// get approval
} else {
// skip approval
}
Представление класса правил управляет как свойства
public class Rules() {
private int _amount;
private int threshold = 100;
public Rules() {
_amount = someExpensiveXpathOperation;
}
// rule property
public bool ProjectRequiresApproval {
get { return _amount > threshold }
}
}
Представление класса правил управляет как методы
public class Rules() {
private int _amount;
private int threshold = 100;
public Rules() {
_amount = someExpensiveXpathOperation;
}
// rule method
public bool ProjectRequiresApproval() {
return _amount > threshold;
}
}
Каковы за и против одного по другому?
Все сводится к передаче семантики тому, кто потребляет эту бизнес-логику.
Свойство - это неотъемлемая ценность конкретного объекта. Rules
в вашем примере - это механизм бизнес-логики, поэтому любые свойства, которые он раскрывает, должны относиться к состоянию и поведению этого механизма, а не к данным, которые он обработал. Таким образом, ProjectRequiresApproval()
- это действие, которое механизм применяет к внешней сущности.
С другой стороны, если бы существовал метод Rules.GetProcess()
, который возвращал бы объект Process
, RequiresAproval
мог бы быть свойством этого объекта.
Это реальный пример? Я спрашиваю, потому что считаю странным, что у объекта Rules может быть сумма и порог. Я говорю об этом, потому что думаю, что это часть ответа. Я мог бы представить, что ваши правила - это пространство имен, а проект - как объект, и, по моему мнению, требуется ли для этого утверждение или нет, будет свойством класса Project.
Согласно рекомендациям Свойства и методы в MSDN (по общему признанию, для более старой версии Visual Studio), похоже, что в вашем случае методы могут быть более подходящими, чем свойства (при условии, что правила становятся более сложными. чем пороги).
Еще немного покопавшись в этом вопросе, мы обнаружили следующее:
Во-первых, вам нужно обернуть get {} вокруг логики свойств, а практическое правило (по крайней мере для меня) должно заключаться в том, что метод может изменять содержимое класса или выполнять какую-то бизнес-логику, тогда как свойство предоставляет информацию о классе.
Для вашего использования я бы предложил свойство, поскольку значения уже существуют, и вы создаете то, что известно как производное свойство.
Кроме того, ваш код может быть преобразован в
return _amount < threshold;
Я согласен с Антони Кохом. Я использую методы, когда мне нужно выполнить сложное вычисление, которое изменяет состояние класса. Если требуется простое вычисление или получение данных для текущего состояния класса, где данные уже существуют в этом состоянии и их не нужно изменять, свойство кажется более подходящим.