Может ли кто-нибудь привести мне пример принципа единой ответственности? Я пытаюсь понять, что на практике означает, что класс несет единственную ответственность, поскольку боюсь, что, вероятно, нарушаю это правило каждый день.
Каков пример принципа единой ответственности?
Ответы (3)
Ознакомьтесь с подробным описанием.
Если вы не попросите чего-то более конкретного, вам будет трудно помочь.
Единая ответственность - это концепция Класса, который выполняет одну конкретную вещь (ответственность) и не пытается сделать больше, чем должен, что также называется высокой сплоченностью.
Классы не часто начинаются с Low Cohesion, но обычно после нескольких выпусков и добавления к ним разных разработчиков вы внезапно заметите, что он стал классом монстра или Бога, как некоторые его называют. Итак, класс следует реорганизовать.
Трудно придумать хороший пример, но я могу вспомнить, что недавно был класс, который у нас есть, который управляет различными этапами обработки пакетов, тип Chain of Responsibility
. Первоначальная цель этого класса состояла в том, чтобы поддерживать список этапов и организовывать для них вызов packetProcess (). Что ж, в итоге все добавили что-либо, связанное со стадиями обработки (поскольку класс менеджера был легким местом для доступа к стадиям) в этот класс менеджера, особенно конфигурацию стадии. У класса менеджера больше не было единой ответственности, но вместо этого он также отвечал за вызовы этапов для изменения конфигурации: таким образом, сплоченность была уменьшена.
В итоге нам пришлось провести рефакторинг класса менеджера, вырвав всю конфигурацию стадии и поместив ее в фабрику, оставив менеджера делать то, что он должен был делать.
Самый эффективный способ сломать приложения - создать классы GOD. Это классы, которые отслеживают большой объем информации и имеют несколько обязанностей. Одно изменение кода, скорее всего, повлияет на другие части класса и, следовательно, косвенно на все другие классы, которые его используют. Это, в свою очередь, приводит к еще большему беспорядку при обслуживании, поскольку никто не решается вносить какие-либо изменения, кроме добавления к нему новых функций.
Следующий пример - это класс TypeScript, который определяет Person
, этот класс не должен включать проверку электронной почты, потому что это не связано с поведением человека:
class Person {
public name : string;
public surname : string;
public email : string;
constructor(name : string, surname : string, email : string){
this.surname = surname;
this.name = name;
if(this.validateEmail(email)) {
this.email = email;
}
else {
throw new Error("Invalid email!");
}
}
validateEmail(email : string) {
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(email);
}
greet() {
alert("Hi!");
}
}
Мы можем улучшить приведенный выше класс, сняв ответственность за проверку электронной почты с класса Person и создав новый класс Email
, который будет нести эту ответственность:
class Email {
public email : string;
constructor(email : string){
if(this.validateEmail(email)) {
this.email = email;
}
else {
throw new Error("Invalid email!");
}
}
validateEmail(email : string) {
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(email);
}
}
class Person {
public name : string;
public surname : string;
public email : Email;
constructor(name : string, surname : string, email : Email){
this.email = email;
this.name = name;
this.surname = surname;
}
greet() {
alert("Hi!");
}
}
Убедившись, что класс несет единственную ответственность, по умолчанию также легче увидеть, что он делает и как вы можете его расширить / улучшить.
У класса должна быть только одна причина для изменения.
Этот принцип гласит, что если у нас есть 2 причины для изменения класса, мы должны разделить функциональность на два класса. Каждый класс будет обрабатывать только одну ответственность, и если в будущем нам понадобится внести одно изменение, мы сделаем это в классе, который его обрабатывает.
Если есть две разные причины для изменения, вполне возможно, что две разные команды могут работать над одним и тем же кодом по двум разным причинам. Каждому придется развернуть свое решение, что в случае компилируемого языка (например, C ++, C # или Java) может привести к несовместимости модулей с другими командами или другими частями приложения.
Этот принцип тесно связан с концепциями сцепления и сплоченности. Связность относится к тому, насколько неразрывно связаны различные аспекты приложения, в то время как согласованность относится к тому, насколько тесно может быть связано содержимое определенного класса или пакета. Все содержимое одного класса тесно связано друг с другом, поскольку сам класс является [единым модулем] [1], который должен либо использоваться полностью, либо не использоваться вовсе.
Моя запись в блоге об этом:
http://javaexplorer03.blogspot.in/2016/12/single-responsibility-principle.html