Course program← Объектно ориентированное программирование
1История ООП
2Объект и Класс
3Базовые концепции ООП
4Принцип проектирования GRASP
5Принцип проектирования SOLID
6Паттерны GOF

High Cohesion (Высокая связность)

This lesson is not translated yet – the Russian original is below.

TODO: отвалидировать – текст собран автоматически из материалов курса на Google Drive, проверьте формулировки и код.

Класс должен выполнять как можно меньше не специфичных для него задач и иметь вполне определённую область применения.

Если модуль несёт много разноплановой ответственности, он сложнее в поддержке и переиспользовании, а меняться будет чаще остальных – по причинам, не связанным друг с другом.

// Низкая связность: класс занимается всем сразу
public class UserManager
{
    public void Register(User user) { }
    public void SendEmail(string to, string body) { }
    public string RenderProfileHtml(User user) => "";
    public void BackupDatabase() { }
}

// Высокая связность: каждый класс про одно
public class UserRegistration { public void Register(User user) { } }
public class EmailSender { public void Send(string to, string body) { } }
public class ProfileView { public string Render(User user) => ""; }
// Низкая связность: класс занимается всем сразу
class UserManager {
public:
    void Register(const User& user) {}
    void SendEmail(const std::string& to, const std::string& body) {}
    std::string RenderProfileHtml(const User& user) { return ""; }
    void BackupDatabase() {}
};

// Высокая связность: каждый класс про одно
class UserRegistration {
public:
    void Register(const User& user) {}
};

class EmailSender {
public:
    void Send(const std::string& to, const std::string& body) {}
};

class ProfileView {
public:
    std::string Render(const User& user) { return ""; }
};
// Низкая связность: тип занимается всем сразу
type UserManager struct{}

func (UserManager) Register(user User)              {}
func (UserManager) SendEmail(to, body string)       {}
func (UserManager) RenderProfileHTML(u User) string { return "" }
func (UserManager) BackupDatabase()                 {}

// Высокая связность: каждый тип про одно
type UserRegistration struct{}

func (UserRegistration) Register(user User) {}

type EmailSender struct{}

func (EmailSender) Send(to, body string) {}

type ProfileView struct{}

func (ProfileView) Render(user User) string { return "" }
# Низкая связность: класс занимается всем сразу
class UserManager:
    def register(self, user: User) -> None: ...
    def send_email(self, to: str, body: str) -> None: ...
    def render_profile_html(self, user: User) -> str: ...
    def backup_database(self) -> None: ...

# Высокая связность: каждый класс про одно
class UserRegistration:
    def register(self, user: User) -> None: ...

class EmailSender:
    def send(self, to: str, body: str) -> None: ...

class ProfileView:
    def render(self, user: User) -> str: ...
// Низкая связность: класс занимается всем сразу
class UserManager {
    register(user: User): void {}
    sendEmail(to: string, body: string): void {}
    renderProfileHtml(user: User): string {
        return "";
    }
    backupDatabase(): void {}
}

// Высокая связность: каждый класс про одно
class UserRegistration {
    register(user: User): void {}
}

class EmailSender {
    send(to: string, body: string): void {}
}

class ProfileView {
    render(user: User): string {
        return "";
    }
}
// Низкая связность: класс занимается всем сразу
public class UserManager {
    public void register(User user) { }
    public void sendEmail(String to, String body) { }
    public String renderProfileHtml(User user) { return ""; }
    public void backupDatabase() { }
}

// Высокая связность: каждый класс про одно
public class UserRegistration {
    public void register(User user) { }
}

public class EmailSender {
    public void send(String to, String body) { }
}

public class ProfileView {
    public String render(User user) { return ""; }
}
// Низкая связность: класс занимается всем сразу
class UserManager {
    fun register(user: User) = Unit
    fun sendEmail(to: String, body: String) = Unit
    fun renderProfileHtml(user: User): String = ""
    fun backupDatabase() = Unit
}

// Высокая связность: каждый класс про одно
class UserRegistration {
    fun register(user: User) = Unit
}

class EmailSender {
    fun send(to: String, body: String) = Unit
}

class ProfileView {
    fun render(user: User): String = ""
}

Проверка на связность

Попробуйте описать, чем занимается класс, одним предложением без союза «и». Если не получается – связность низкая.

Обратите внимание на пару с предыдущим принципом: High Cohesion и Low Coupling дополняют и поддерживают друг друга, а все остальные принципы GRASP по сути служат тому же – уменьшить зацепление и увеличить связность.