2012-02-06 2 views
1

Итак, предположим, что у нас есть класс Foo со свойствами FirstProp и SecondProp и ThirdProp. Бизнес-мудрый, допустимые значения в SecondProp зависят от значения, установленного для FirstProp, и допустимые значения ThirdProp зависят от значений как FirstProp, так и SecondProp. Где он наиболее подходит, чтобы поставить эту логику?Наиболее подходящее место для проверки состояния объекта

Если он находится в настройщике каждого свойства, то есть тот факт, что пользователь класса может установить его ThirdProp перед двумя другими, потребовалось бы также принудительное выполнение порядка установки свойств? Это не кажется оптимальным. Кроме того, если мы хотим ограничить инициализацию объекта пармеризованными конструкторами, то это не будет практичным в таких случаях, как когда мы проектируем объект как тип значения (struct), поскольку конструктор по умолчанию в структуре всегда доступен.

Любой ввод оценивается.

ответ

0

Лично я бы сохранил Foo как чистую фасоль java. Это имеет много преимуществ, которые могут быть не очевидны вначале. Один из них - вам нужен/нужен простой сеттер, когда вы читаете/сохраняете этот объект в базе данных (если есть).

Вместо этого создайте подкласс Foo, который содержит бизнес-логику. Это разделит ваш код на уровень сохранения и уровень домена/бизнес-объекта.

+0

Если я правильно вас понимаю, то такие проверки в более конкретных классах нарушают LSP. Рассмотрим классический прямоугольник <--> квадратный пример –

+0

Это правда, в зависимости от его логики, это может быть нарушение LSP. Это действительно трудно понять из его примера. – Michael

0

Я бы предпочел сделать Foo объект неизменяемого значения и сделать все необходимые проверки на статических фабриках.

final class Foo { 
    private final SomeObject first; 
    private final SomeObject second; 
    private final SomeObject third; 

    private Foo(SomeObject first, SomeObject second, SomeObject third) { 
    this.first = first; 
    this.second = second; 
    this.third = third; 
    } 

    /* Simple Getters + equals and hashCode if necessary */ 

    public static Foo newInstance(SomeObject first, SomeObject second, SomeObject third) { 
    if (! /* your condition holds */) 
     throw new IllegalArgumentException(); 

    return new Foo(...); 
    } 
} 
+0

Но действительно ли этот подход не позволяет пользователям класса пропускать завод и переходить непосредственно к конструктору? – MSD

+0

@MSD, конструктор является закрытым, и он заставляет пользователей использовать статические заводы. Вы можете создать такой объект и попробовать сами. В любом случае, все эти ограничения можно избежать на более низких уровнях (любого подхода). –

0

Я бы группа валидация свойства в методе Validate(), который может либо быть вызван извне, прежде чем использовать объект (возвращает истину, если правильно инициализировать), или в каких-либо добытчиках бросить InvalidObjectStateException, если они используются прежде чем свойства будут установлены правильно.

+0

Я не согласен. Объекту никогда не разрешается попадать в недопустимое состояние. – cdaq

Смежные вопросы