42

誰かが単一責任の原則の例を教えてもらえますか? 私はおそらく毎日この規則を破るのではないかと恐れているので、実際には、クラスが単一の責任を持つことが何を意味するのかを理解しようとしています。

4

3 に答える 3

53

アプリケーションを破壊する最も効果的な方法は、GODクラスを作成することです。これらは、多くの情報を追跡し、いくつかの責任を持つクラスです。1 つのコード変更がクラスの他の部分に影響を与える可能性が高く、そのため、それを使用する他のすべてのクラスに間接的に影響を与えます。これは、新しい機能を追加する以外に変更を加えようとする人がいないため、さらに大きなメンテナンスの混乱につながります。

次の例は、 を定義する 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!");
    }
}

クラスに単一の責任があることを確認すると、デフォルトごとに、その機能と、それを拡張/改善する方法を簡単に確認できます。

于 2015-04-03T15:21:22.980 に答える
7

ソリッドの説明を確認してください。

より具体的なことを求めない限り、これ以上の支援は難しいでしょう。

単一の責任とは、クラスが 1 つの特定のこと (責任) を実行し、必要以上のことをしようとしないという概念であり、高い結束力とも呼ばれます。

クラスが低結束で始まることはあまりありませんが、通常、いくつかのリリースとさまざまな開発者がそれらに追加した後、突然、それがモンスターまたは神クラスと呼ばれるようになったことに気付くでしょう。したがって、クラスをリファクタリングする必要があります。

良い例を思いつくのは難しいですが、最近思いつくのは、さまざまなパケット処理段階を管理するクラスで、Chain of Responsibility. このクラスの最初の目的は、ステージのリストを維持し、それらで packetProcess() の呼び出しを調整することでした。結局、誰もが処理ステージに関係するものを (マネージャー クラスはステージにアクセスするのに簡単な場所だったので) このマネージャー クラス、特にステージ構成に追加することになりました。マネージャー クラスには単一の責任がなくなりましたが、代わりに、構成変更のためにステージへの呼び出しを行う責任もありました。したがって、結束力が低下していました。

最終的にはマネージャー クラスをリファクタリングする必要があり、すべてのステージ構成を取り除いてそれをファクトリに配置したため、マネージャーは意図したとおりに実行する必要がありました。

于 2012-05-16T13:55:06.360 に答える