Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Абасс... обсудите рахитекурту

3762  1 2 3 4 5 6 7 8 все
alex445 патриот21.05.24 12:19
NEW 21.05.24 12:19 
в ответ alex445 21.05.24 12:15, Последний раз изменено 21.05.24 12:37 (alex445)

Хотя нет, не то. Функция валидации у меня присваивает отвалидированное значение. У вас получается, что MaxValue остаётся неприсвоенным, а присваивается лишь CurrentValue. Тут надо больше править. Что-то типа того, что ниже.


public class Param
{
    double maxValue;
    public virtual double MaxValue
    {
        get { return maxValue; }
        set
        {
           maxVaslue = value;
           Validate ();            
        }
    }
    protected void virtual Validate ()
    {
        maxValue = ... // maxValue validation
    }
}
public class ParamVolatile : Param
{
    double currentValue;
    public double CurrentValue
    {
        get { return currentValue; }
        set
        {
           currentValue = value;
           Validate ();
        }
    }
    protected override void Validate ()
    {
        base.Validate (); // maxValue validation  
        currentValue = ... // currentValue validation
    }
}


При этом зачем присвоения maxVaslue = value и currentValue = value, если мы будем их переприсваивать при валидации? А это явно из-за того, что нельзя передать параметр value в фукнцию Validate в обоих классах одинаково - т.е. сначала присвоить это значение полю, а потом поле отвалидировать внутри функции Validate. При этом функция Validate используется тоже запутанно - она ничего не возвращает, и будто поэтому ничего не меняет, а на самом деле меняет значения полей. Но мы не можем написать так, как в моём варианте maxValue = Validate(value), т.к. иначе придётся делать две фукнции валидации - для каждого свойства отдельно, каждая со своим набором параметров.


Я бы сказал, что у вас от моего варианта отилчается лишь тем, куда вы помещаете непонятную, запутанную часть кода, требующую пояснения. Вы это делаете в отдельной функции - ход её выполнение у вас нетривиальный. Зато свойства "чистые". У меня это в свойствах, а сами фукнции валидации "чистые".


Но по сути ничего не поменялось - как было у класса ParamVolatile свойство из базового класса, так и осталось, и его название будет смущать разных АлексНеков. )))

Программист коренной житель21.05.24 12:33
NEW 21.05.24 12:33 
в ответ alex445 21.05.24 12:15

MaxValue не валидируется, там пустой валидатор :)

Но если вдруг понадобится валидация MaxValue, то ее всегда можно добавить.

alex445 патриот21.05.24 12:39
NEW 21.05.24 12:39 
в ответ Программист 21.05.24 12:33, Последний раз изменено 21.05.24 12:40 (alex445)

Вобщем, ваш вариант тоже имеет право на жизнь, и от моего отличается лишь переносом неочевидной части кода в функцию валидации, и дополнительной валидацией MaxValue при изменении CurrentValue, хотя это не нужно.

Программист коренной житель21.05.24 12:45
NEW 21.05.24 12:45 
в ответ alex445 21.05.24 12:19

Прикол в том, что это нифига не вализация :)

По идее Validate должна кидать исключение :) Тут надо было бы подумать над названием функции... не знаю FitToRange или что там больше по смыслу подходит.


Я бы сказал, что у вас от моего варианта отилчается лишь тем, куда вы помещаете непонятную, запутанную часть кода, требующую пояснения.

Запутанная часть кода? :) Запутанная часть кода - это херь с new :) А тут все просто.


Вы это делаете в отдельной функции - ход её выполнение у вас нетривиальный. Зато свойства "чистые". У меня это в свойствах, а сами фукнции валидации "чистые".

Ход выполнения вполне тривиальный. И, при этом, никакого дублирования кода ;)


Но по сути ничего не поменялось - как было у класса ParamVolatile свойство из базового класса, так и осталось, и его название будет смущать разных АлексНеков. )))

Ну тут уж как ты задачу сформулировал ;)

alex445 патриот21.05.24 12:56
NEW 21.05.24 12:56 
в ответ Программист 21.05.24 12:45, Последний раз изменено 21.05.24 13:09 (alex445)
Прикол в том, что это нифига не вализация :)
По идее Validate должна кидать исключение :) Тут надо было бы подумать над названием функции... не знаю FitToRange или что там больше по смыслу подходит.

