Последовательность логики
От: snaphold  
Дата: 16.11.15 14:03
Оценка:
Привет

Есть класс Бонус и есть конструктор

class Bonus 
{
    public Bonus(int days, int baseSalary)
    {
      this.days = days;
      this.baseSalary = baseSalary;
      this.rate = baseSalary / days;     
    }
    
.....
    public Double Salary
    {
        get { return rate * baseSalary; }
    }
}





Как сделать так, чтобы rate всегда вычилялся после days. т.е. чтобы кто-то случайно в коде не поменял последовательность и из-за этого не перестало работать?
И вообще насколько данных подход правильный?
Re: Последовательность логики
От: Sinix  
Дата: 16.11.15 14:17
Оценка:
Здравствуйте, snaphold, Вы писали:

S>Как сделать так, чтобы rate всегда вычилялся после days. т.е. чтобы кто-то случайно в коде не поменял последовательность и из-за этого не перестало работать?

S>И вообще насколько данных подход правильный?

Сам код сфероконичный донельзя.
Если говорить про пример как есть — порядок строк конкретно в этом коде неважен. В общем случае, если нужны гарантии и нельзя разюить код на несколько методов — просто заполните сначала промежуточные переменные, а затем скиньте вычисленные значения в поля. Чтобы искользовать переменную до её заполнения — придётся перемещать её выше, будет видно.

А если говорить про код для биз-расчётов, то в нём всё неправильно. Начиная от int вместо decimal и заканчивая смешиванием состояния и биз-логики в одном классе, причём в конструкторе.
Re[2]: Последовательность логики
От: snaphold  
Дата: 16.11.15 14:33
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, snaphold, Вы писали:


S>>Как сделать так, чтобы rate всегда вычилялся после days. т.е. чтобы кто-то случайно в коде не поменял последовательность и из-за этого не перестало работать?

S>>И вообще насколько данных подход правильный?

S>Сам код сфероконичный донельзя.


класс показывает, какой у человека будет бонус.

S>Если говорить про пример как есть — порядок строк конкретно в этом коде неважен. В общем случае, если нужны гарантии и нельзя разюить код на несколько методов — просто заполните сначала промежуточные переменные, а затем скиньте вычисленные значения в поля. Чтобы искользовать переменную до её заполнения — придётся перемещать её выше, будет видно.


т.е. если грубо, то надо самому следить, чтобы нужные переменные были иниицированы выше?

S>А если говорить про код для биз-расчётов, то в нём всё неправильно. Начиная от int вместо decimal и заканчивая смешиванием состояния и биз-логики в одном классе, причём в конструкторе.


с типом понятно. а про смешивание подробней можно?
Re: Последовательность логики
От: SuhanovSergey  
Дата: 16.11.15 14:48
Оценка: +3 :)
Здравствуйте, snaphold, Вы писали:

S>Как сделать так, чтобы rate всегда вычилялся после days. т.е. чтобы кто-то случайно в коде не поменял последовательность и из-за этого не перестало работать?


Написать юнит тест
Re: Последовательность логики
От: Mr.Delphist  
Дата: 16.11.15 14:58
Оценка:
Здравствуйте, snaphold, Вы писали:

S>Как сделать так, чтобы rate всегда вычилялся после days. т.е. чтобы кто-то случайно в коде не поменял последовательность и из-за этого не перестало работать?


Значит, надо сделать так, чтобы Rate перевычислялся автоматом после установки days. Например, оформить это rate как приватное property и привязать INotifyPropertyChanged (а если юзается какой-то фреймворк типа MVVM, то там подобное есть из коробки — дописать одну строчку в сеттер и готово).
Re[3]: Последовательность логики
От: Sinix  
Дата: 16.11.15 17:15
Оценка: 73 (2) +3
Здравствуйте, snaphold, Вы писали:

S>класс показывает, какой у человека будет бонус.

Ну так оно не так считается совсем

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

Если человек понимает, о чём говорит — берегите его, это ваш запасной аналитик и куча сэкономленного времени. Если просто цитирует Фаулера, с доводами "я про это читал" — ни под каким предлогом не подпускать к принятию глобальных архитектурных решений — это ваша личная смертьпроекту. Потому что лучшего способа угробить проект, чем жертвовать реальными задачами ради феншуя не придумал ещё никто и никогда


