セッターとゲッターは常に単一責任の原則を破りますか?


8

私たちが知っているように、SRPはすべてのクラスが単一の責任を持つべきであり、その責任はクラスによって完全にカプセル化されなければならないことを述べています。

しかし、セッターとゲッターは別の責任を果たします -それらは抽象クラスのプロパティ(データ)アクセスを行います。

場合セッターとゲッターは、抽象クラスのプロパティへのアクセスを行う、その後、彼らは別の責任を果たす行います

だから私がこのようなものを持っているなら、

class Config
{

    private location;


    public function write(array $data)
    {
        ....
    }

    public function read($key)
    {
        ...
    }

    public function exists($key)
    {
        ...
    }

    public function delete($key)
    {
        ...
    }

    // Below comes property abstraction

    // Here I doubt - I CANNOT USE this class without them
    // but they seem to break the SRP at the same time!?

    public function setFileLocation($location)
    {
        $this->location = $location;
    }


    public function getFileLocation()
    {
        return $this->location;
    }


    public function setConfigArray(...)
    {
        ...
    }

    public function getConfigArray()
    {
        ...
    }
}

私はSRPを壊します。問題は、それがクラスが存在する唯一の方法であることです。

だから問題は、

私の状況では、CRUD setFileLocation()getFileLocation()使用する方法を回避することはほとんど不可能です。

したがって、CRUDメソッドとデータアクセス抽象化を組み合わせることにより、SRPを壊す場合、

SRPを遵守し、同時にConfigクラスの共通の概念(CRUD操作)を維持する方法はありますか?


1
@metal_fan:パブリックメンバーがある場合、または自明なパブリックゲッターとセッターを持つプライベートメンバーがある場合は、機能がまったく同じになります。そして、私はまったく同じように言っています。それらを使用すると、内部の不変式が壊れるかどうかに応じて。
Jan Hudec 2013

1
これらの構成値を格納および取得するための集中化された場所を提供しない場合、構成クラスの責任は何ですか?すべてのデータベースでSRPが壊れていますか?リンクする例では、2つの責任があります。1つはゲッターとセッター、2つはCRUDです。投稿する例ではCRUDがないため、責任は1つだけです。
Trylks 2013

あなたは本当と本当を混同しました。」-サミュエル・R・デラニーが引用した会話中のジョージ・スタンリー

回答:


11

正直なところ、あなたは単一責任の概念を少しだけ受けすぎていると思います。ゲッターとセッターは、パブリックメンバーに直接アクセスするか、メソッド(またはプロパティ)を使用してそれを行うかに関係なく、クラスの機能に付随しています。

クラスの一部のメンバーを取得および設定することは別の責任であるため、別の場所に移動する必要があるという主張をしています。それを行うとしましょう。これで、クラスとが呼び出さConfigれましたConfigAccessor。この時点で、メンバーConfigにアクセスするためのインターフェースがないため、2つのクラスの間にエアギャップができましたlocation。そのためConfigAccessor、を書くことが不可能になり、まったく役に立たない不変の1回限りのクラスが残ります。ある種のインターフェースを追加ConfigAccessorしてその機能を実行できるようにすると、再帰的な問題が発生します。

この分野の他の多くのものと同様に、SRPは原則であり、厳格な規則ではありません。つまり、無条件に追跡するのではなく、状況に判断を適用する必要があります。純粋主義者であることと仕事を成し遂げることの間には線があり、前者が後者を妨げているとき、あなたはそれの間違った側にいます。

あなたの設計を少し批判できる場合:Configクラスがディスクに格納された構成ファイルとコードの間のインターフェイスになるように設計されている場合、最後に行うことは、その位置を途中で変更することです。location別のファイルへのアクセスを開始する方法としてを変更する場合は、古いオブジェクトを破棄して新しいオブジェクトを作成する必要があります。ファイルの内容をオブジェクトに格納するかどうかは明確ではありませんでした。ある構成ファイルの内容を吸い込んで別の構成ファイルに書き込む方法として使用する場合は、新しいファイルを指す新しいオブジェクトにデータを複製するメソッドの使用を検討してください。


4

SRPを適用できるレベルは2つあります。

最初のレベルは、個々の関数/メソッドのレベルです。それぞれが1つのタスクのみを実行する必要があります(メソッド名で判断するとConfig、SRPを中断するメソッドはありません)。

第2レベルはクラスのレベルです。ここで、単一の責任の概念は少し抽象的になりますが、単語を(暗黙的に)使用せずにクラスの責任を1つの文で述べることができるかどうかは、良い指標です。ゲッターとセッターの存在でそれができる場合、クラスはSRPを壊しません。

ただし、一般に、ゲッターと、それよりは少ないがセッター、クラスのカプセル化が壊れていることを示しています。Configクラスの場合、データがどこにあるかを知るために何らかの方法が必要setFileLocationなので、メソッドは優れていConfigますが、他のユーザーはConfig必要としないはずの情報を公開するため、疑わしいようです。


4

構成クラスには、特定のデータへのプライベート参照を保持し、ミューテーターメソッドを介してそれらへのアクセスを提供することによって実装される構成を追跡する責任があります。クラス自体が単一の責任を持つためこれはSRPを壊しません。ミューテーターは、データへのアクセスを抽象化することで、その責任を果たすのを支援します。ミューテーターには、クラスの責任とは別の責任はありません。それらはクラスのより大きな責任の一部です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.