Подумать над названием можно. Но я специально убрал конкретное исполнение, т.к. там может быть любая валидация, а не только приведение к диапазону. И что должна делать валидация - не установлено раз и навсегда кем-то. И уж тем более не обязательно кидать исключения. В некоторых фреймворках она просто возвращает статус и сообщение об ошибке. А в некоторых других, например встроенная в контролы валидация, принудительно исправляет введённые значения безо всяких сообщений и исключений - типа, при вводе в числовое поле числа, выходящего за пределы диапазона, число принудительно устанавливается в ту или иную границу этого диапазона. У меня ближе ко второму варианту.


Я бы сказал, что у вас от моего варианта отилчается лишь тем, куда вы помещаете непонятную, запутанную часть кода, требующую пояснения.
Запутанная часть кода? :) Запутанная часть кода - это херь с new :) А тут все просто.

У меня нет "хрени с new" - это был один из вариантов, который не рассматривался далее. Далее я давал ссылки на вариант с override. Вы просто перегрузили метод валидации, а я перегрузил свойство. Других особых отличий нет. Ну ещё у меня не смешаны валидация MaxValue и CurrentValue, т.к. это разные валидации. У вас же вся валидация в одном методе, метод отвечает за валидацию всего класса и вызывается при изменении любого свойства из MaxValue и CurrentValue.


Вот наши варианты (ваш я подправил, т.к. maxValue надо присвоить отвалидированное значение в любом случае). Ваш слева, мой справа.


alex445 патриот21.05.24 13:06
NEW 21.05.24 13:06 
в ответ alex445 21.05.24 12:56

У меня, например, минус в том, что переопределение всего свойства MaxValue в классе ParamVolatile явно избыточно - достаточно переписать лишь сеттер. Но сеттер отдельно не переписывается, а городить для этого отдельный метод SetMaxValue, который вызывать в сеттере же свойства MaxValue - избыточно.

alex445 патриот21.05.24 13:32
NEW 21.05.24 13:32 
в ответ Программист 21.05.24 12:45, Последний раз изменено 21.05.24 13:44 (alex445)

Вот я причесал выш код, как я бы его написал - два валидирующих метода вместо одного общего


public class Param
{
    double maxValue;
    public virtual double MaxValue
    {
        get => return maxValue;
        set => maxValue = ValidateMaxValue();
    }
 
    protected double virtual ValidateMaxValue() => ...
}


public class ParamVolatile : Param
{
    double currentValue;
    public double CurrentValue
    {
        get => return currentValue;
        set => currentValue = ValidateCurrentvValue();
    }
 
    override double ValidateMaxValue()
    {
        base.ValidateMaxValue();
        ValidateCurrentvValue();
    }
 
    double ValidateCurrentvValue() => ...
}

Вот слева направо: ваш вариант, ваш, исправленный мной, мой собственный вариант. Вот посередине - ваш исправленный - мне нравится больше всего.


alex445 патриот21.05.24 13:46
NEW 21.05.24 13:46 
в ответ alex445 21.05.24 13:32

Хотя вариант посередине больше напоминает мой вариант с переписанным свойством, только вместо свойства - метод валидации.

Программист коренной житель21.05.24 13:51
NEW 21.05.24 13:51 
в ответ alex445 21.05.24 13:32

Я не знаю зачем надо валидировать MaxValue, ну тут уж хозяин - барин :)


Я также не совсем понимаю, каким образом тут будет установлено значение maxValue

public class Param
{
    double maxValue;
    public virtual double MaxValue
    {
        get => return maxValue;
        set => maxValue = ValidateMaxValue();
    }
 
    protected double virtual ValidateMaxValue() => ...
}

если value из сеттера не передается :)


А вот эта конструкция

    override double ValidateMaxValue()
    {
        base.ValidateMaxValue();
        ValidateCurrentvValue();
    }
 
    double ValidateCurrentvValue() => ...

необходима по одной простой причине: по какой-то неведомой причине валидации currentValue и maxValue должны иметь разные названия :)


Но спишем это все на "задачу в с тиле Murr'а", когда в процессе решения всплывает еще 100500 деталей :D


alex445 патриот21.05.24 13:57
NEW 21.05.24 13:57 
в ответ Программист 21.05.24 13:51, Последний раз изменено 21.05.24 14:51 (alex445)
Я также не совсем понимаю, каким образом тут будет установлено значение maxValue


