Недоречна близькість

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Недоречна близькість (англ. 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";
    }
}

Переваги[ред. | ред. код]

  • Покращення організації коду;
  • Спрощення технічної підтримки і повторного використання коду.

Див. також[ред. | ред. код]

Посилання[ред. | ред. код]