すべてのオブジェクトは自分自身を表示/描画する方法を知っている必要がありますか?


8

David Westは、著書Object Thinking(第10章、セクション1、サブセクション2)で、理想的なOO環境では、すべてのオブジェクトが要求に応じて自分自身を表示できる必要があると提案しました。人間向け(GUIとして)、非ネイティブコンポーネント(JSONやXMLとして)、またはその他の関係者向け:

オブジェクト思考は、ビュー(インターフェイスとも呼ばれます)は、グラフィックまたはその他の方法で、オブジェクトが別のオブジェクトと通信するための手段であり、それ以上のものではないと言います。ビューの必要性は、オブジェクトが他のオブジェクト(通常は人間)またはアプリケーション(たとえば、プラットフォーム間で共有されているデータオブジェクトのXMLビュー)に対して「非ネイティブ」形式で表示される必要がある場合に発生します。

ビューが満たす必要のあるニーズとパラメーターの発見は、オブジェクトが参加するシナリオで明らかになります。オブジェクトがそれ自体を表示するように要求されるときは常に、その表示メッセージの送信者に適したビュー(表現)を使用する必要があります。たとえば、オブジェクトがそれ自体をインスタンス化しようとしている(それ自体の値を取得している)場合、そのオブジェクトのビューを、人間(または他のサービス提供オブジェクト)に暗黙の要求として値を提示する必要があります。ソフトウェアオブジェクトと人間のオブジェクトの間の仲介役として機能するGUIを構築する場合は、表示用にグリフを使用し、対話用にウィジェットを使用します。

しかし、どのグリフとウィジェットをGUIに含める必要がありますか?アプリケーションの実行中に当面のシナリオのシナリオを完了するために必要なもののみ。この視点は、アプリケーションからGUIを定義することを示唆しているため、ほとんどの開発者にとって直観に反しています。

例として、醸造所を考えてみましょう。片側にはビールが入ったバットがあります。ボトルウォッシャー、フィラーステーション、キャッピングマシン、パッケージアセンブラーで構成される複雑な生産ライン。その上にあるのは、醸造所を監視し、人間の管理者にステータスと問題を通知するコントロールステーションです。従来の開発者は、コントロールパネルの観点から「醸造所管理システム」の分析と設計を開始する可能性があります。これは、インターフェースからの設計に似ています。

オブジェクト思考は、代わりに、どのオブジェクトが醸造所とそのすべての無数の機械の主要な顧客であるかを検討することを示唆します。誰のために、機器の複雑な迷路が存在しますか?ビジネスの正解は、もちろん「お客様」です。しかし、オブジェクトの考え方をより反映した答えは、「ビール」です。すべてのシナリオは、ビールの観点から書かれており、キャップを付けて、ボトルに入れられ、パッケージに入れられ、トラックに常駐しています。コントロールパネルは、醸造所の状態の受動的な観察者5です。ある時点でビールに問題が発生した場合、介入サービスを要求するメッセージをコントロールパネル(またはマシン固有のコントロールパネル)に送信することにより、オペレーターの介入を要求するのはビールの責任です。

このパースペクティブは、GUI設計を簡素化し、さらに重要なことに、コントロールパネル(GUI)のパースペクティブから設計するときに必然的に発生すると思われるマネージャーおよびコントローラーオブジェクトのホストを排除します。

オブジェクト指向の世界の初心者から来る:これは本当にそうでしょうか?

自分自身を表現する方法を知っているオブジェクトがあれば、ウェストが彼の本で繰り返し言ったコントローラー/マネージャーオブジェクトの数を減らすことができます。しかし、この「ルール」を守らないとSRPが破られますか?

また、(それが事実であることが判明した場合)、たとえばAndroidアプリケーションでの典型的な実装を考えると、どうすればこの種の目標を達成できるでしょうか?私たちが作成するすべてのオブジェクトは、それ自体をとして提示する方法を知っている必要がありViewますか?