public class Param
{
    double maxValue;
    public virtual double MaxValue
    {
        get => return maxValue;
        set => maxValue = ValidateMaxValue();
    }
 
    protected double virtual ValidateMaxValue() => ...
}
если value из сеттера не передается :)

Это я опечатался - надо передать значение из сеттера. Ещё надо присвоить currentValue при валидации MaxValue в классе ParamVolatile, затем там же вернуть отвалидированное значение MaxValue. И убрать virtual у свойства MaxValue. И изменить метод ValidateCurrentValue, чтобы он мог принимать значение MaxValue. Мдаа, много изменить надо, чтобы ваш подход применить. Вот так будет правильнее


public class Param
{
    double maxValue;
    public double MaxValue
    {
        get => return maxValue;
        set => maxValue = ValidateMaxValue(value);
    }
 
    protected virtual double ValidateMaxValue(double value) => ...
}

public class ParamVolatile : Param
{
    double currentValue;
    public double CurrentValue
    {
        get => return currentValue;
        set => currentValue = ValidateCurrentValue(value);
    }
 
    protected override double ValidateMaxValue(double maxValue)
    {
        var newMaxValue = base.ValidateMaxValue(maxValue);
        currentValue = ValidateCurrentValue(CurrentValue, newMaxValue);
        return newMaxValue;
    }
 
    double ValidateCurrentValue(double currentValue, double maxValue) => ...
}


alex445 патриот21.05.24 14:01
21.05.24 14:01 
в ответ Программист 21.05.24 13:51, Последний раз изменено 21.05.24 14:07 (alex445)
по какой-то неведомой причине валидации currentValue и maxValue должны иметь разные названия :)

Попробуйте переписать мой последний вариант с одним методом валидации. У них же разный набор параметров. И в вашем случае у вас лишняя валидация - т.е. валидируются оба свойства, когда изменяется любое из них. Заметьте, у меня идёт переприсваивание значений полей при валидации. В вашем варианте изменения всех свойств при изменении любого из них придётся клиентам класса это учитывать - что изменится MaxValue при изменении CurrentValue и наоборот. А мне нужно лишь наоборот. Поэтому валидацию этих свойств лучше разделить и вызывать отдельно или одну за другой в зависимости от того, какое свойство изменилось.

Программист коренной житель21.05.24 14:22
NEW 21.05.24 14:22 
в ответ alex445 21.05.24 14:01
У них же разный набор параметров.

Ну это уже твои тараканы :) Оба этих метода легко переписываются так, что у них вообще нет никаких параметров.


И в вашем случае у вас лишняя валидация

Нету там никакой лишней валидациию Эта функция:

    protected virtual Validate ()
    {
    }

ничего не валидирует и не изменяет. Она пустая.


Я вообще не понимаю, от куда в условии взялась необходимость валидировать/изменять maxValue (подход Murr'а? :D)


Да даже если вдруг и надо валидировать maxValue, то я не вижу в этом проблемы. Ну займет эта ненужная валидация лишких 3 такта. И что? Зато тот, кто будет использовать ParamVolatile будет уверен в том, что все поля валидны и сразу понятно где, что, как и по каким правилам меняется.

alex445 патриот21.05.24 14:28
NEW 21.05.24 14:28 
в ответ Программист 21.05.24 14:22, Последний раз изменено 21.05.24 14:30 (alex445)
Да даже если вдруг и надо валидировать maxValue, то я не вижу в этом проблемы. Ну займет эта ненужная валидация лишких 3 такта. И что? Зато тот, кто будет использовать ParamVolatile будет уверен в том, что все поля валидны и сразу понятно где, что, как и по каким правилам меняется.

Изменение CurrentValue не влияет на MaxValue. Т.е. при изменении CurrentValue не нужно лишний раз удостовериваться, что MaxValue имеет правильное значение. У вас это получается случайно, т.к. хочется всю валидацию поместить в один метод. Но при масштабировании (вовлечении в валидацию большего числа свойств) это будет давать лишнюю нагрузку и захламлять усложнять метод Validate. В моём же подходе я буду просто тасовать вызовы валидирующих методов в нужном порядке по мере увеличения свойств, требующих валидации.


Ну и там не 3 такта. Как я сказал, клиенты класса тоже должны отреагировать, что изменилось больше свойств, чем планировалось. Но это мелочи.


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

Программист коренной житель21.05.24 14:48
NEW 21.05.24 14:48 
в ответ alex445 21.05.24 14:28
Т.е. при изменении CurrentValue не нужно лишний раз удостовериваться, что MaxValue имеет правильное значение.

Это очень спорное утверждение, т.к. Validate по идее должена валидировать весь объект.


У вас это получается случайно, т.к. хочется всю валидацию поместить в один метод.

Нет, никакой случайности тут нет.


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

И в результате будет захламлен весь класс :) Т.е. на каждую проперти будет по специальному валидатору при этом с неизвестным заранее количеством вызовов. И самое забавное в том, что валидироваться будет только часть объекта, т.е. нельзя будет гарантировать, что объект находится в валидном состоянии :)


