タグ付けされた質問 「object-oriented」

システムを、モジュール方式で制御および操作できるオブジェクトのセットとしてモデル化できるようにする方法論

7
オブジェクト指向言語では、オブジェクトはいつ自分自身に対して操作を行う必要があり、いつオブジェクトに対して操作を行う必要がありますか?
Pageページレンダラーへの一連の指示を表すクラスがあるとします。そしてRenderer、画面上にページをレンダリングする方法を知っているクラスがあるとします。次の2つの異なる方法でコードを構成できます。 /* * 1) Page Uses Renderer internally, * or receives it explicitly */ $page->renderMe(); $page->renderMe($renderer); /* * 2) Page is passed to Renderer */ $renderer->renderPage($page); 各アプローチの長所と短所は何ですか?いつ良くなるのでしょうか?いつ他の方が良くなりますか? バックグラウンド もう少し背景を追加するには-同じコードで両方のアプローチを使用していることに気付きます。と呼ばれるサードパーティのPDFライブラリを使用していTCPDFます。私のコードのどこかに私が持って仕事にPDFレンダリングのため、以下を持っています: $pdf = new TCPDF(); $html = "some text"; $pdf->writeHTML($html); ページの表現を作成したいとします。次のようなPDFページスニペットをレンダリングするための指示を保持するテンプレートを作成できます。 /* * A representation of the PDF page snippet: * a …

2
すべての主要なOOP機能を失うことなく、OOPで不変性を本当に使用できますか?
私のプログラムでオブジェクトを不変にすることの利点を理解しています。アプリケーションの良い設計について本当に深く考えているとき、私は多くの場合、オブジェクトの多くが不変であることに自然に到達します。多くの場合、すべてのオブジェクトを不変にしたいところになります。 この質問は同じ考えを扱っていますが、不変性に対する優れたアプローチと、それを実際に使用するタイミングを示唆する答えはありません。いくつかの良い不変のデザインパターンがありますか?一般的な考え方は、「オブジェクトを変更する必要が絶対にない限り、オブジェクトを不変にする」ことであるように見えますが、実際には役に立ちません。 私の経験では、不変性はコードをますます機能的なパラダイムに追い込み、この進行は常に起こります。 リスト、マップなどの永続的な(機能的な意味での)データ構造が必要になります。 相互参照(たとえば、子が親を参照している間、子を参照しているツリーノード)で作業することは非常に不便です。 継承は意味をなさないために停止し、代わりに構成を使用し始めます。 カプセル化のようなOOPの基本的な考え方全体がバラバラになり始め、私のオブジェクトは関数のように見え始めます。 この時点で、私は実際にはOOPパラダイムの何も使用しておらず、純粋に機能的な言語に切り替えることができます。したがって、私の質問:良い不変のOOP設計への一貫したアプローチがありますか、または不変のアイデアを最大限に活用すると、常にOOPの世界から何も必要としない関数型言語でプログラミングすることになりますか?OOPがバラバラにならないように、どのクラスを不変にし、どのクラスを不変にするかを決定するための良いガイドラインはありますか? 便宜上、例を示します。さんが持ってみましょうChessBoard不変のチェスの駒の不変なコレクションとして(抽象クラスを拡張しますPiece)。OOPの観点から見ると、ピースはボード上の位置から有効な動きを生成する役割を果たします。しかし、動きを生成するには、ピースがそのボードへの参照を必要とする一方で、ボードはそのピースへの参照を必要とします。さて、あなたのOOP言語に応じてこれらの不変の相互参照を作成するためのいくつかのトリックがありますが、それらは管理するのが苦痛で、ボードを参照する部分を持たない方が良いです。しかし、ボードの状態がわからないため、ピースは動きを生成できません。すると、ピースはピースタイプとその位置を保持する単なるデータ構造になります。その後、ポリモーフィック関数を使用して、あらゆる種類のピースの動きを生成できます。これは関数型プログラミングでは完全に達成できますが、ランタイム型チェックやその他の不適切なOOPプラクティスがないOOPではほとんど不可能です...

6
これは非オブジェクト指向でどのようにプログラムされますか?[閉まっている]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 2年前に閉店。 OOPのマイナス面に関する痛烈な記事を読んで、他のパラダイムを支持して、私はあまり過失を見つけることができない例にぶつかった。 私は著者の議論にオープンになりたい、と私は彼らのポイントを理論的に理解することができますが、特に1つの例は、例えばFP言語でそれがより良く実装される方法を想像しようとするのに苦労しています。 From:http : //www.smashcompany.com/technology/object-oriented-programming-is-an-expensive-disaster-which-must-end // Consider the case where “SimpleProductManager” is a child of // “ProductManager”: public class SimpleProductManager implements ProductManager { private List products; public List getProducts() { return products; } public void increasePrice(int percentage) { if (products != null) { for (Product product : …

5
サブクラス型を要求しないようにするための優れた設計方法は何ですか?
プログラムがオブジェクトのクラスを知る必要がある場合、通常は設計上の欠陥を示しているので、これを処理するための適切なプラクティスを知りたいと読みました。Circle、Polygon、Rectangleなど、さまざまなサブクラスを継承するShapeクラスを実装しています。また、CircleがPolygonまたはRectangleと衝突するかどうかを知るためのさまざまなアルゴリズムがあります。次に、Shapeの2つのインスタンスを取得し、一方が他方と衝突するかどうかを知りたいと仮定します。そのメソッドでは、どのアルゴリズムを呼び出すべきかを知るために衝突しているオブジェクトがどのサブクラスタイプであるかを推測しますが、これは悪いデザインや練習?これが私が解決した方法です。 abstract class Shape { ShapeType getType(); bool collide(Shape other); } class Circle : Shape { getType() { return Type.Circle; } bool collide(Shape other) { if(other.getType() == Type.Rect) { collideCircleRect(this, (Rect) other); } else if(other.getType() == Type.Polygon) { collideCirclePolygon(this, (Polygon) other); } } } これは悪いデザインパターンですか?サブクラス型を推測せずにこれをどのように解決できますか?

7
オブジェクト指向のオブジェクト指向言語での実装?
カーレースをシミュレートするJavaコードをいくつか見てきました。これには基本的なステートマシンの実装が含まれています。これは、古典的なコンピューターサイエンスステートマシンではなく、複数の状態を持つことができ、一連の計算に基づいて状態を切り替えることができるオブジェクトにすぎません。 問題だけを説明するために、Carの状態の定数(OFF、IDLE、DRIVE、REVERSEなど)を定義するネストされたenumクラスを持つCarクラスを取得しました。この同じCarクラス内には、更新機能があります。これは基本的に、現在の車の状態を切り替え、計算を行い、車の状態を変更する大きなswitchステートメントで構成されています。 私が見る限り、Cars状態は独自のクラス内でのみ使用されます。 私の質問は、これが上記の性質のステートマシンの実装を処理する最良の方法ですか?それは最も明白な解決策のように聞こえますが、過去には「switchステートメントが悪い」といつも聞いていました。 ここで見られる主な問題は、状態を追加すると(必要に応じて)switchステートメントが非常に大きくなり、コードが扱いにくくなり、保守が難しくなる可能性があることです。 この問題のより良い解決策は何ですか?

3
`Employee`クラスはどのように設計されるべきですか?
私は従業員を管理するためのプログラムを作成しようとしています。ただし、Employeeクラスの設計方法を理解することはできません。私の目標は、Employeeオブジェクトを使用してデータベース上の従業員データを作成および操作できるようにすることです。 私が考えた基本的な実装は、この単純な実装でした: class Employee { // Employee data (let's say, dozens of properties). Employee() {} Create() {} Update() {} Delete() {} } この実装を使用すると、いくつかの問題が発生しました。 ID従業員のは、私は、新しい従業員を記述するためのオブジェクトを使用するのであれば、何があるだろう、データベースによって与えられていないID既存の従業員を表すオブジェクトはながら、まだ格納するだろう持っていますID。そのため、オブジェクトを説明するプロパティと、オブジェクトを説明しないプロパティがあります(SRPに違反していることを示すことができますか?新しいクラスと既存の従業員を表すのに同じクラスを使用しているため...)。 Create一方、この方法は、データベース上の従業員を作成することになっているUpdateとは、Delete既存の従業員(ここでも、上で動作するようになっているSRP ...)。 「作成」メソッドにはどのようなパラメーターが必要ですか?すべての従業員データまたはEmployeeオブジェクトのための数十のパラメーター? クラスは不変であるべきですか? どのようにUpdate動作しますか?プロパティを取得してデータベースを更新しますか?または、「古い」オブジェクトと「新しい」オブジェクトの2つのオブジェクトを取り、それらの違いでデータベースを更新しますか?(答えは、クラスの可変性に関する答えと関係があると思います)。 コンストラクターの責任は何ですか?必要なパラメーターは何ですか?idパラメーターを使用してデータベースから従業員データを取得し、プロパティを設定しますか? それで、あなたが見ることができるように、私は私の頭の中に少し混乱を持っています、そして、私は非常に混乱しています。そのようなクラスがどのように見えるべきかを理解してください。 このような頻繁に使用されるクラスが一般的にどのように設計されているかを理解するためだけに、意見を望まないことに注意してください。

5
進行状況をUIに報告するための最善の戦略-コールバックはどのように行われるべきか
ユーザーは、実行に時間がかかる拡張技術操作を開始する場合があります。このような場合、通常、現在進行中のタスクに関する情報とともに、何らかのプログレスバーを表示すると便利です。 UIとロジックレイヤーの密接な結合を避けるために、通常、何らかのプロキシを介して通信を行うことが最善です。つまり、バックエンドは独自のUI要素を操作したり、中間層と直接対話したりすることはできません。 明らかに、これを機能させるためにはどこかにコールバックが必要です。通常、2つの方法のいずれかで実装しました。 可変オブジェクトをバックエンドに渡し、進行中にバックエンドに変更を加えます。オブジェクトは、変更が発生するとフロントエンドに通知します。 フォームのコールバック関数を渡すvoid f(ProgressObject)かProgressObject -> unit、バックエンドが呼び出します。この場合、バックエンドはを構築し、ProgressObject完全に受動的です。進行状況を報告するたびに新しいオブジェクトを作成する必要があると思います。 これらの方法の欠点と利点は何ですか?合意された最適な使用方法はありますか?それらの使用には異なる状況がありますか? 私が見落としている進捗状況を報告するための完全に異なるテクニックはありますか?

2
優れた実践における乾燥の原則?
私は、できる限り一生懸命プログラミングのDRY原則に従うようにしています。最近、私はOOPでデザインパターンを学んでいますが、結局、かなりの量を繰り返しています。 永続性を処理するために、FactoryパターンとGatewayパターンとともにRepositoryパターンを作成しました。私はアプリケーションでデータベースを使用していますが、ゲートウェイを交換して、必要に応じて別の種類の永続性に切り替えることができるはずなので、それは問題ではありません。 最終的に自分で作成した問題は、所有しているテーブルの数に対して同じオブジェクトを作成することです。たとえば、これらはテーブルを処理する必要があるオブジェクトになりますcomments。 class Comment extends Model { protected $id; protected $author; protected $text; protected $date; } class CommentFactory implements iFactory { public function createFrom(array $data) { return new Comment($data); } } class CommentGateway implements iGateway { protected $db; public function __construct(\Database $db) { $this->db = $db; } public function …

2
インスタンスが1つだけのPythonクラス:(単一の)クラスインスタンスを作成するタイミングと、代わりにクラスを使用するタイミング
1回だけインスタンス化されるPythonクラスがある場合、つまり、クラスのオブジェクトは1つだけになります。クラスを直接操作するのではなく、単一のクラスインスタンスを作成する方が理にかなっているのではないかと思いました。 同様の質問がありますが、焦点は異なります。 グローバル変数と関数をクラスにグループ化することです Python固有ではありません。後者は、(Pythonで)クラスもオブジェクトであるという事実を考慮しないことを意味します。 更新: Pythonでは、クラスとオブジェクトの両方で次のことができます。 class A(object): pass A.some_state_var = True # Then later A.some_state_var = False my_a = A() my_a.some_state_var = True # Then later my_a.some_state_var = False そのため、クラスとそのクラスのインスタンスの間の選択が(Pythonで)状態に関するものであるかどうかはわかりません。どちらかで状態を維持できます。 さらに、クラス/クラスインスタンスを作成する動機は、シングルトン要件を強制することではありません。 また、新しいTypeを作成することはそれほど重要ではありません。 動機は、関連するコードとデータをグループ化し、それへのインターフェースを持つことです。これが、最初にクラス図のクラスとしてモデル化した理由です。実装に関してのみ、このクラスをインスタンス化するかどうか疑問に思い始めました。

5
このシナリオで構成または継承を優先すべきですか?
インターフェイスを考えてみましょう: interface IWaveGenerator { SoundWave GenerateWave(double frequency, double lengthInSeconds); } このインターフェイスは、さまざまな形状の波を生成するいくつかのクラス(SineWaveGeneratorおよびなどSquareWaveGenerator)によって実装されます。 SoundWave生のサウンドデータではなく、音楽データに基づいてを生成するクラスを実装したいと思います。それは音の名前と拍数(秒ではない)の長さを受け取り、内部的にIWaveGenerator機能を使用してSoundWaveそれを作成します。 質問は、「をNoteGenerator含むIWaveGeneratorべきIWaveGeneratorですか、それとも実装から継承すべきですか?」 次の2つの理由から、作曲に傾倒しています。 1- 動的に任意のIWaveGeneratorものを注入できNoteGeneratorます。またNoteGenerator、、などSineNoteGeneratorでSquareNoteGeneratorはなく、1つのクラスのみが必要です。 2-でNoteGenerator定義された下位レベルのインターフェースを公開する必要はありませんIWaveGenerator。 しかし、私はこれに関する他の意見を聞くためにこの質問を投稿しています。おそらく考えていない点です。 ところで:私はそれがsを生成するため、概念的に言うNoteGenerator と思います。IWaveGeneratorSoundWave

7
OOPはプロパティの概念を含むようにどのように進化しましたか
私はC ++のバックグラウンドから来て、現在の仕事でC#を使い果たしており、パブリックフィールドとプロパティの違いと、このバリエーションと化身の前後の違いについて多くのQ&Aを読んでいます。基本的な質問(たとえば、このSO投稿と関連するすべてのリンクされた質問)。これらの質問はすべて、プロパティシステムの存在を当然とする実際的な違いの観点から説明されていますが、最初のプロパティをサポートすることを決めたすべての言語のデザイナーがこのテーマにアプローチするのは良いと思います場所は考えていました(Wikipediaの記事のリストをチェックしてください)。OOPはC ++ / Javaからどのように進化し、Wikipediaの記事で興味深いことにメソッドとメンバーデータの中間であると特定されました。 「つまり、プロパティはクラスのメンバーコード(メソッド)とメンバーデータ(インスタンス変数)の中間であり、プロパティはパブリックフィールドよりも高いレベルのカプセル化を提供します。」 MSDNはさらに背景を追加します。 「プロパティは技術的にはメソッドに非常によく似ていますが、使用シナリオの点ではまったく異なります。スマートフィールドと見なすべきです。フィールドの呼び出し構文とメソッドの柔軟性があります。」 カプセル化のこの中間レベルが一般的なプログラミングに有用であることが判明したことを知りたいと思います。この概念は、OOPパラダイムを表現したプログラミング言語の最初の化身には存在しなかったと思います。

4
「OOPは状態を隠す」とはどういう意味ですか?[閉まっている]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 5年前に閉鎖されました。 でcat-v.org上の多くの抗OOPの暴言の一つ、私は以下の通りであったそのうちの一つOOPモデルに対して複数の異議を上げるジョー・アームストロングの通路を見つけました: 異論4 –オブジェクトにはプライベート状態があります 国家はすべての悪の根源です。特に、副作用のある機能は避けてください。 プログラミング言語の状態は望ましくありませんが、現実の世界では状態が豊富です。私は銀行口座の状態に非常に興味があり、銀行に入金または引き出しを行うと、銀行口座の状態が正しく更新されることを期待しています。 状態が現実の世界に存在する場合、プログラミング言語は状態を処理するためにどの機能を提供する必要がありますか? OOPLは「プログラマーから状態を隠す」と言います。状態は非表示であり、アクセス関数を介してのみ表示されます。従来のプログラミング言語(C、Pascal)は、状態変数の可視性は言語のスコープルールによって制御されると言います。純粋な宣言型言語は、状態がないと言います。システムのグローバルな状態はすべての機能に持ち込まれ、すべての機能から出てきます。モナド(FPL用)やDCG(ロジック言語)などのメカニズムは、プログラマーから状態を隠すために使用され、「状態は重要ではないかのように」プログラムできますが、必要に応じてシステムの状態に完全にアクセスできます。 OOPLによって選択された「プログラマーから状態を隠す」オプションは、最も悪い選択です。国家を明らかにし、国家の迷惑を最小限に抑える方法を見つけようとする代わりに、彼らはそれを隠します。 これはどういう意味ですか?私は、ほとんどの場合OOPの低レベルまたは手順の経験がほとんどないため、これがおそらく私がこれに慣れていないことを説明しています。そして、より現代的な観点から、オブジェクト指向のヒステリーのほとんどが渡されたので(少なくとも私が知る限り)、あなたはあなたはその通過がどれほど正確/関連していると思いますか? ご協力いただきありがとうございます。

5
内部データ構造を常に完全にカプセル化する必要がありますか?
このクラスを考慮してください: class ClassA{ private Thing[] things; // stores data // stuff omitted public Thing[] getThings(){ return things; } } このクラスは、データを保存するために使用する配列を、関心のあるクライアントコードに公開します。 作業中のアプリでこれを行いました。sのChordProgressionシーケンスを格納するクラスがありましたChord(その他の処理も行います)。Chord[] getChords()コードの配列を返すメソッドがありました。データ構造を(配列からArrayListに)変更する必要がある場合、すべてのクライアントコードが破損しました。 これは私に考えさせられた-多分次のアプローチが優れている: class ClassA{ private Thing[] things; // stores data // stuff omitted public Thing[] getThing(int index){ return things[index]; } public int getDataSize(){ return things.length; } public void setThing(int …

6
適切な設計で簡単にするには大きすぎる変更は何ですか?
これはかなり曖昧な質問ですが、適切な設計について読んだときに満足のいく方法で答えられたとは思っていませんでした。 一般に、オブジェクト指向プログラミング、抽象化、因数分解などについて学ぶとき、設計の聖杯-そして、あなたが問題の開発技術を使用していると常に主張する理由-は、プログラムを「変更しやすくする」ことです、「維持可能」、「柔軟」、またはそのような生産的な響きの概念を表現するために使用される同義語のいずれか。ivarをプライベートとしてマークし、コードを多くの小さな自己完結型のメソッドに分割し、インターフェイスを一般的な状態に保つことで、プログラムを完全に簡単かつ優雅に変更できるようになります。 比較的小さな変更の場合、これは私にとってはうまくいきました。クラスがパフォーマンスを向上させるために使用する内部データ構造の変更は大きな困難ではありませんでした。また、テキスト入力システムの再設計やゲームプレイ要素のグラフィックのオーバーホールなど、APIに依存しないユーザーインターフェイスエンドの変更もありません。 これらの変更はすべて、本質的に自己完結型のようです。それらのいずれも、外部コードに関する限り、変更されるプログラムのコンポーネントの動作または設計への変更を伴いません。手続き型であろうと大規模な機能であろうと小規模であろうとOOスタイルであろうと、これらはあなたが適度に良いデザインしか持っていなくても簡単に変更できます。 しかし、変更が大きくて毛深いものになったとき、つまりAPIに変更が加えられたときはいつでも、私の貴重な「パターン」はどれも助けになりません。大きな変化は大きなままで、影響を受けるコードは影響を受けたままで、何時間もバグを生み出す作業が私の前にあります。 だから、私の質問はこれです。適切な設計がどの程度大きな変更を促進できると主張していますか?私には未知の、または実装に失敗した、さらにスティッキーなサウンドの修正を本当に単純にする、またはその約束(非常に多くの異なるパラダイムによって行われたと聞いた)は単に素晴らしいアイデアである、いくつかのさらなる設計技術がありますか?ソフトウェア開発の不変の真実から完全に切り離されていますか?ツールベルトに追加できる「変更ツール」はありますか? 具体的には、私がフォーラムに導かれた問題はこれです:私は解釈されたプログラミング言語(Dで実装されていますが、それは関係ありません)の実装に取り​​組んでおり、クロージャの引数は現在の位置ではなく、キーワードベース。これには、匿名関数を呼び出す既存のすべてのコードを変更する必要がありますが、幸いなことに、私は言語の開発の初期段階(2000行未満)であるため、かなり小さいですが、後の段階でこの決定を行った場合は非常に大きくなります。そのような状況では、設計の適切な先見によって、この変更を簡単にすることができたのでしょうか、それとも特定の(ほとんどの)変更が本質的に広範囲に及ぶのでしょうか?これが何らかの形で自分自身の設計スキルの失敗であるかどうかに興味があります-もしそうなら、私は 明確にするために、私はOOPや一般的に使用されている他のパターンのいずれにも決して懐疑的ではありません。ただし、私にとっては、それらの長所は、コードベースの保守ではなく、元の記述にあります。継承を使用すると、繰り返しパターンを適切に抽象化できます。ポリモーフィズムを使用すると、機械が理解する効果(switchステートメントのブランチ)ではなく、人間が理解する機能(クラス)でコードを分離できます。非常に快適な「ボトムアップ」スタイルで記述します。しかし、私は彼らの柔軟性の主張に懐疑的です。

4
読み取り専用オブジェクトを返すベストプラクティス
C#でのOOPに関する「ベストプラクティス」の質問があります(ただし、すべての言語に当てはまります)。 たとえば、プロパティアクセサを介して、パブリックに公開されるオブジェクトを含むライブラリクラスを持つことを検討してください。 class A { // Note: List is just example, I am interested in objects in general. private List<string> _items = new List<string>() { "hello" } public List<string> Items { get { // Option A (not read-only), can be modified from outside: return _items; // Option B (sort-of read-only): …

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