3
SRPは、あなたが考えていることを意味するものではありません。SRPは、「車」オブジェクトがペットの問題を診断しないことを意味します。これは、ビジュアルUI要素がそれ自体を表示できないことを意味するものではありません。
Robert Harvey

そうですか。ただし、ビジュアルUI要素については言及します。ソフトウェアの設計にこのルールを適用すると、作成するオブジェクトの大部分はビジュアルUI要素になりますか?それらのほとんどは遅かれ早かれユーザーとの対話を要求するからですよね?
MrHadiSatrio

1
@RobertHarveyその引用がMVCタイプのパターンをサポートしていると見なすことができるかどうかはわかりません。MVCパターンでは、モデルはそれを表示するビューを無視するのに対し、そのインターフェース/「ビュー」を定義するのはクラスの責任であると言っているように見えます。
ベンアーロンソン

1
@ridsatrioあなたは自明の初心者なので...オブジェクトに何かをするように指示するメソッドではなく、コントロールの外で起こったことについてオブジェクトに伝えるために存在するインターフェースを書くように努力することをお勧めします。したがって、「buttonWasClicked」や「pageWillBeDisplayed」などのメソッドは、「changeState」や「​​drawInCorner」よりも優れています。「質問しないでください...」オブジェクトに物事を依頼するのではなく、何が起こっているかをオブジェクトに伝えます。
ダニエルT.16年

2
筆者は、ある時点で執筆をやめ、「瓶に入れたいビールについて話し、それができないときはオペレーターに伝えることで、実際にOOPについて人々に教えたいですか?」これがどのようにして概念やアイデアを誰にでも明らかにするはずだとは思わない。
Sebastian Redl 2016年

回答:


12

これはオブジェクト指向の設計について理解するのが最も難しいことの1つだと思います。正直に言って、多くの作者はそれについて間違っているか、十分に説明していないと思います。多くの人がこれを誤解し、実際に理解することはありません。GUIベースではないが、同じ落とし穴に遭遇する例を見てみましょう。

Javaでは、すべてのオブジェクトにequalsメソッドがあります。次に、このメソッドに依存するsetやmapなどのコレクション型があり、いつオブジェクトをコレクションに追加するか、またはオブジェクトを複製するかを決定します。これは多くの人にとって良いオブジェクト指向のようです。問題は、最終的にはオブジェクト(コレクション)であり、その動作はオブジェクトによってではなく、オブジェクトに含まれるオブジェクトによって決定されることです。これは、バスの乗客が行くべき場所に直接行くのと少し似ています。彼らが同意しない場合はどうなりますか?これは理論上の問題ではありません。プログラムのバグを防ぐために継承を基本的に解除しなければならないという厄介な問題です。ShapeとColoredShapeを取ります。2x2の正方形は2x2の青い正方形と同じですか?Shapeは「はい」、ColoredShapeは「いいえ」と言います。WHO' ね?答えは、コレクションで何をしたいかによって異なります。それはあなたが何をしようとしているのかに依存しません。

これは問題として何度も何度も発生します。面白いのは、解決策があり、それがComparableのすぐ隣にあるということです。Comparableを実装するオブジェクトにも同じ難問がありますが、それらが等しいかどうかだけでなく、別のオブジェクトよりも大きいかどうかを判断する必要があります。非常に狭い使用範囲の外では本当に扱いにくいものです。ですから、コンパレータと呼ばれるものがあります。2つのオブジェクトを見て、どちらが大きいかをコレクションに伝えるのが仕事です。Comparableオブジェクトでこれを実行しようとしていたすべての問題が消えます。

