Skip to content

Instantly share code, notes, and snippets.

@FaAway
Created March 19, 2016 12:54
Show Gist options
  • Save FaAway/fad5326ddd46f0bc2b73 to your computer and use it in GitHub Desktop.
Save FaAway/fad5326ddd46f0bc2b73 to your computer and use it in GitHub Desktop.
javarush level29.lesson15.big01
package com.javarush.test.level29.lesson15.big01.car;
/**
* Created by FarAway on 09.03.2016.
*/
public class Cabriolet extends Car {
public Cabriolet(int numberOfPassengers) {
super(Car.CABRIOLET, numberOfPassengers);
}
@Override
public int getMaxSpeed() {
final int MAX_CABRIOLET_SPEED = 90;
return MAX_CABRIOLET_SPEED;
}
}
package com.javarush.test.level29.lesson15.big01.car;
import java.util.Date;
public abstract class Car {
static public final int TRUCK = 0;
static public final int SEDAN = 1;
static public final int CABRIOLET = 2;
double fuel;
public double summerFuelConsumption;
public double winterFuelConsumption;
public double winterWarmingUp;
private int type;
private boolean driverAvailable;
private int numberOfPassengers;
protected Car(int type, int numberOfPassengers) {
this.type = type;
this.numberOfPassengers = numberOfPassengers;
}
public static Car create(int type, int numberOfPassengers) {
switch (type) {
case TRUCK: return new Truck(numberOfPassengers);
case SEDAN: return new Sedan(numberOfPassengers);
case CABRIOLET: return new Cabriolet(numberOfPassengers);
default: return null;
}
}
public void fill(double numberOfLiters) throws Exception
{
if (numberOfLiters < 0) throw new Exception();
fuel += numberOfLiters;
}
public double getTripConsumption(Date date, int length, Date SummerStart, Date SummerEnd)
{
if (isSummer(date, SummerStart, SummerEnd)) {
return getSummerConsumption(length);
}
else {
return getWinterConsumption(length);
}
}
public int getNumberOfPassengersCanBeTransferred() {
if (!canPassengersBeTransferred())
return 0;
return numberOfPassengers;
}
public boolean isDriverAvailable() {
return driverAvailable;
}
public void setDriverAvailable(boolean driverAvailable) {
this.driverAvailable = driverAvailable;
}
public void startMoving() {
fastenDriverBelt();
if (numberOfPassengers > 0)
fastenPassengersBelts();
}
public void fastenPassengersBelts() {
}
public void fastenDriverBelt() {
}
public abstract int getMaxSpeed();
public boolean isSummer(Date date , Date summerStart, Date summerEnd) {
return (date.before(summerEnd) && date.after(summerStart));
}
public double getWinterConsumption(int length) {
return length * winterFuelConsumption + winterWarmingUp;
}
public double getSummerConsumption(int length) {
return length * summerFuelConsumption;
}
private boolean canPassengersBeTransferred() {
return isDriverAvailable() && fuel > 0;
}
}
package com.javarush.test.level29.lesson15.big01.car;
/**
* Created by FarAway on 09.03.2016.
*/
public class Sedan extends Car {
public Sedan(int numberOfPassengers) {
super(Car.SEDAN, numberOfPassengers);
}
@Override
public int getMaxSpeed() {
final int MAX_SEDAN_SPEED = 120;
return MAX_SEDAN_SPEED;
}
}
package com.javarush.test.level29.lesson15.big01.car;
/**
* Created by FarAway on 09.03.2016.
*/
public class Truck extends Car {
public Truck(int numberOfPassengers) {
super(Car.TRUCK, numberOfPassengers);
}
@Override
public int getMaxSpeed() {
final int MAX_TRUCK_SPEED = 80;
return MAX_TRUCK_SPEED;
}
}
package com.javarush.test.level29.lesson15.big01.human;
/**
* Created by FarAway on 09.03.2016.
*/
public interface Alive {
void live();
}
package com.javarush.test.level29.lesson15.big01.human;
/**
* Created by FarAway on 09.03.2016.
*/
public class BloodGroup {
private final int code;
public int getCode() {
return code;
}
private BloodGroup(int code) {
this.code = code;
}
public static BloodGroup first() { return new BloodGroup(1);}
public static BloodGroup second() { return new BloodGroup(2);}
public static BloodGroup third() { return new BloodGroup(3);}
public static BloodGroup fourth() { return new BloodGroup(4);}
}
package com.javarush.test.level29.lesson15.big01.human;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Human implements Alive {
private static int nextId = 0;
private int id = nextId++;
protected int age;
protected String name;
public class Size {
public int height,
weight;
}
protected Size size;
private List<Human> children = new ArrayList<>();
private BloodGroup bloodGroup;
public void setBloodGroup(BloodGroup bloodGroup) {
this.bloodGroup = bloodGroup;
}
public BloodGroup getBloodGroup() {
return bloodGroup;
}
public Human(String name, int age)
{
this.name = name;
this.age = age;
this.id = nextId;
nextId++;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public List<Human> getChildren() {
return Collections.unmodifiableList(children);
}
public void addChild(Human child) {
children.add(child);
}
public void removeChild(Human child) {
children.remove(child);
}
public String getPosition() {
return "Человек";
}
public void printData() {
System.out.println(getPosition() + ": " + name);
}
@Override
public void live() {
}
public void printSize() {
System.out.println("Рост: " + size.height + " Вес: " + size.weight);
}
}
package com.javarush.test.level29.lesson15.big01.human;
/**
* Created by FarAway on 09.03.2016.
*/
public class Soldier extends Human {
public Soldier(String name, int age) {
super(name, age);
}
@Override
public void live() {
fight();
}
public void fight() {
}
}
package com.javarush.test.level29.lesson15.big01.human;
import java.util.Date;
public class Student extends UniversityPerson {
private int course;
private double averageGrade;
private Date beginningOfSession;
private Date endOfSession;
public Student(String name, int age, double averageGrade) {
super(name, age);
this.name = name;
this.age = age;
this.averageGrade = averageGrade;
}
public void live() {
learn();
}
public void learn() {
}
public int getCourse() {
return course;
}
public void incAverageGrade(double delta)
{
setAverageGrade(getAverageGrade() + delta);
}
public void setCourse(int course) {
this.course = course;
}
public void setAverageGrade(double averageGrade) {
this.averageGrade = averageGrade;
}
@Override
public String getPosition() {
return "Студент";
}
public void setBeginningOfSession(Date date) {
beginningOfSession = date;
}
public void setEndOfSession(Date date) {
endOfSession = date;
}
public double getAverageGrade() {
return averageGrade;
}
}
package com.javarush.test.level29.lesson15.big01.human;
import java.util.ArrayList;
import java.util.List;
public class StudentsDataBase {
public static List<Student> students = new ArrayList<>();
public static void addInfoAboutStudent(Student student) {
students.add(student);
printInfoAboutStudent(student);
}
public static void printInfoAboutStudent(Student student) {
System.out.println("Имя: " + student.getName() + " Возраст: " + student.getAge());
}
public static void removeStudent(int index) {
if (index >= 0 && index < students.size())
students.remove(index);
}
public static void findDimaOrSasha() {
for (int i = 0; i < students.size(); i++) {
if (students.get(i).getName().equals("Dima")) {
System.out.println("Студент Dima есть в базе.");
break;
}
if (students.get(i).getName().equals("Sasha")) {
System.out.println("Студент Sasha есть в базе.");
break;
}
}
}
}
package com.javarush.test.level29.lesson15.big01.human;
public class Teacher extends UniversityPerson {
private int numberOfStudents;
public Teacher(String name, int age, int numberOfStudents) {
super(name, age);
this.name = name;
this.age = age;
this.numberOfStudents = numberOfStudents;
}
public void live() {
teach();
}
public void teach() {
}
@Override
public String getPosition() {
return "Преподаватель";
}
}
package com.javarush.test.level29.lesson15.big01.human;
import java.util.ArrayList;
import java.util.List;
public class University {
private String name;
private int age;
private List<Student> students = new ArrayList<>();;
public University(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
public University() {
}
public Student getStudentWithAverageGrade(double averageGrade) {
for (Student student : students) {
if (student.getAverageGrade() == averageGrade)
return student;
}
return null;
}
public Student getStudentWithMaxAverageGrade() {
int iMaxGrade = 0;
for (int i = 1; i < students.size(); i++) {
if (students.get(i).getAverageGrade() > students.get(iMaxGrade).getAverageGrade())
iMaxGrade = i;
}
return students.size() == 0 ? null : students.get(iMaxGrade);
}
public Student getStudentWithMinAverageGrade() {
int iMinGrade = 0;
for (int i = 1; i < students.size(); i++) {
if (students.get(i).getAverageGrade() < students.get(iMinGrade).getAverageGrade())
iMinGrade = i;
}
return students.size() == 0 ? null : students.get(iMinGrade);
}
public void expel(Student student) {
students.remove(student);
}
}
package com.javarush.test.level29.lesson15.big01.human;
/**
* Created by FarAway on 09.03.2016.
*/
public class UniversityPerson extends Human {
private University university;
public UniversityPerson(String name, int age) {
super(name, age);
}
public University getUniversity() {
return university;
}
public void setUniversity(University university) {
this.university = university;
}
}
package com.javarush.test.level29.lesson15.big01.human;
public class Worker extends Human{
private double salary;
private String company;
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public Worker(String name, int age)
{
super(name, age);
}
public void live() {
live();
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
package com.javarush.test.level29.lesson15.big01.user;
/**
* Created by FarAway on 10.03.2016.
*/
public class Address {
private String country;
private String city;
private String house;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getHouse() {
return house;
}
public void setHouse(String house) {
this.house = house;
}
}
package com.javarush.test.level29.lesson15.big01.user;
public class User {
private String name;
private String surname;
private int age;
private boolean man;
private Address address;
private Work work;
public User(String name, String surname, int age) {
this.name = name;
this.surname = surname;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCountry() {
return address.getCountry();
}
public void setCountry(String country) {
address.setCity(country);
}
public String getCity() {
return address.getCity();
}
public void setCity(String city) {
address.setCity(city);
}
public String getAddress() {
return address.getCountry() + " " + address.getCity() + " " + address.getHouse();
}
public Work getWork() {
return work;
}
public void setWork(Work work) {
this.work = work;
}
public boolean isMan() {
return man;
}
public void setMan(boolean man) {
this.man = man;
}
public void printInfo() {
System.out.println("Имя: " + getName());
System.out.println("Фамилия: " + getSurname());
printAdditionalInfo();
}
public void printAdditionalInfo() {
if (getAge() < 16)
System.out.println("Пользователь моложе 16 лет");
else
System.out.println("Пользователь старше 16 лет");
}
public String getBoss() {
return getWork().getBoss();
}
}
package com.javarush.test.level29.lesson15.big01.user;
public class UserHelper {
private User userAnya = new User("Аня", "Смирнова", 10);
private User userRoma = new User("Рома", "Виноградов", 30);
public void printUsers() {
userAnya.printInfo();
userRoma.printInfo();
}
public int calculateAvarageAge() {
User userUra = new User("Юра", "Карп", 28);
return (userAnya.getAge() + userRoma.getAge() + userUra.getAge()) / 3;
}
public double calculateRate(double base, int age, boolean hasWork, boolean hasHouse) {
double result = base;
result += age / 100;
result *= hasWork ? 1.1 : 0.9;
result *= hasHouse ? 1.1 : 0.9;
return result;
}
public String getBoosName(User user) {
return user.getBoss();
}
}
package com.javarush.test.level29.lesson15.big01.user;
public class Work {
private String boss;
public String getBoss() {
return boss;
}
public void setBoss(String boss) {
this.boss = boss;
}
}
Задание 15.
Отлично. Ты освоил основные методы рефакторинга: Подъём поля, Подъём метода,
Инкапсуляция коллекции, Извлечение подкласса, Подъём тела конструктора, Спуск
метода, Спуск поля, Извлечение интерфейса, Свёртывание иерархии, Замена наследования
делегированием, Извлечение суперкласса, Замена простого поля объектом, Создание
шаблонного метода, Замена делегирования наследованием, Переименование метода,
Замена параметра набором специализированных методов, Добавление параметра,
Удаление параметра, Разделение запроса и модификатора, Параметризация метода,
Передача всего объекта, Замена параметра вызовом метода, Замена параметров
объектом, Удаление сеттера, Сокрытие метода, Замена исключения проверкой условия,
Удаление управляющего флага, Самоинкапсуляция поля, Замена поля-массива объектом,
Инкапсуляция поля, Замена кодирования типа классом, Замена конструктора фабричным
методом, Замена кода ошибки исключением, Разбиение условного оператора,
Объединение условных операторов, Объединение дублирующихся фрагментов в условных
операторах, Замена магического числа символьной константой, Замена условного
оператора полиморфизмом, Извлечение метода, Встраивание метода, Перемещение
метода, Расщепление переменной, Удаление присваиваний параметрам, Перемещение
поля, Извлечение класса, Встраивание класса и Сокрытие делегирования.
Конечно есть еще и другие, обязательно ознакомься и с ними. Очень важно не только
уметь применять методы рефакторинга, но и видеть места, где их нужно применить. По
мере возрастания опыта, такие места будет все проще и проще находить. Мартин Фаулер в
своей книге "Рефакторинг: Улучшение существующего кода" называет такие места "код с
душком". Обязательно прочитай про основные варианты "кода с душком". Желаю, чтобы
твой код пах хорошо!
***************************************************************************************
Задание 14.
14.1. Перемещение поля. Замени поля isManAnya и isManRoma полем man в нужном классе.
Добавь сеттер и геттер для нового поля (при выборе имен методов учти тип поля).
14.2. Извлечение класса.
14.2.1. Добавь класс Address в пакет user.
14.2.2. Перенеси поля country, city и house в новый класс.
14.2.3. Добавь сеттеры и геттеры для них.
14.2.4. Перепиши класс User, используя поле класса Address address.
14.3. Встраивание класса. Класс House почти ничего не делает, избавься от него.
14.4. Сокрытие делегирования.
14.4.1. Добавь в класс User метод getBoss().
14.4.2. Перепиши реализацию метода getBoosName(User user) класса UserHelper.
***************************************************************************************
Задание 13.
Разберись с кодом пакета user (пользователь).
13.1. Извлечение метода. Добавь метод printInfo(), который будет выводить имя и фамилию
в консоль так же, как это делается в методе printUsers(). Замени повторяющийся код
метода printUsers() его вызовом.
13.2. Встраивание метода. Избавься от метода ageLessThan16().
13.3. Перемещение метода. Перемести методы printInfo() и printAdditionalInfo() в класс User.
13.4. Расщепление переменной. Переменная age в методе calculateAvarageAge()
используется для разных промежуточных значений. Перепиши метод без использования
этой переменной.
13.5. Удаление присваиваний параметрам. Перепиши метод calculateRate(), чтобы он не
пытался менять входные параметры, а просто возвращал рассчитанное значение.
***************************************************************************************
Задание 12.
12.1. Объединение условных операторов.
12.1.1. Добавь внутренний метод, сообщающий, могут ли быть перевезены пассажиры
boolean canPassengersBeTransferred() в класс Car. Метод должен возвращать true, если
водитель доступен isDriverAvailable и есть топливо fuel.
12.1.2. Перепиши метод getNumberOfPassengersCanBeTransferred(), объединив условные
операторы (используй метод canPassengersBeTransferred()).
12.2. Объединение дублирующихся фрагментов в условных операторах. Перепиши метод
startMoving(), чтобы в нем не было повторяющихся вызовов функций.
12.3. Замена магического числа символьной константой. Замени магические числа в методе
getMaxSpeed() на константные переменные метода: MAX_TRUCK_SPEED,
MAX_SEDAN_SPEED и MAX_CABRIOLET_SPEED.
12.4. Замена условного оператора полиморфизмом.
12.4.1. Переопредели метод getMaxSpeed() в подклассах, избавившись от условного
оператора.
12.4.2. Метод getMaxSpeed() в классе Car сделай абстрактным.
***************************************************************************************
Задание 11.
11.1. Замена кода ошибки исключением. Перепиши метод заправиться fill(double
numberOfLiters), чтобы он в случае ошибки кидал исключение Exception.
11.2. Разбиение условного оператора.
11.2.1. Добавь и реализуй метод в классе Car, определяющий относится ли переданная дата к
лету: boolean isSummer(Date date , Date summerStart, Date summerEnd).
11.2.2. Добавь и реализуй метод, рассчитывающий расход топлива зимой: double
getWinterConsumption(int length).
11.2.3. Добавь и реализуй метод, рассчитывающий расход топлива летом: double
getSummerConsumption(int length).
11.2.4. Перепиши метод getTripConsumption(), используя новые методы.
***************************************************************************************
Задание 10.
Разберись с кодом в пакете car (машина).
10.1. Замена конструктора фабричным методом.
10.1.1. Объяви классы Truck (грузовик), Sedan (седан) и Cabriolet (кабриолет), унаследованные
от Car.
10.1.2. Добавь в них конструкторы, принимающие int numberOfPassengers.
10.1.3. Добавь фабричный статический метод Car create(int type, int numberOfPassengers) в
класс Car.
10.1.4. Измени область видимости конструктора класса Car.
***************************************************************************************
Задание 9.
9.1. Самоинкапсуляция поля. Перепиши метод incAverageGrade() используя сеттер и геттер для
доступа к averageGrade.
9.2. Замена поля-массива объектом. Замени массив int[] size. Объектом нового типа Size,
содержащим публичные поля: рост int height и вес int weight. Публичный класс Size объяви
внутри класса Human.
9.3. Инкапсуляция поля. Сокрой поле company в классе Worker. Добавь сеттер и геттер для
него.
9.4. Замена кодирования типа классом.
9.4.1. Объяви публичный класс группы крови BloodGroup внутри пакета human.
9.4.2. Добавь в класс BloodGroup константное поле int code, приватный конструктор,
принимающий int и инициализирующий поле code, геттер для поля класса.
9.4.3. Добавь в класс BloodGroup статические методы first(), second(), third() и fourth(),
создающие и возвращающие объекты типа BloodGroup с правильным кодом внутри (1,
2, 3 и 4 соответственно).
9.4.4. Примени в классе Human новый тип BloodGroup.
***************************************************************************************
Задание 8.
8.1. Удаление сеттера. Удали метод setId(). Поле id должно устанавливаться только в момент
создания объекта.
8.2. Сокрытие метода (поля). Изменить область видимости поля nextId в соответствии с
областью его использования.
8.3. Замена исключения проверкой условия. Перепиши метод removeStudent(int index), чтобы
он удалял студента из списка студентов только, если он там есть. Метод не должен кидать
исключение.
8.4. Удаление управляющего флага. Перепиши метод findDimaOrSasha(), сохранив логику его
работы. В методе не должны использоваться флаги типа found, воспользуйся оператором
break.
***************************************************************************************
Задание 7.
7.1. Параметризация метода. Замени методы incAverageGradeBy01() и incAverageGradeBy02()
одним методом incAverageGrade(double delta).
7.2. Передача всего объекта. Перепиши метод addInfoAboutStudent(), чтобы он в качестве
параметра принимал объект типа Student.
7.3. Замена параметра вызовом метода. Перепиши метод printInfoAboutStudent(), чтобы он не
требовал в качестве параметра имя студента, а получал его, вызвав соответствующий
метод у переданного объекта.
7.4. Замена параметров объектом. Перепиши методы setBeginningOfSession и setEndOfSession,
чтобы они вместо набора параметров принимали по одному объекту даты.
***************************************************************************************
Задание 6.
6.1. Замена параметра набором специализированных методов. Замени метод setValue() класса
Student специализированными методами setCourse и setAverageGrade.
6.2. Добавление параметра. Добавить параметр с типом double в метод
getStudentWithAverageGrade(), чтобы было понятно с каким средним балом нужен студент.
Реализуй метод getStudentWithAverageGrade().
6.3. Удаление параметра. Убери параметр из метода getStudentWithMaxAverageGrade().
Реализуй этот метод, он должен возвращать студента с максимальным средним балом.
6.4. Разделение запроса и модификатора. Раздели метод
getStudentWithMinAverageGradeAndExpel на Student getStudentWithMinAverageGrade() и
void expel(Student student). Первый метод должен возвратить студента с
минимальным средним балом, а второй - отчислить переданного студента (удалять из
списка students).
***************************************************************************************
Задание 5.
5.1. Создание шаблонного метода.
5.1.1. Добавь в класс Human метод String getPosition(), который должен возвращать строку
"Человек".
5.1.2. Переопредели этот метод в классе Student и Teacher. Метод должен возвращать
"Студент" и "Преподаватель".
5.1.3. Замени метод printData в подклассах шаблонным методом в базовом классе,
использующим getPosition().
5.2. Замена делегирования наследованием. Класс Worker должен наследоваться от Human, а
не содержать его.
5.3. Переименование метода. Переименуй метод setSlr, чтобы было понятно сеттером чего
является этот метод.
***************************************************************************************
Задание 4.
4.1. Замена наследования делегированием.
4.1.1. Класс University не должен наследоваться от Student.
4.1.2. Класс University должен содержать список students.
4.1.3. Добавь сеттер и геттер для students.
4.1.4. Университет имеет название и возраст. Добавь необходимые поля, сеттеры и геттеры
для них.
4.2. Извлечение суперкласса.
4.2.1. Создай класс UniversityPerson в пакете human.
4.2.2. Перенеси в него поле university.
4.2.3. Перенеси сеттер и геттер для поля university.
4.2.4. Унаследуй необходимые классы от UniversityPerson.
4.3. Замена простого поля объектом. Измени тип поля university на University.
***************************************************************************************
Задание 3.
3.1. Спуск поля. Спусти поле course в соответствующий класс. Сделай его приватным.
3.2. Спуск метода. Спусти геттер для поля course в соответствующий класс.
3.3. Извлечение интерфейса.
3.3.1. Создай интерфейс Alive (живой) в пакете human.
3.3.2. Интерфейс должен содержать метод жить live().
3.3.3. Добавь интерфейс нужному классу.
3.4. Свёртывание иерархии. Избавься от класса Professor.
***************************************************************************************
Задание 2.
2.1. Извлечение подкласса.
2.1.1. Добавь класс Soldier в пакет human.
2.1.2. Избавься от поля isSoldier.
2.1.3. Перенеси в Soldier необходимые методы из Human.
2.1.4. Обновить сигнатуру конструктора Human.
2.2. Подъём тела конструктора.
2.2.1. Перенеси инициализацию полей name и age в подходящее место, добавь
необходимые параметры в конструктор Human.
2.2.2. Добавь конструктор в класс Soldier.
***************************************************************************************
Задание 1.
Пришло время немного порефакторить. Википедия говорит: "Рефакторинг (англ. refactoring)
или реорганизация кода - процесс изменения внутренней структуры программы, не
затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы. В
основе рефакторинга лежит последовательность небольших эквивалентных (то есть
сохраняющих поведение) преобразований. Поскольку каждое преобразование маленькое,
программисту легче проследить за его правильностью, и в то же время вся
последовательность может привести к существенной перестройке программы и улучшению её
согласованности и четкости." Такими маленькими преобразованиями мы и будем заниматься.
После каждого изменения следи за сохранностью работоспособности кода.
Многие методы рефакторинга не однократно применены и проверены сообществом
программистов. Получили свои названия. Каждое задание будет сопровождено названием
рефакторинга. Ты всегда можешь прочитать более подробно о нем в книге Мартина Фаулера
"Рефакторинг: Улучшение существующего кода".
Начнем. Внимательно ознакомься с кодом пакета human (человек). Задания:
1.1. Подъём поля. Подними поле children в базовый класс.
1.2. Подъём метода. Подними сеттер и геттер для children в базовый класс.
1.3. Инкапсуляция коллекции.
1.3.1. Метод getChildren должен возвращать не модифицируемое представление списка
children.
1.3.2. Убери сеттер для children.
1.3.3. Добавить методы addChild и removeChild.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment