Недоречна близькість (англ. Inappropriate Intimacy) — один із «запахів коду», тобто код із ознаками проблем у системі. Суть «запаху» полягає у тому, що один клас використовує службові поля і методи іншого класу. Для уникнення недоречної близькості між класам потрібно пам'ятати, що класи повинні знати один про одного якомога менше. Такі класи легше підтримувати і повторно використовувати
Проблема
License у методі GetSummary() використовує методи об'єкта motorist, Motorist у методі getRiskFactor() використовує методи об'єкта license (приклад коду на Java)
public class License {
private Motorist motorist;
private int points = 0;
public void setMotorist (Motorist motorist) {
this.motorist = motorist
}
public int getPoints() {
return points;
}
public void addPoints(int points) {
this.points +=points;
}
public String getSummary() { // includes information about motorist (method in the wrong place)
return motorist.getTitle() + " " + motorist.getFirstName() + " "
+ motorist.getSurname() + ", " + Integer.toString(getPoints()) + " points";
}
}
public class Motorist {
public final License license;
private final String surname;
private final String firstName;
private final String title;
public Motorist (License license, String surname, String firstName, String title) {
license.setMotorist(this);
this.license = license;
this.surname = surname;
this.firstName = firstName;
this.title = title;
}
public String getSurname() {
return surname;
}
public String getFirstName {
return firstName;
}
public String getTitle() {
return Title
}
public String getRiskFactor() { // risk factor is calculated using the number of points from the license (method in the wrong place)
if (license.getPoints() > 3)
return "HIGH_RISK";
if (license.getPoints() > 0)
return "MODERATE_RISK";
return "LOW_RISK";
}
}
Лікування
- Найпростіший вихід за допомогою переміщення методу і переміщення поля перенести частини одного класу в інший (в той, де вони використовуються). Проте це може спрацювати тільки в тому випадку, якщо оригінальний клас не використовує переміщувані поля і методи.
- Іншим рішенням є відокремлення залежних частин в окремий клас і приховання делегування до цього класу.
- Якщо між класами існує взаємна залежність, варто використати заміну двонаправленого зв'язку на однонапрямлену.
- Якщо близькість виникає між підкласом і батьківським класом, краще розглянути можливість заміни делегування наслідуванням.
Належне лікування для попереднього приладу:
public class License {
private int points = 0;
public int getPoints() {
return points;
}
public void addPoints(int points) {
this.points +=points;
}
public RiskFactor getRiskFactor() {
if (getPoints() > 3)
return "HIGH_RISK";
if (getPoints() > 0)
return "MODERATE_RISK";
return "LOW_RISK";
}
}
public class Motorist {
public final License license;
private final String surname;
private final String firstName;
private final String title;
public Motorist (License license, String surname, String firstName, String title) {
this.license = license;
this.surname = surname;
this.firstName = firstName;
this.title = title;
}
public String getSurname() {
return surname;
}
public String getFirstName {
return firstName;
}
public String getTitle() {
return Title
}
public String getSummary() { // includes information about Motorist
return getTitle() + " " + getFirstName() + " " + getSurName() + ", " + license.getPoints() + " points";
}
}
Переваги
- Покращення організації коду;
- Спрощення технічної підтримки і повторного використання коду.
Див. також
Посилання