この本も作者もわかりませんが、ビールの例はまったく役に立ちません。ビールを瓶に入れるべきか、樽に入れるべきかをビールはどのようにして知るのでしょうか、そしてなぜそれを決定するのでしょうか?それは良い味をして、ユーザーの血流にアルコールを届けることです。私たちは本当に醸造所がこのように機能していると思いますか?「オーケービール、あなたはボトルまたは樽のどちらにいるべきですか、それがボトルの場合、25オンスのボトルまたは12オンスのボトルでなければなりませんか?」とにかく、この場合のビールは何ですか?ビール一滴?多分これは文脈外ですが、私はこれが間違っているか、少なくともこの概念に照明を追加していないと思います。

以上のことをすべて説明した上で、私が使用したインターフェースを構築する方法には、物事を簡素化してオブジェクト指向にするための方法があります。基本的に、オブジェクトを表示するために実行できる抽象アクションを定義するインターフェースを作成します。標準のJava命名パターンを使用している場合や、Displayメソッドと呼ばれるインターフェースがある場合があります。次に、オブジェクトにはメソッドがありますsetTitlesetDescriptiondisplay(Display display)(3回が魅力だからです!)このアプローチでは、オブジェクトはインターフェイスが何であるかを理解する必要はありません。テキスト、バイナリ、svg、ビットマップなど、インターフェイスはオブジェクトについて知る必要はありません。 。このようにして、オブジェクトは、表示がどのように機能するかを知る必要なく、「自身を表示」できます。この方法では、必要なラッパークラスの数を大幅に減らすことができますが、オブジェクトごとに異なる複雑な表示要件がある場合は、面倒なことがあります。これを標準のMVCタイプのアプローチと組み合わせて効果を上げることができます。


2
いい答えです。関連するすべての問題に関係していると思います。
Robert Harvey

これは確かに非常に良い答えです。考えてみてください。おそらく、定義されたインターフェースを介してオブジェクトが自分自身を描画できるようにする方法が、この問題に対する最善のアプローチです。このようにして、オブジェクトは(外部コントローラーではなく)表示方法を制御する権利を保持しますが、オブジェクトが具体的な実装でどのように機能するかを学習する必要はありませんDisplayJFrameたとえば、 )。ありがとう。
MrHadiSatrio 2016年

1
この回答は素晴らしく、一般的にOOPに多くのことを反映させています。データと機能を分離するために維持するのがはるかに簡単なECSであることがわかりました。これは、オブジェクトを使用して内部的に自分自身と比較する正しい動作を決定しようとするオブジェクトを使用して説明したものとの類似性の影響を受けないためです他の何か。

8

単一責任原則は、クラスが1つのことだけを行うことを意味するものではありません これは、クラスには変更する単一の理由があることを意味します。

あなたはおそらくメソッドを考えているでしょう。

これは論理的な結論ですが、ロギングは別の責任であるため、SRPのバージョンは何もログに記録できないことを意味します

クラスは、明確に定義された単一の主題と考える方がよいでしょう あなたはその主題をサポートするいくつかの方法を持つことができ、それらはすべて異なることをしている可能性があります。

最も基本的な「display me」メソッドはToStringであり、これは常にオブジェクトのメソッドです。


そうは言っても、UIを作成するときは、通常、他のオブジェクト(ビュー)からのデータを表示することだけを目的とするオブジェクトを提供することで、懸念の分離を促進します。

おそらく例が正しいでしょう。ビューを使用したPHP Webサイトについて考えてみましょう。単純なビューは次のようになります。

<?php
class View
{
    private $model;
    private $controller;

    public function __construct($controller,$model) {
        $this->controller = $controller;
        $this->model = $model;
    }

    public function output(){
        return "<p>" . $this->model->string . "</p>";
    }
}

PHPでは、ビューには常にoutput()関数が含まれています。 ビューの視覚的表現を取得するにはoutput()、を呼び出すだけで、最新のブラウザでの表示に適した文字列を取得できます。

気が付くと、ビューはというオブジェクトを参照しますmodel。これは、実際のデータを含むオブジェクトです。ビューとモデルは別のオブジェクトにあります。これが懸念の分離を確立するものです。

関心事の分離は、デザイナーがプログラマーとは別の Webページデザインで作業できるようにするため、Webサイトにとって重要です

さらに読書
ザ・MVCパターンとPHP


よし。しかし、ビューをモデルから分離した後も、ビューを提供するのはモデルの仕事ですか?それが私が上記の引用から得ているものだからです。オブジェクト(またはボキャブラリーのモデル)は、それ自体を表示する方法を知っているはずですよね?ある意味でReceiptは、典型的なPOSソフトウェアでオブジェクトを取得したとしても、を呼び出すのReceipt.draw(Canvas)ではなく、と呼びますReceiptView.draw(Receipt)
MrHadiSatrio 2016年

2
MVCでは、使用するビューを選択するコントローラーの責任です。
Robert Harvey

しかし、コントローラーオブジェクトは、オブジェクトシンキングにおけるWestの認識において(したがって、その引用において)避けるべきものとして正確に提示されているものです。引用は、「自分自身を表示する方法を知っているオブジェクト」の背後にある全体の考えが「マネージャーとコントローラーのオブジェクト」を避けることであると明確に述べています。
MrHadiSatrio 2016年

それは結構ですが、その考えを視覚的な表示のみを目的とするオブジェクトに限定する必要があると思います 言い換えれば、ビュー。コントローラは、ビューの表示方法を気にしません。使用するビューのみが考慮されます。また、MVCは唯一の可能な表示パラダイムではなく、他のもの(特にMVVM)は多少異なる動作をします。しかし、懸念分離の基本原則は残っています。
Robert Harvey

あなたが読んでいる本はソフトウェアの本(2004年)のためにかなり古いことに注意してください。MVCとMVVMはまだ一般的には使用されていませんでした。
Robert Harvey

1

貼り付けた引用から判断すると、テキストを誤って解釈しています。

著者は、すべてのオブジェクトがUIで自分自身を提示できる必要があると言っているわけではありません。オブジェクトが表示されるUIをオブジェクトが認識できないため、これは不可能です(WinFormsアプリ、XServerを使用するLinuxアプリ、JSON文字列、XML、PNG画像など)。

要点は、特定のエンティティを表示することを唯一の責任とする専門的なビューを記述する必要があるということです。たとえば、オブジェクトをHTMLとしてレンダリングするビューを作成できます(MVCアプリケーションのビューによって行われます)。オブジェクトをJSON文字列に変換できるJSONシリアライザーを作成できます。他の種類のオブジェクトをPDFレポートに変換するオブジェクトを作成できます。それはすべて異なります。

重要なのは、ビジネスエンティティを視覚的な(またはシリアル化された)表現から分離することです。それらは異なるものであり、異なる理由で変化します。


見積もりを詳しく説明するために質問を編集しました。
MrHadiSatrio

1
私の回答はもうそれほど重要ではないと感じていますが、あなたの質問が引用とどう関係しているかはわかりません。引用は、視覚的なレンダリングではなく、APIとインターフェースの点でより多くを語っているようです。オブジェクトのどの部分にアクセスできるようにし、ビジネスドメインでの仕事を完了するためにオブジェクトが送信できるメッセージを教えてください。
sara 2016年

「ソフトウェアオブジェクトと人間のオブジェクトの間の仲介役として機能するGUIを構築している場合は、表示用にグリフを使用し、対話用にウィジェットを使用します。」その文章から判断すると、引用は視覚的なレンダリングの目的も意味していると確信しています。
MrHadiSatrio 2016年

「問題のオブジェクトは、特定のコンテキストでそれを最もよく表すグリフとウィジェットを選択する必要があり、また、上記のグリフとウィジェットのレンダリングを担当する必要がある」と述べることは何もありません。オブジェクトとそれを表示するものは必ずしも同じである必要はありません(すべきではありません)。
sara 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.