А если на все это наложить требование тестируемости, то станет совсем весело :)



Ну и там не 3 такта. Как я сказал, клиенты класса тоже должны отреагировать, что изменилось больше свойств, чем планировалось. Но это мелочи.

Если ничего не менялось, то и реагировать не нужно ;) Я уж не говою о том, что такого условия не было ;) Для оповещения клиентов должен быть свой механизм.


alex445 патриот21.05.24 14:52
NEW 21.05.24 14:52 
в ответ Программист 21.05.24 14:48
Т.е. при изменении CurrentValue не нужно лишний раз удостовериваться, что MaxValue имеет правильное значение.

Это очень спорное утверждение, т.к. Validate по идее должена валидировать весь объект.

Нужно ли валидировать ёмкость бака при изменении уровня топлива по мере езды или при заправке?

alex445 патриот21.05.24 14:53
NEW 21.05.24 14:53 
в ответ Программист 21.05.24 14:48, Последний раз изменено 21.05.24 14:59 (alex445)

Ща попробую переписать это с одним методом валидации, как вы говорите. Я там наисправлял, т.к. оказалось, что не учёл много деталей при переписывании с двумя методами.

Программист коренной житель21.05.24 15:10
NEW 21.05.24 15:10 
в ответ alex445 21.05.24 14:52
Нужно ли валидировать ёмкость бака при изменении уровня топлива по мере езды или при заправке?

Не нужно. Более того, емкость бака неизменяемая величина, а значит у емкости бака не должно быть никакого сеттера или другой возможности изменить этот параметр :)

alex445 патриот21.05.24 15:14
NEW 21.05.24 15:14 
в ответ Программист 21.05.24 15:10

По мере езды или заправки - да. Но если мы заедем на веркштатт к знакомому Михалычу, который за бутылку приварит нам второй бак с возможностью перекачки... Или просто заменит нам бак на более ёмкий... Вобщем, совсем уж от сеттера избавляться не надо, т.к. на более глобальном уровне и ёмкость бака может измениться. В условии я просто обозначил, что это тоже должно иметь сеттер, а не быть там константой или одним лишь геттером.

alex445 патриот21.05.24 15:27
NEW 21.05.24 15:27 
в ответ alex445 21.05.24 14:53, Последний раз изменено 21.05.24 15:33 (alex445)

Переписал с одним методом валидации так. С учётом, что мне надо в методе валидации обновить отвалидированное значение изменяемого свойства, используя при этом правильные свойства, с учётом уровня доступности полей (это я про "currentValue = ... // validate currentValue using MaxValue, currentValue"). Т.е. сам метод валидации ничего не возвращает, а все присваивания полям делает внутри себя.


public class Param
{
   double maxValue;
   public double MaxValue
   {
        get => maxValue;
        set
        {
            maxValue = value;
            Validate();
        }
   }
 
   protected virtual void Validate()
   {
        maxValue = ... // validate maxValue using maxValue
   }
}

public class ParamVolatile : Param
{
   double currentValue;
   public double CurrentValue
   {
        get => currentValue;
        set
        {
            currentValue = value;
            Validate();
        }
   }

   protected override void Validate()
   {
        base.Validate();
        currentValue = ... // validate currentValue using MaxValue, currentValue
   }
}
Программист коренной житель21.05.24 15:34
NEW 21.05.24 15:34 
в ответ alex445 21.05.24 15:14
Вобщем, совсем уж от сеттера избавляться не надо, т.к. на более глобальном уровне и ёмкость бака может измениться.

Не может. Может меняться конфигурация, т.к. можно вызывать конструктор бака с одним или с другим параметром (объемом). Однако объем бака - все равно не меняется.

1 2 3 4 5 6 7 8 все