web-dev-qa-db-ja.com

抽象クラスでプロパティを宣言して設定することは良い習慣ですか?

PHPを使用して、いくつかの抽象クラスを設計しています。

抽象クラス内で定数値を使用してプロパティを宣言し、拡張クラス内で再宣言せずに、これを拡張する任意のクラスからプロパティにアクセス/上書きできます。

これの利点は、繰り返し入力が少なくなることですが、これらの抽象プロパティの元の構造/レイアウトが時間の経過とともに忘れられ、デフォルトの静的値のままにするか、完全に忘れる(使用しない)場合があるという欠点があります。

これはプロの環境でどのように処理されますか?これは以前に考え抜かれたことがあり、支持されているのではないかと思います。

私は良いOOP SOLID、DRY and KISSなどの原則/ルールを遵守していますこれらの中で話題になっているこの特定の問題を見た(おそらく、調査中にそれを逃したのだろうか?)

4
cecilli0n

これは個人的な好みかもしれませんが、基本クラス目的のためにプロパティを共有することは避けます。特にデータクラスで。繰り返しは気にしません。クラスを固定された「データ」階層にロックすることは避けます。

特にコードベースが大きくなるにつれて、継承に関する十分な問題があり、クラス階層を通じてメソッドを共有することに消極的になり、クラス階層を通じてプロパティを共有することにさらに消極的になります。

...

うーん。 「静的な」プロパティについて言及していることに気づきました。基本クラスの静的(つまり、グローバル)プロパティではなく、ファクトリによってディスペンスされたものの個別の単一インスタンスを使用するほうがよいでしょう。競合状態を回避するために、並行性を提供するようにしてください。

2
Rob

あなたの質問に答えるために、はい。抽象クラスがプロパティの論理的な場所である場合は、そこに配置します。クラスとOOPが提供するツールを使用します。

「時間が経過すると、これらの抽象プロパティの元の構造/レイアウトは忘れられ、デフォルトの静的値のままにするか、完全に忘れる(使用しない)ことさえあります。」

これは、抽象クラスまたは子クラスを使用/作成する開発者がこれらのプロパティで何かを行う必要があることを私に示唆しています。それが本当なら、開発者にこれに対処するように強制するクラス設計を考え出すようにしてください。それは誰もが常に正しくそれを行うことを信頼するより良いです。

静的な値の変更について言及しています。静的プロパティはすべてのクラスインスタンス間で共有されるため、1つのオブジェクトの値を変更することで、すべてのオブジェクトの値を変更できます。グローバル状態を変更する複数のオブジェクトは、すべての変更を正しい順序で維持することが難しいため、回避したいものです。

0
Kwebble

継承を浅く保つ場合( lasagna の反対)、抽象クラスにプロパティを配置することに哲学的に問題はありません。結局のところ、言語はそれを可能にします。継承を浅く保つと、これらのプロパティが忘れられないようになります。

これについて真剣に検討したいのは、これらのプロパティを保護することだけです。クラスを継承すると、常に可視性が失われる可能性がありますが、それ以外の場合、ある時点でパブリックプロパティを保護されたプロパティにする必要がある場合は、うまくいきません。

抽象クラスを設計するときは、次のことを考えてみてください。

  • 物件はたくさんありますか?
  • これを継承するクラスはいくつありますか? 3? 15? 100?
  • 抽象メソッドを宣言していますか(部分的なインターフェース実装の残りなど)?
  • この抽象化は、2つ以上のその他の無関係なクラスを結び付けますか?

多くのクラスがそれから継承しないか、そうでなければ何も存在しない関係を作成する場合、トレイトで実行しようとしていることを実行できる可能性があります。

例はModelActiveRecordです。 「フォームvs機能」。

  • ActiveRecordは、CRUDインターフェースの足場/部分実装を提供できます(_$table_プロパティ、static::load($id)メソッドなど)。
  • Modelには組み込みのヘルパー関数または抽象validate()メソッドが含まれる場合があり、それ自体ではインスタンス化できません。
  • すべてのModelsActiveRecordsであるとは限りません。逆も同様です。

ActiveRecordは、アプリケーション全体に適用されるhorizo​​ntallyため、特性として最適です。一方、Modelsは明確な階層を持ち、抽象として最適に機能します。

0
R Y

これは 継承よりも構成を優先する の古典的な使用例です。一部のプロパティが密接に属している場合は、それらを独自のクラスに配置します。次に、必要なのは、場所全体でプロパティを繰り返すのではなく、そのクラスを参照する1つのプロパティだけです。その後、完全なクラス階層を取り除くことができます。

また、抽象クラスは動作を抽象化することを目的としています。ゲッターがクラスの動作である場合、ゲッターを持つ抽象クラスがあっても問題ない場合があります(セッターにも同じことが当てはまります)。しかし、動作の観点から見ると、同じ基本クラスの同じプロパティにゲッターとセッターを設定しても意味がありません。これは、動作の抽象化の余地がないためです。

0
SpaceTrucker