$ git clone [email protected]:davygora/rubybursa.git
$ cd rubybursa
$ ruby homework_4.rb
Задача 1. Класс Developer
Создаём класс Developer (разработчик) со следующей ответственностью:
- Создаётся с именем разработчика как аргументом:
dev = Developer.new('Вася')
- Можно добавить задачу:
dev.add_task('Полить кактус')
— должен напечатать: «Вася: добавлена задача "Полить кактус". Всего в списке задач: 1» (цифра увеличивается при добавлении новых задач) - Можно спросить, какие есть задачи в списке:
puts dev.tasks
— должен напечатать нумерованный список задач в порядке их добавления. - Можно заставить работать:
dev.work!
— должен выбрать первую из добавленных задач и напечатать: «Вася: выполнена задача "Полить кактус". Осталось задач: 0» (после этого задача из списка задач должна исчезать) - Если задач не осталось, то метод
work!
должен бросать исключение с текстом «Нечего делать!» - В классе
Developer
должна быть константаMAX_TASKS
, равная 10 - Если задач у разработчика уже столько, сколько записано в константе
MAX_TASKS
, методadd_task
должен бросать исключение с текстом «Слишком много работы!» - У класса
Developer
должен быть методstatus
, возвращающий одно из трёх значений: "свободен" (задач нет), "работаю" (задачи есть, но можно добавить ещё) и "занят" (задач много, больше добавить нельзя) - У класса
Developer
должны быть методcan_add_task?
возвращающийtrue
илиfalse
в зависимости от того, можно ли добавить ещё задачу, или их уже слишком много; иcan_work?
, возвращающийtrue
илиfalse
в завимости от того, есть ли разработчику что делать
Задача 2. Наследники класса Developer
- Создать двух наследников класса
Developer
:JuniorDeveloper
иSeniorDeveloper
JuniorDeveloper
ведёт себя какDeveloper
, со следующими отличиями:- у него меньше максимальное количество задач (5);
- если длина текста задачи больше 20 символов, он должен бросать исключение с текстом "Слишком сложно!"
- при работе (вызов метода
work!
) он должен писать: «Вася: пытаюсь делать задачу "Полить кактус". Осталось задач: 0»
SeniorDeveloper
ведёт себя какDeveloper
, со следующими отличиями:- у него больше максимальное количество задач (15);
- при вызове метода
work!
он со случайной вероятностью либо выполняет сразу две задачи (и, соответственно, печатает две строки «Вася: выполнена задача "Полить кактус". Осталось задач: N»), либо печатает «Что-то лень» и не выполняет ни одной.
Задача 3.
- Учитывая, что у нас есть классы из предыдущего задания (
Developer
,JuniorDeveloper
иSeniorDeveloper
), нужно написать классTeam
(команда разработчиков), который бы работал так:
team = Team.new do
# создаём команду, описываем её в этом блоке
# описываем, какие в команде есть разработчики
have_seniors "Олег", "Оксана"
have_developers "Олеся", "Василий", "Игорь-Богдан"
have_juniors "Владислава", "Аркадий", "Рамеш"
# описываем в каком порядке выдавать задачи:
# * сначала любому джуниору
# * потом любому обычному разработчику
# * потом любому старшему
priority :juniors, :developers, :seniors
# описываем дополнительные действия, когда задача выдана джуну
on_task :junior do |dev, task|
puts "Отдали задачу #{task} разработчику #{dev.name}, следите за ним!"
end
# ...и так можно для любого типа разработчиков описать, например:
on_task :senior do |dev, task|
puts "#{dev.name} сделает #{task}, но просит больше с такими глупостями не приставать"
end
end
То есть вам надо сделать, чтобы Team
в конструкторе принимал блок, и внутри этого блока могли быть выполнены методы
have_seniors
, have_developers
, have_juniors
, priority
и on_task
.
- Созданная таким образом команда должна работать следующим образом:
team.add_task 'Погладить шнурки'
— задача выдана тому разработчику, у которого меньше всего задач, в порядке, описанном вpriority
: то есть первую задачу даём первому свободному джуну, вторую тоже (пока не кончатся свободные джуны), следующую — первому свободному обычному разработчику и т.д; когда у всех уже есть по одной задаче — опять начинаем с джунов. - Если задача оказалась выдана джуниору (или другому типу разработчика, который мы указали в
on_task
) — должно отрабатывать действие, указанное вon_task
. - Методы
team.seniors
,team.developers
,team.juniors
должны возвращать массивы разработчиков соответствующих типов. - Метод
team.all
должен возвращать массив разработчиков (в том порядке в котором они описаны — то есть в нашем случае это будет массив из 8 объектов: первые два — сеньоры, следующие три — обычные, следующие три — джуны) - Метод
team.report
должен печатать примерно такой результат:
Олег (senior): задача1, задача2
Оксана (senior): задача3, задача8
Олеся (developer): задача4, задача5
...и т.д....
То есть «Имя (тип): список задач» для каждого разработчика. Порядок вывода разработчиков — в порядке, в каком им будут
выдаваться задачи (то есть с учётом priority
и текущего числа задач, сверху — тот, кто получит задачу следующим).
Бонусное задание. Добавляем опции методу add_task
team.add_task 'Помыть окна', complexity: :senior
— задача должна быть выдана обязательно старшему разработчику.team.add_task 'Налить чаю', to: 'Василий'
— задача должна быть обязательно выдана Василию.
Подсказки
- Классы
Developer
,SeniorDeveloper
,JuniorDeveloper
можно менять при необходимости, но основная функциональность должна быть в классеTeam
. - Для правильной работы блока, который передаётся в
Team.new
, вам понадобитсяinstance_eval
. - Я рекомендую хранить разработчиков внутри объекта
Team
в одном общем массиве, и для решения, кому выдать следующую задачу, использоватьsort_by
.
Рекомендации которые были выданы во время выполнения задания от преподавателя:
Немного рекомендаций по ДЗ, сделанных на основании уже существующего вашего кода.
- класс — это тоже значение, поэтому вполне можно передавать классы в методы, хранить их в хешах, сравнивать друг с другом и т.д.; то есть вполне можно сделать какой-нибудь такой метод:
def make_developer(type, name)
type.new(name)
end
# и вызывать его как-нибудь так:
make_developer(JuniorDeveloper, 'Вася')
- напоминаю, что классы из предыдущей домашки менять можно; например, можно добавить им метод, возвращающий
:senior
дляSeniorDeveloper
,:junior
дляJuniorDeveloper
и т.п. в большинстве случаев это чудовищно упростит код - не забываем про принцип DRY — Don't Repeat Yourself — Не повторяйся. Регулярно смотрите на свой код свежим взглядом, и если у вас оказалось несколько методов с почти-одинаковым кодом, или несколько веток case, в которых много похожего происходит — вполне вероятно, что код можно очень сильно упростить.
- в реализации
add_task
(выборе правильного разработчика для задачи) вам может сильно помочь методsort_by
, надо только понять, по каким критериям отсортировать - ...а в решении бонусной задачи (опции
add_task
) лучше всего сработает предварительная (доsort_by
) фильтрация списка разработчиков, из которых будем выбирать - напоминаю, что в задании есть рекомендация хранить всех разработчиков в одном общем массиве
- разделение ответственности: знание о приоритетах — ответственность команды, не стоит заставлять разработчиков в команде помнить, какой у них приоритет, это не их забота; инкапсуляция!