И собственно про требования к типовым биз-расчётам — они все описываются очень простым правилом: любая костанта — это переменная.

Отработанное время может браться в часах или в днях (причём реальные часы к учётным имеют весьма слабое отношение). Базовый оклад может собираться из нескольких источников, начиная с ФОТ штатной должности и заканчивая суммой в конкретной оплате. Ставка (коэффициент) может исчисляться в процентах, может в количестве ставок, может в учетных баллах, может определяться по весьма неочевидным правилам (например, 19% оклада но не более 30000 в сумме с прочими надбавками и не менее чем 5% от МРОТ). На каждом из этапов вычислений может применяться округление и/или повышающие-понижающие коэффициенты.

Про то, что ваша зарплата на самом деле не то, что вы получаете на руки, а целый набор из выплат (и удержаний) — начисленная зарплата, ндфл, пенсионный, соцстрахование и про то, как эти выплаты раскидываются по разным источникам даже не будем, и без этого проблем хватает.

Если суммировать, то типовой биз-расчёт очень походит на конвеер: само число шагов конечно, но каждый из шагов может быть сконфигурирован под нужды заказчика несколькими способами. Пытаться уместить всю эту кухню в одном классе (и тем более в одном конструкторе) — не самая лучшая идея

Решение не менее стандартно: заводим класс для расчетных данных и иерархию классов, которые будут изменять логику отдельных шагов вычислений.
Разумеется, для принципиально разных алгоритмов придётся заводить свои ветки классов, а в особо тяжёлых случаях собирать конечные алгоритмы ч/з DI, но начинается всегда с пары "класс с расчётными данными + класс с логикой расчёта".

S>>Если говорить про пример как есть — порядок строк конкретно в этом коде неважен. В общем случае, если нужны гарантии и нельзя разюить код на несколько методов — просто заполните сначала промежуточные переменные, а затем скиньте вычисленные значения в поля. Чтобы искользовать переменную до её заполнения — придётся перемещать её выше, будет видно.


S>т.е. если грубо, то надо самому следить, чтобы нужные переменные были иниицированы выше?

Нет, просто объявляйте переменные перед использованием. Компилятор проследит, чтобы вы не использовали неинициализированные переменные. Это только один из вариантов решения, не факт что он вам подойдёт.

S>>А если говорить про код для биз-расчётов, то в нём всё неправильно. Начиная от int вместо decimal и заканчивая смешиванием состояния и биз-логики в одном классе, причём в конструкторе.

S>с типом понятно. а про смешивание подробней можно?
См простыню выше
Re: Последовательность логики
От: Vladek Россия Github
Дата: 16.11.15 21:04
Оценка: +1
Здравствуйте, snaphold, Вы писали:

S>Как сделать так, чтобы rate всегда вычилялся после days. т.е. чтобы кто-то случайно в коде не поменял последовательность и из-за этого не перестало работать?


Привязать к бонусу стратегию начисления зарплаты. Она же пригодится, если потом кому-то будут начислять бонусы по другим параметрам (размер бюста, степень родства, прошлый опыт работы).
Re: Последовательность логики
От: Janus Россия  
Дата: 20.11.15 14:24
Оценка:
Здравствуйте, snaphold, Вы писали:


S>Как сделать так, чтобы rate всегда вычилялся после days. т.е. чтобы кто-то случайно в коде не поменял последовательность и из-за этого не перестало работать?

S>И вообще насколько данных подход правильный?


А если так :

class Bonus 
{
   private  int days;
    ......
    ......


internal static Bonus Create(int days, int baseSalary)

    {
        Bonus bonus = new Bonus();      
        bonus.days = days;
        bonus.baseSalary = baseSalary;
        bonus.rate = baseSalary / days; 
        return bonus;
    
    }
    
.....
    public Double Salary
    {
        get { return rate * baseSalary; }
    }
}


......
Bonus  bn = Bonus.Create(2,4);
  .....  =  bn.Salary;
... Хорошо уметь читать между строк. Это иногда
приносит большую пользу
Отредактировано 20.11.2015 14:30 Janus . Предыдущая версия . Еще …
Отредактировано 20.11.2015 14:26 Janus . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.