1 :
デフォルトの名無しさん :
2005/09/24(土) 16:35:59 全部publicでいいじゃん!ってならないようにするスレです。
2
∧_∧ / ̄ ̄ ̄ ̄ ̄ (ω・ )ゝ < なんだって? ノ/ / \_____ ノ ̄ゝ
全部public と OOP限定 の関連がわかりません
双方向関連です
∧_∧ / ̄ ̄ ̄ ̄ ̄ (ω・ )ゝ < なんだって? ノ/ / \_____ ノ ̄ゝ
>>4 Java屋やC屋が入り混じると煽りが入りえるので住み分けしました。
OOP限定はスレの利便性のためとお考えください。
オープンソース全盛の今設計手法で商売する時代になったので、 無料では教えてあげません
へー、javaってOOPLじゃなかったんだ
新しいSmalltalkスレはここですか?
>>9 Java(OOP)とC(構造化)の煽りあいという意味です。
MVCを意識してライブラリを設計しているのですが とあるメインループを持つController部を切り替えても Model, Viewは同じものを使う手法を考えています。 この場合メインControllerを切り替える為のControllerを それらの最上位に実装するのは正しい設計でしょうか? ControllerController ├Model ├View └Controller この図の場合だとControllerがControllerControllerに 自身をあのControllerに切り替えてと頼む形になります。 ControllerControllerは切り替え処理以外の機能は持ちません。
デザパタ勉強してください
15 :
デフォルトの名無しさん :2005/09/24(土) 17:19:15
全部publicではないが、数千行あるクラスでprivateなメソッドが1個だけで、 他は全部publicなメソッドってのがあった。
CLOS最強!!
17 :
デフォルトの名無しさん :2005/09/24(土) 17:53:32
>>15 コボラーの仕業だな。
最近、似たようなモンみたよ。
18 :
デフォルトの名無しさん :2005/09/24(土) 18:53:42
19 :
デフォルトの名無しさん :2005/09/25(日) 02:43:03
20 :
マイク ◆yrBrqfF1Ew :2005/09/25(日) 03:53:27
MVCウザイな。 使いやすくない。
MVCはCが如何に無理をするかが焦点だな
22 :
デフォルトの名無しさん :2005/10/02(日) 00:11:03
youzyoパターンってなんぞ? 委譲じゃないよな?
23 :
デフォルトの名無しさん :2005/10/02(日) 01:11:15
===== 基地外スレ =====
gofのすとらてじい?
25 :
デフォルトの名無しさん :2005/10/21(金) 18:16:26
Mのクラスが、VやCのクラスを引数にとったり、内包したら設計ミスかな?
というか
>>21 が何気に至言だ
って、なんだ最後の発言が3週間くらい前か
26 :
デフォルトの名無しさん :2005/10/23(日) 21:34:16
Mって早い話が構造体クラスでしょ? SQLにマッピングするためのゲッタくらいが限界じゃないかな
それはCクラスでやりたいな・・・
28 :
デフォルトの名無しさん :2005/11/04(金) 15:47:55
デザパタは10回同じのを使うとわかった気になるなあ、おい。
デザパタはOOPをプロでやってく上での教養なのかねぇ 実際仕事で汲んでも使う機会無い気がする。 せーぜーシングルトンがあぶ工場くらい。
30 :
デフォルトの名無しさん :2005/11/06(日) 01:10:50
OOPのアルゴリズムテンプレートがあって それをDBから引っこ抜いてくるように出来たら面白いのにな プログラムとはそれすなわちアルゴリズムって証明できる
アルゴリズムテンプレートってなに?
機能じゃないよ。言葉そのままの意味。 ソートとかコレクションとかOOPならどれでも共通化できそうなものを纏めて欲しい。
だいたいだなぁ、OOP限定なら「プログラム設計」じゃなくっ「てクラス設計」ではないのか?
てクラス設計
37 :
デフォルトの名無しさん :2005/12/02(金) 21:54:29
AOPって何ですか?
エージェント?
スミス?
40 :
デフォルトの名無しさん :2005/12/03(土) 01:05:30
41 :
デフォルトの名無しさん :2005/12/03(土) 01:10:27
Oがないじゃん
23のパターンを用いてHelloWorldを実装してください。
public interface MessageStrategy { public void sendMessage(); } public abstract class AbstractStrategyFactory { public abstract MessageStrategy createStrategy(MessageBody mb); } public class MessageBody { Object payload; public Object getPayload() { return payload; } public void configure(Object obj) { payload = obj; } public void send(MessageStrategy ms) { ms.sendMessage(); } } public class DefaultFactory extends AbstractStrategyFactory { private DefaultFactory() {;} static DefaultFactory instance = new DefaultFactory(); public static AbstractStrategyFactory getInstance() { return instance; } public MessageStrategy createStrategy(final MessageBody mb) { return new MessageStrategy() { MessageBody body = mb; public void sendMessage() { Object obj = body.getPayload(); System.out.println((String)obj); } }; } } public class HelloWorld { public static void main(String[] args) { MessageBody mb = new MessageBody(); mb.configure("Hello World!"); AbstractStrategyFactory asf = DefaultFactory.getInstance(); MessageStrategy strategy = asf.createStrategy(mb); mb.send(strategy); } }
45 :
デフォルトの名無しさん :2005/12/03(土) 22:07:59
GoF以外のデザパタ集で有名どころってある?
マルチスレッドのデザインパターンやら、 GRASPやJ2EEパターンが有名どころか?
C++でか書かれてるデザパタ参考本ってないよね
smelltalkもはいってんじゃん。>本家
smalltalkは本家じゃん。本家が本家を扱って何が悪い。
本家本は確かにSmalltalkとC++だな。
でもC++が多いから
>>48 みたいな反応でもあながち間違えではないと思う。
そんなわけで、Smalltalkに特化したThe Design Patterns Smalltalk Companionがわけだし。
smelltalk
54 :
デフォルトの名無しさん :2005/12/03(土) 23:55:21
なんだかワケワカメ 本家本=GoFデザパタ本だよね?
smalltalkの特徴って何? 何でもオブジェクトって言う思想はRubyと同じ思想?
>>53 ワロス
確かに臭うね
>>55 何でもオブジェクトって考えは近いとは思うよ。
ただ、Smalltalkは徹底的に何でもオブジェクト。
いわゆる制御文(if、whileやforのようなもの)も
各種オブジェクトのメッセージとして定義されてる。
Rubyもそうなのかな?(じぶんはRubyってそれほどしらない)
「Smalltalkの思想がRubyの思想と同じ」 っていうのは順序がおかしいと思う
すべてのOOはSmalltalkよりはじまるか。
>>59 違う。Rubyは制御文はメッセージ送信ではない。
ifやwhileなどの制御文はCやPerlと同じモデル。
そのページは間違い。ifメッセージをなんのオブジェクトに送信しとるっちゅーねん。
Rubyの制御構造の一部は式ってのを勘違いしている?
だとしたら 4. 制御構造までオブジェクト 私はこれで乗り換えました。(ついに!) ってのはかなり痛いんだけど、Rubyに詳しい人解説お願い。
1円で海外旅行に行けますと勧誘されて入会金50万円払ってる感じが痛々しい
そうか? void型メソッドをあえて自分への参照を返すようにしているコードって結構好きだし、痛さは感じないが。
勘違いして乗り換えしてるのが痛いってだけ しかも間違えた解説付きときている 言語構造云々について痛いとかは思わない
ああ、3項演算子がネストできないと思ってるところかw
>4. 制御構造までオブジェクト これはオブジェクトではなく”式”の勘違いですね。 >if 〜 end.tr("a-z", "A-Z") この記述が勘違いを助長させた原因でしょう。 ifの結果としてオブジェクトが返却され、.tr〜はそのオブジェクトに 対しての操作だということをこの人は誤解しています。 Rubyの構文規則は柔軟に見えますが、こういった誤解を受ける問題があります。
イテレータブロックは?
だれかそこへメールを送ってみないか?
>>69 ありゃあ関数オブジェクトとかクロージャといった類のモノだよ。
起源はLISPのインライン関数とかSmalltalkのブロックだな。
Rubyは動的時にメソッド選択してるからトンデモ構文に見える。
s/動的時/動的/ な
全てが protected
74 :
デフォルトの名無しさん :2005/12/11(日) 15:08:43
シーケンス図ってホントにプログラム知らないお偉いさんでも読めるの?
75 :
デフォルトの名無しさん :2005/12/11(日) 15:21:18
>>74 プログラムシラナイお偉いさんにシーケンス図見せる時点で間違ってないか?
ユースケースとか配備図とかコラボレーション図とか…
76 :
デフォルトの名無しさん :2005/12/11(日) 15:24:20
UMLの全てがユーザフレンドリーってわけではないのね
77 :
デフォルトの名無しさん :2005/12/11(日) 15:26:46
>>76 えーと、UMLって単に開発で使う図に統一規格を持ち込んだだけの
話で、それ以上のものじゃないですよ。
じゃあ参考書の書き方がまずかったのかな
書くレベル次第だな 厳密な設計書として書いているなら細かすぎて読めないかも
日本語だらけの仕様書は曖昧さが目で見て取れるため問題に気づきやすいが 曖昧なまま書き起こされたUMLは、一見する分には完全な仕様書に見えるため問題が分かりにくい。 UMLが客が読める仕様書としてしまうのはある意味とても危険。
いやいや、そんなレベルのUMLは仕様書としないでしょ。 あくまでコミュニケーションツールの一つ。 処理の流れはこんな感じですよ〜みたいに。
UMLでは、異常系の記述がやり辛いよな。 ・・・はっ!!
83 :
デフォルトの名無しさん :2005/12/17(土) 02:12:04
会計ソフト作ってみたいんだが仕訳モデルのサンプルとか無い? 3級レベルで会計ソフトって作れるのかいな?まあそっちも勉強しながらやってきます
自分で分析したら?
言ってることはある意味正しいが そういうレスはこのスレの役を果たさないな
javaでアプリ作ったんだけど、関連が全部双方向になったんだけど これってやっぱ良くないの?
> 関連が全部双方向 ここがちょっとわからないが、まぁpublic全開になるのは仕方ないんじゃないかな。 コンポーネント郡はそのまま使わず、派生させてから使えば上手くカプセルにできるかもしれん。
まぁ、初心者にありがちなパターンだな。 関連というか、メッセージ送信が双方向になるなら、そのメッセージを一度整理して、分類して、 クラス内のメッセージ受信部分をインタフェースに分離するという観点で構築しなおしたらいいんじゃないの?
実はFlashってのはOOPの訓練に役立つ。
>>87-88 サンクスコ
そうです、メッセージ送信が双方向ってことでした。
そういえばインターフェースも抽象クラスも全く使ってない。
というか使いどころもわかんね。
とりあえずそれらの勉強してみます。
ありがとうございました
>>15 漏れは何も考えずにとりあえずメソッドはpublicにしてるんだけど…
内部からしか呼ばれないのはprotectedにしてる
まずいのか?
>>91 いつの間にかぐちゃぐちゃなソースになるのが弊害かな。
アクセス権の指針 public:外から呼ぶ必要がある protected:外から呼ぶ必要はないが派生クラスから呼ぶ必要がある private:デフォルト
下駄/雪駄なんて書く気しねー。
憂鬱本ではメソッドは基本的に全部publicで問題ないって書いてあったが
>>95 その本は読んでないが、そこだけ聞いたら焚書モノだな。
>>93 その判断を誤るとややこしいことになるからすべてpublicにしておけ
って程度なんだろうね、その本
>>95
もともとC++やってて、最近仕事でjavaやり始めたんだけど、 javaのprotectedって全然プロテクトじゃないんだね 最初はprivateで作ってて派生クラスからメンバ変数へのアクセスが必要になる度に アクセサメソッド追加してるんだけど、まずいですか? まともなjava技術者ならどうしてます?
>>98 全然プロテクトじゃないってどういうこと?
>>98 はC++もまともに使えていないと予想する。
packageの時の扱いが違うくらいしか思いつかないけど、なんかすごい引っ掛けがあるのかな・・?
>>98 早くプロテクトじゃない理由を教えてくれよう。ワクワク
>最初はprivateで作ってて派生クラスからメンバ変数へのアクセスが必要になる度に >アクセサメソッド追加してるんだけど、まずいですか? C++もそうだし、オブジェクト指向もわかってないんじゃないかな なんか、Cプログラマーみたい グローバル変数使うなっていわれたから、プライベートにしてみました みんなが必要とするから悪切磋つけました そんなところでしょ
Lispを使わないなんてバカげてる
105 :
デフォルトの名無しさん :2005/12/23(金) 13:14:14
サブクラスのためにその都度スーパークラスを改変するのはナンセンス まともなC++技術者ならそんなことやらない まともなJava技術者もそんなことやらない まともなSmalltalkerもそんなことやらない まともなオブジェクト指向言語使用者ならそんなことやらない
まともな奴なら継承は使わないってことか
107 :
98 :2005/12/23(金) 14:10:15
自分はまともじゃないです(つд`) プロテクトじゃない云々は、javaのprotectedメンバは派生クラスだけでなく 同じパッケージにいるクラスでもアクセスできるのでC++のより緩いって意味です。 親クラス作るときにはメンバ変数全部に対してprotectedのアクセサ用意しとくものなのかな、と。 で、こういう設計はおかしいですか?
親クラスのメンバーにサブクラスがあとあといろいろアクセスしなきゃならなくなるかもぁー。 そういうときにpribvateだと、困るから、protectedにしておいたほうが、いいのかなぁ〜。 なんっていう、下らんこと気にしているようでは、そもそもクラス抽出がうまくできているとは思えない。
>>106 サブクラスのためにその都度スーパークラスを改変する ってのがナンセンス。
継承前提で設計されたスーパークラスはそんな改変しょっちゅうしない。
>>107 ?
派生からアクセスが必要になる度にアクセッサを追加してるんじゃないの?
そもそも日本語もだめだったり?
俺も勉強したてでよく分からんけど、 メンバ変数全部に対してprotectedのアクセサ用意って これはカプセル化の意味ないと思うんだが… 多分そのスーパークラスの設計から見直したほうがいいんじゃ
継承前提で作るときはこういう悩みはないんですが、 工数削減の関係で仕方なく、継承させるつもりがまったくなかったクラスに スーパークラスとして、アクセサを追加してました。 まったく継承させるつもりがなくても、あとあとのことを考えて protectedアクセサを…ってダメダメですよね。 設計が悪かったのが理解できました。みなさんありがとう
コンストラクタはオーバーロードできないっぽくて悲しい デフォコンだけでしょ
115 :
デフォルトの名無しさん :2005/12/31(土) 04:53:35
>>113 ∧_∧ / ̄ ̄ ̄ ̄ ̄
(ω・ )ゝ < なんだって?
ノ/ / \_____
ノ ̄ゝ
コンストラクタでHoge(String str)とかは継承されないという話 オーバーロードとは違う
StrutsのActionみたいなリクエストを処理するクラスで、思想の問題と思われるが Aという共通抽象クラスがあって、業務Bと業務Cがあり、BとCは機能がほとんど同じ この場合、どっちがよい? 1)A<Bと継承して、更にB<Cと継承して違うところだけは追加・オーバーライドする 2)A<B, A<Cと別々に継承する 1だと違う部分だけ書けばそれだけでいいけど、もしBの共通部分が変更になるとCにも影響する恐れがある 2だとBの共通部分が変更になってもCには影響しないが、多少かぶってしまう箇所が出てくる 個人的には2かなと思ってるけど、今の現場では1が多い 2は共通化できそうな部分だけは別クラスに作るってので対処できるし
>>117 もし俺なら、(共通部分の内容と量にもよるが)もう1層括りだせないか?
と、考えてみる。
AbstractA<抽象クラス
│
AImpl<共通実装部分
├SubclassB<差異
└SubclassC<差異
感じとして会社によってはドメインフレームワークって言ってるやつかな?
121 :
117 :2005/12/31(土) 20:13:31
レスサンクス
>>118 Decoratorパターンでやったことないから今度実験してみよう
>>119 2の拡張みたいな感じかな
それも検討してみたことがあるけど、サブシステム全体で共通ならいいような気がするけど
サブシステム内のある2機能だけ特別にクラスを作るってのはどうか悩んだ
そこまで差が少なければ俺は119のAImplをクラステンプレートにして、 BとCの差異をTraitsクラスにして選択できるようにするだろう。 119のように継承するのと大して差異はないけど。
124 :
122 :2006/01/01(日) 13:02:39
>>123 そうだよ。
ついC++スレにいるつもりでだった。
117がC++を使っていなければすまん、使えないな。
設計相談って難しいよね 冗談半分でSmalltalkならこうするよ といったら怒られたw Javaでやろうとするとひどく煩雑になるんだもん・・・
設計という分野は言語より上位だと思ったりもするんだが、 実装する言語によって良い設計が変わってしまうしね。
>>126 言語で左右されるような実装レベルまで設計するなよ
そうなのかなぁ どんなにすばらしい設計をしたとしても、 それを実現する手段がなければ 意味のない物になってしまうと思うんだけど
C++でtemplateで静的に解決できるものが
Javaでやるならクラスで動的解決になるし。
しかも静的動的って言葉すらも言語によって意味違うし。
>>127 の思想だと最大公約数的な設計になりそう。
まぁ別にそれでも問題無いことも多い気もするけど。
設計は二段階で
基本設計 詳細設計
132 :
デフォルトの名無しさん :2006/02/12(日) 12:27:56
デザインパターンっていつ使うの?
パターン化したいとき
使えるとき(マジレス)
私もRubyが何故ifをTrueClass/FalseClassのメソッドに しなかったかなぁ、と思った事はあるね。 Perlとかを意識して妙な仕様にしたんだと思うが。
ぐは、誤爆
137 :
デフォルトの名無しさん :2006/07/01(土) 21:50:01
publicばっかのクラスというけれど 7割がたそうなってしまうのが人の世だと思う
public といっても、属性と操作がある。 属性は全て private 、 操作はデフォルトで public 必要に応じて private ってのが 実装レベルでは当然と思う。 ぶっちゃけ、7割りがた属性が public なクラスなんてありえない。
139 :
デフォルトの名無しさん :2006/07/01(土) 22:31:20
そら属性は7割がたprivate、残りprotectedだろうね。
140 :
デフォルトの名無しさん :2006/07/04(火) 00:15:15
フィールドは本来10割がprivateだろう。 派生クラスで使用したい場合も、protectedなプロパティとして用意するべき。
protected も無印(package) も意外と使わないんだよね。 なんか使うとしても、デバッグとかテストケース動かすためとか、 裏技的な目的が多いような・・・。
私はpackageは使いまくってるよ これがないと(ていうかC++のことだが) ユーザー公開用のファサードを用意しなきゃならなくてだるすぎる
俺もパッケージプライベートは良く使う 無名インナークラスでもない限りは、インナークラスは外に出すのでね
今日、とあるプロジェクトに加わることになって、 そのプロジェクトで利用されてるライブラリ(プロジェクトメンバーが開発) を見たんだけど、やたらと〜Managerみたいなクラスばっかりだった。 これって、どうなのかなぁ? 例えば、ファイル入出力を司るクラスが抽象クラスで用意されてて、 そいつを必ず継承して使ってねっていう感じだった。 他の各機能も同じ。 んで、プロジェクトファイル名も〜Managerみたいなのばっかり。 (マスタデータを登録するやつだったらDataManagerとか・・) うまく説明できないんだけど、何か違和感を感じました。 こういうのってOOPで主流(?)なんでしょうか? ちなみに言語は.NETのC#です。
>144 抽象クラスを継承して使うことが、Managerが多いことの例え、 って部分が理解出来ない。
>>145 参考になりました・・・・・
明日から、どうしよ。
なんか、このライブラリを使用することを半強制されてるんだけど・・・・
(;´Д`)
使いにくいだけのショボブラリを仕事で使わされると虐待かと思う
>>146 説明が悪くて申し訳ないす。
何というか汎用的な各機能毎にManagerがいて、
汎用的な処理を実装する機能をもつクラスが必要になる
場合はそのManagerを継承して、新たなManagerを作ってねという感じなんですよ。
んで、ファイルを読んだり、書いたりする機能がある場合だったら
必ずFileManagerとやらを継承してHogeFileManagerや、
FugaFileManagerみたいなクラスを作ろうという風になってます。
Managerと言う割には、ファイルの読み/書きの機能の為だけに
わざわざ継承するのはどうなのかなぁと。
FileManagerにHogeFileManagerやFugaFileManagerのインスタンスを
渡して処理するような事も無いみたいだし・・・
うまく説明できないけどこんな状態です・・・。
>>149 "Manager"という名前がアレだけど、それって単に物理的な何かを
抽象化してるだけでしょ。
良くある話。
〜erみたいなクラスは確かによく見るんですが、 余りにも〜Managerがたくさんいたんで おかしいなと、自分が考えすぎてただけなのかもしれないすね。 明日あたり、作成者の人にどういう意図で作ったのか 聞いてみます。 お騒がせしました。
やめとけ、意図と聞くと切れる。 聞いただけで否定されてる?って切れる。
↑こういうプロになりたくないと思ったbyアマチュア
糸は切れやすい。たしかに。
自分の設計が最強と思ってる人間が、 同じプロジェクトに居たりすると困るよなぁ。 やたらと、自作ライブラリを使わせようとしたり、 頼んでも無いのに勝手にこれ使ってくださいとか言ってきたりする奴。 身の回りに一人居るが、 今、新人を洗脳してるw 型って何?、レベルの人間に 懇々と我流オブジェクト指向について熱く薀蓄を語っては、 新人のやる気を萎えさせてる。 おかげで、久しぶりに開発人数が増えそうなのに、 辞めてってしまいそうだ。
>>155 俺の事言われてるのかと思ったw
まぁ、数千行の関数とかコピペで作る奴よりマシだと思ってるけど。
俺は自作ライブラリ作るときは、シンプル&単機能な設計でUnitTestとセットで提供しているから問題ないよな。
田舎ライブラリ使わされるのは苦痛なだけ そのまま作らせろ
155の新人は、優秀なメンテナンス要員に成長しましたとさ。 めでたしめでたし
161 :
デフォルトの名無しさん :2006/08/01(火) 22:01:01
デザインパターンってどのくらい覚えるのがいいんだろうか GoF以外のJ2EEとかマルチスレッドとか視点を絞ったパターンまでは手が出ない
>>161 必要な時に調べて使え。覚える必要は無い
163 :
デフォルトの名無しさん :2006/08/08(火) 12:54:24
>>119 の
AbstractA<抽象クラス
│
AImpl<共通実装部分
├SubclassB<差異
└SubclassC<差異
のAImpl<共通実装部分って部分ってテンプレートパターン?
どうも何パターンとかって分類するのが苦手なのよ
164 :
デフォルトの名無しさん :2006/08/08(火) 13:12:16
デザパタとか本当に使ってるの?使っていてもまわり の人が理解できてる? C++やデザパタをつかってプログラムしてもまわりが 理解できず、バグ混入の原因になっているのでは? オタクなクラス設計やデザパタ使ってるあなたが 結果的にプロジェクトを破壊するテロリストになって しまっているんじゃないの? で、実際にトラブルが起きると「こんなことも理解して ないなんて一人前のプログラマじゃない!」とか言って 自分の知識をひけらかしたり、失敗を人のせいにするん だろ。ラーメン屋の亭主みたいな融通のきかない職人 じゃあるまいし。こういう職人肌みたいな人はC++の テンプレートと共に消えてくれ。頼むから。 」
166 :
デフォルトの名無しさん :2006/08/08(火) 13:30:14
このスレに書かれている愚痴って、 もう2002年当時からずっと一緒。 プログラムのプウの字も知らない煽り屋が必死に煽ってるだけなんだろ。 無意味
10年経ってもNewbieは必ず誕生するからね。 彼らから議論の場を取り上げるのは、酷というものであろう。
2002年なら新しい方だな C++は1998年の仕様がまだ実装されてないんだから
業務でManagerと名の付くクラスは大抵ろくでもないクラスだよな。 DBConnection関係のクラスをキモくラップしただけの奴とか。 これを共通で使ってくださいとか指示されると萎えるw
171 :
デフォルトの名無しさん :2006/08/08(火) 23:20:46
みんなクラス抽出ってどうやってんの? ユースケースから名詞を全部抜き出して一つ一つ吟味したり、 boundary,control,entityって分類分けしたりする? 仕様書が完璧に出来てるならやってもいいけど、 仕様書が完全になるの待ってたらいつまでたっても仕事に取り掛かれないし、 仕様変更のたびにそんなんやってらんないよね。
別会社から引き継いだソースを設計チームでレビューしてたときの話。 ソースの中に簡単なFactoryパターンが含まれていたんだが、 一人だけFactoryが分からないやつがいた(年齢だけでいえば中堅)。 まあパターンを知らないってのは別によい、知らなくてもコードを 読めば何やってるか分かるはずだからな。 と、みんな思ってたんだが、いくら説明しても伝わらない。 細かく聞いていったらどうやら継承とインスタンス化の違いが分かっていなかった ということが判明。 そんな人を設計から外す方法を相談させてください。
継承とインスタンス化の違いを説明できないのもヤバイと思う
分かってないポイントが遥か手前だと、そこから全て教育するのがマンドクサい
職場の愚痴か、せいぜい教育方法の話だしな。 無理に設計に絡ませると、「馬鹿でも分かる、かつOOを生かす方法とは?」になるか。 最近流行のDIが近い回答か?
本人、解ってない事は判ってるんだろうか?
179 :
デフォルトの名無しさん :2006/10/05(木) 13:05:29
( ゚д゚ )
180 :
デフォルトの名無しさん :2006/10/06(金) 22:17:05
Javaなんだが、フレームワークが乱立してる昨今。 フレームワークそのものはOOしないで高速にして欲しいと思う。 Hibernateとかは内部はMapで公開するときだけBeanらしいし 何は無くともちょっぱやってのをコンセプトにしたフレームワークが欲しい。
( ゚д゚ ) ( ゚д゚ ) ( ゚д゚ )
>OOしないで高速に な、なんだってー(AA略
183 :
デフォルトの名無しさん :2006/10/10(火) 19:12:27
package privateとかfriendとか使えば 公開部だけをOOにしたnew最小限ロジックが描けるけど 世間ではこういうのってタブーなのかね
( ゚д゚ ) ( ゚д゚ ) ( ゚д゚ ) ( ゚д゚ ) ( ゚д゚ ) ( ゚д゚ )
>>180 Javaって時点で速度犠牲にしてんだから
C言語のフレームワークとかw
おまえら フレームワーク って何?
frameとworkを組み合わせたまんまの意味だよ。 枠組みの中での仕事。その作業が出来る環境が用意された中で仕事する。
プレハブ住宅のイメージだにょ
ワークフレーム?
>190 逆なのは和訳の方だろw
192 :
デフォルトの名無しさん :2006/10/28(土) 00:05:34
インテグレーション層とビジネス層のインターフェイスの話なんですが、 ビジネス層の記述としてどの設計が一番合理的ですかね? /* データオブジェクトにはいかなるロジックも載せないぞ、と */ public Member addMember( String groupname, String membername ) { Group group = this.integration.getGroup( groupname ); this.integration.assignMember( group, membername ); return group.getMember( membername ); } /* データオブジェクトがなんでもやっちゃうぞ、と */ public Member addMember( String groupname, String membername ) { Group group = this.integration.getGroup( groupname ); group.addMember( membername ); return group.getMember( membername ); } /* データオブジェクトはデータソースにはアクセスしないぞ、と */ public Member addMember( String groupname, String membername ) { Group group = this.integration.getGroup( groupname ); group.addMember( membername ); integration.updateGroup( group ); return group.getMember( membername ); }
テーブルとある程度等価なJavaBeansと DBへの問い合わせメソッドを記述したインタフェースを 用意するのがDAOパターンじゃなかったっけ? こうしておくと分業体制のときにスタブが作れるし レイヤーを分けることによる保守性の向上にも役立つ利点があったはず。
194 :
デフォルトの名無しさん :2006/10/28(土) 16:36:01
>>193 関連を考慮しないのであれば、それだけでよいのですが。
Member が Group に所属する、というような構造があった場合に、
その関連をどの部分で扱うかということです。
テーブルと等価な JavaBeans を DAO で get した場合、
例えば、
Group group = dao.get();
としても、得られるのは Group の情報だけだとすると、
Member のリストを得るような処理は、どこにどのように入れるのが妥当なのか、
という問題です。
ドトネトの話なんだけどさぁ。OOPのはどれ読んでもデザパタ使ってポリモすればクラスの拡張も楽チンだよぅって 書いてあるけど、クラスのDLLだけ増やして済むならその通りだけどさぁ。 実際はクラスが増えれば結局参照の追加やビルドのし直しが発生するじゃん? そこらへんまで書いて説明してないよね。クラスと実ファイルの構成まで説明してくれよ。ビルドやり直すんなら 単一ファイルのでっかいクラスでもいいじゃん、てならね?
>>195 えーと、それはモデルと実装がゴッチャになってるだけなのではないかと思いますが?
197 :
195 :2006/11/18(土) 11:07:44
>>196 ゴッチャというか、でも実装を考えないでモデリングしたって意味ないじゃん?
例えばファクトリパタンでクラス生成のクラスをFactory.dllとして機能クラスがbuhin1.dll、buhin2.dll
ってあったとしてbuhin3.dllを増やしたら関係ないbuhin1.dllとクライアントもビルドし直しじゃん?
そんならclass.dllにまとめて放り込んでこいつのビルドだけでってのもアリなんじゃって
気がするけどこれは実装のデザパタ?みたいのからは外れちゃうんだしょ?
こういった場合の良設計パターンを教えてくださいまし。
ようしらんけど、怒涛熱湯って、必ず、1クラス1DLL なの? 自分は Java しかしらんけど、Product 抽象クラスなり、 インターフェイスを作れば、具象クラスがいくら増えようが、 利用側は再コンパイルはいらんと思うのだが、 怒涛熱湯はそういうことはできないの? つうか、Product を抽象化できないなら、 Factory のありがたみは半減のような・・・。
199 :
195 :2006/11/19(日) 18:53:40
>>197 の訂正
>関係ないbuhin1.dllとクライアントも
↓
関係ないFactory.dllとクライアントも
>>198 > ようしらんけど、怒涛熱湯って、必ず、1クラス1DLL なの?
いや、一個のdllにまとめてもよいけど、そうすると一箇所のクラスの修正だけで
アセンブリ(dll)のバージョンが上がってしまうからどのクラスが修正されたか管理上
わかりにくいよね。
> 自分は Java しかしらんけど、Product 抽象クラスなり、
> インターフェイスを作れば、具象クラスがいくら増えようが、
> 利用側は再コンパイルはいらんと思うのだが、
> 怒涛熱湯はそういうことはできないの?
逆に俺はJava知らんけど、ドトネトはベースクラスで変数を定義してても実際にインスタンス化
される実態のクラスが含まれるdllを事前に参照しておかないと無理。
つまり言葉のまま参照設定が必要。遅延バインディングでできなくはないけど普通やらない。
VS2005からは複数のdllとかのファイルを一個にまとめる機能が付いたみたいだけど、それは
提供上の管理性とかが主眼でこれの問題とは別箇だからなぁ・・
っていうか、ファクトリパターン使うなら遅延バインディングにしないと意味ねーじゃん
201 :
デフォルトの名無しさん :2007/01/15(月) 01:10:51
シナリオ制御をうまいことやんのはどうすんの?
も少し具体的にいったほうがいんじゃね?
203 :
デフォルトの名無しさん :2007/01/30(火) 23:09:50
オブジェクト指向プログラム初心者なんですけど 悩んでるんでアドバイス頂けませんでしょうか? 良くあるケースだと思うのですが DBに、n:nの関係の2つのテーブル(AとB)があって、 間に、お互いのIDの主キーにした関連付け用テーブルCがあるとして Bのテーブルの、あるIDとあるIDを持っているAの列(カラムは全部)取得した時、 結果を配列(又は配列オブジェクト)で取得するじゃないですか? で、しかもCにある情報も使いたい時って取得した配列を回して、 また、DBにCの情報を要求しなきゃならないじゃないですか? 例えば食べ物屋(テーブルA)をメニュー(テーブルB)で検索して、 メニューそれぞれの値段(テーブルC)も取得する時、などをイメージしてもらえると良いと思います。 この時shop_classに色々な条件で検索して配列を返すメソッドを実装するのが良いのでしょうか? 私が思いついたのはshop_classには一件分の店データ(店データと複数のメニューデータ) を取得するメソッドのみを実装して、別のクラス(例えばshop_search_class)で関連付けテーブルから 条件にあった店のIDのみを取得して、その配列を回してshop_classのメソッドを実行して最終的な データを得るのは方法なのですが、変でしょうか? なんか無駄なDBへの問い合わせが一回多いようにも思われるし、 すごい感覚的な物なのですが、 一件分のデータを得るクラスと複数の店を検索してリストを得るクラスを 同じクラスにするのになんか抵抗があった物で。 ご意見ありましたらお願い致します。 長文すいません。
204 :
デフォルトの名無しさん :2007/01/30(火) 23:26:34
>>203 の言わんとしていることが
分かった奴、いるか?
>>203 A=店マスタ、B=商品マスタ、C=ラインナップテーブルで
A:Cが1:N、C:Bが1:Nに見えるけど、認識違い?
基本はCに対してSELECTかけてAのIDのリストを得ると思うし
詳細検索ならBを絞り込んでから、検索条件としてのCのリストを得て、そこからAのIDリストを得る。
内部的なSELECT回数は別として、SQLだけならひとつだけでいけると思うが。
>>203 駄文で読むの疲れるから、流し読みしたんだが言ってることはわかる
つまり彼はRDBを否定する考えの持ち主
>>202 文章もプログラムもセンスないね
この小学生の文章はなに?新入社員?
読ませる気がなくてあれを書いたのなら君は大物だ
>DBに、n:nの関係
n:nじゃなくてUMLに則って*対*のほうがいいと思う
以降、何の罪も無い
>>202 を哀れむスレとなりますた。
>>203 DBを使う場合、プログラムで何度もSELECTするよりも結合を使って
一回でやったほうが速いと普通思うので、配列に一度いれてからSELECTする
のはあまりやらないかも。
あと、クラスは、テーブルをベースにするのではなくて、検索結果をベースに
したほうよさそうですね。
その例だと、shopの配列を持つクラスとして、メソッドで検索条件を渡す感じで
よいか思いますが。
副問い合わせって今でも遅いの? 見やすいからテーブル結合よりそっちのがメインなんだよね
>>209 スレ違いな気もするが
DBと流すQUERYにもよると思うが、そんなに変わらないと思うけどね
211 :
203 :2007/01/31(水) 08:51:59
>>205 >>206 >>208 レスありがとうございます。
ちょっとすれ違いな話になってきちゃいましたが
例えば商品Xを扱っている店とその店が扱っている全ての商品、
店1(商品X・商品Y)
店3(商品X)
店6(商品X・商品S・商品Y・商品Z)
↑こういうの取り出したい時って一回のSQLでいけるんでしょうか?
だとしたらSQLの勉強不足と言うことで、悩みは一気に解消なのですが。
DB版行った方がよさげですか?
>>211 副問い合わせやGROUP_CONCAT()を使えばできますが
ここよりはSQL関連の質問スレへほうがいいかも
213 :
211 :2007/01/31(水) 12:36:44
>>212 ありがとうございます
GROUP_CONCAT()というのは知りませんでした。
というか、使ってるのがpostgreSQLなんですけど、
ちょっと調べてみたらpostgreにはないっぽいですね。
自作関数を実装しなきゃならないようです。
どっちにしてもすれ違いなので、SQLの方に行ってみます。
皆さんお世話になりました。
>>213 >自作関数を実装しなきゃならないようです。
せっかく
>>212 が指摘してくれた
「副問い合わせ」の件は無視かよ・・・
ま、ご自由に(w
しょしんしゃって おもしろいよね おれもそんなじきがあったのかなぁ
どんな要素技術についても、全ての人は初心者であった時期はあるだろう。 世の中の要素技術全てについて初心者を脱却した人なぞおらん。 ということはもう新たな要素技術を知る必要のない立場/ポジションにいるわけだ。
delegate event modelとobserver patternの違いがわかりません><
呼び方が違うだけじゃねーの?
俺、オブザーバーパターンはsubjectとobserver、2つの要素があって、 observerがイベントを監視し、subjectに対しイベントに変更があったこと通知、 そして、subjectが他のobserverに通知。 なんて教えられたんだけど このぐらいの変更なら許容範囲?
subjectが、自分が変更されたことをobserverにつうちするんだぞー observerがsubjectへ変更を加える事があっても、subjectに 何かを通知する事はない もっともobserverが別のobserverのsubjectなら話は別だが
ふむむむ・・・・・・・・・
223 :
デフォルトの名無しさん :2007/05/13(日) 22:19:14
Swingアプリの設計って一般的にはどうなってるんでしょうか? Observerパターン使ってViewがイベントを受け取ったらControllerに渡して、ControllerからServiceを用いてデータ操作→Modelに加工して保存→通知してViewのリペイントって感じですか? 単純なSwingアプリでModelとかServiceってどういう役割になるのか分かりません。Modelの役割ってどういうものなのか、実例を見てみたいのですが。。。経験が全く無いので困ってます。どなたか設計の勉強になる本とか教えて下さい。。。
224 :
デフォルトの名無しさん :2007/05/13(日) 23:58:46
一時期デスクトップでも自作よりショップブランドとかDELLの方が安く付いた時期あったけど、 最近は明らかに自作の方が安いよね。とC2Dマシンを組終えてMemtest中の俺が流れを無視して言ってみる。 E6600、メモリ1GBx4、HDD320GBx4、GF7900GS、電源550W、ケースだけ古いSongcheerを使い回し。 最近アキバはキモいのでツクモで一括通販。 この組み合わせで16万ちょいなんてDELLじゃ絶対ムリ。 ま、確かに超ローエンドだとキーボードとか他のパーツが占める割合が増えるから結果として安いけどね。 特にハイスペックでなくとも容量なんかが欲しければ自作の方が安い。 嫁もIntelMacになってMacに見切り付けたみたいだから次は安く上がるなw 元がMac G5だからお下がりのP4 3Ghzでも速く感じるだろうwww
誤爆か?
次はどんな自作嫁を投下してくれるのか楽しみだ
大きなおっぱい
228 :
デフォルトの名無しさん :2007/05/18(金) 12:24:33
プラガブル MVC を Java で説明してくれません?
interface
230 :
デフォルトの名無しさん :2007/06/15(金) 08:33:51
C++で非決定性有限オートマトン(NFA)のクラスを作りたいと思っているのですが、 なかなかいいアイデアがまとまりません。どこか良いサイトや何かよいアイデアありましたらお願いします。 ちなみに今考えているのは、 CState 状態S。次の遷移先を教える。CEpsilonとCDeltaの派生CDeltaMultiple、CDeltaRangeを複数保持。 CEpsilon イプシロン遷移。複数の遷移先(CState*)を保持する。 CDeltaMultiple 複数の遷移条件で一つの遷移先(CState*)を保持する。 CDeltaRange ある範囲の遷移条件で一つの遷移先(CState*)を保持する。 CStateChart 複数のCState*を保持管理する。最初の状態S0を教える。 CAutomaton 一つのCState*を保持する。 CAutomata 複数のCAutomatonを管理する。CStateChart*を持ち、入力(シグマ)に応じて適切な状態を持つCAutomatonを生成する。 このような感じになっています。 しかし、これだと入力(シグマ)の型によってテンプレートにしてソースを晒したりしなければいけません。 よろしくお願いします。
なんに使うんだそんなもん
C++で書いてます。クライアントクラスの管理をしたいのですが、 管理されるクライアントクラスはnewで動的に生成されるという物です。 また、マルチスレッド環境での使用も考えています。 class client{ client_management *cmgmt_; public: client( client_management *cmgmt ):cmgmt_( cmgmt ){ cmgmt_->add( this ); // 排他処理はcmgmt内で } void haandle(){ //クライアントとの通信とか、いくつかの処理 //処理終了で、クライアントと切断後、 cmgmt_->remove( this ); delete this; } }; これをserver側で class server{ client_management cmgmt_; void listen(){ socket sock = accept();//clientクラスのオブジェクトを返す new client( &cmgmt_ ); } }; こんな設計しか思い浮かばなかったのですが、特に new client( &cmgmt_ )の部分とかdelete thisな部分が嫌な感じがします。 よりベストな設計を伺いたいです。よろしくお願いします。
>>232 とりあえず設計に関して。
clientがclient_managementを参照するのは良くない。
(少なくとも非constのポインタを持つのは良くない)
clientがclient_managementを知っている必要を感じない。
clientのインスタンスをclient_managementに追加するのは、
今回の例ではserverクラスで行うのが妥当か。
例えば、
client* ptr = new client;
cmgmt_.add(ptr);
clientの削除を行うのも、client_managementに行わせる。
そうじゃなければ何のためにaddしたのかわからん。
複数のclientの管理を統括するためでしょ?
delete this;は色んな意味でありえない。というか最悪。
大体、ptr->haandle();の後、ptrが使えなくなるとは絶対誰も考えないから。
その他
socket sock = accept();//clientクラスのオブジェクトを返す → socketが返っているようにみえる
new client(&cmgmt_); →思いっきりメモリリーク
haandle()メソッドが長い。複数のメソッドに分割すること。
haandle()というメソッド名を見ても何をするメソッドかわからない。
命名が気に入らない
→cmgmtを見て、client_managementだとわかったらエスパー。
→メソッド名、クラス名、一時オブジェクト名の区別がつかない。
どういたばしく
ここで質問するのが適切かどうかはわからないのですが、 よくいうビジネスロジックってどういうものを言うのでしょうか。 staticで提供されているユーティリティメソッドなどはビジネスロジックではないのなら、 どういう観点で見てどういうくくりでこの処理を行うビジネスロジッククラスと設計すればいいのでしょうか。 なんとなくはわかっているんですが、なんかしっくりこないんです。 また、ビジネスロジッククラスに作成するメソッドをどのビジネスロジッククラスにコーディングするかは どのように決めればいいでしょうか。ユーザーに関連する処理だからこのクラスとか、分け方が理解できません。
>>237 レスありがとうございます。
読んでみると意味はわかるのです。ですが、それを実際にかたちにすることができません。
こんなレベルでも実際に仕事をしています。私の会社ではこれらを全て同じクラス内にコーディングするのです。
実際に要件から設計、コーディング、クラス設計を学ぶことができる書籍などはないでしょうか。
書籍を読んでも疎結合だとかビジネスロジックは分離だとか、いろいろ書いてあるのですが
自分の仕事でうまくやることができないのです。
> 実際に要件から設計、コーディング、クラス設計を学ぶことができる書籍などはないでしょうか。 どうしても自分で設計したければ、 大き目の本屋に行ってオブジェクト指向 に関係ありそうな本を片端から買って読む。 多分100冊も無いと思う。 その上で、実戦を10回くらい経験すれば なんとか人並に設計できるようになると思う。
240 :
デフォルトの名無しさん :2007/11/01(木) 21:38:01
AOPなどを使えない環境で、DBコネクション管理、コミット/ロールバックを制御したいのですが、 どういった方法が最善なのでしょうか。メソッドを細分化するのはいいのですが、引数にDBコネクションを必要とする場合が多くなってしまいます。
springのトランザクションマネージャ使えば? それも使えないならスレッドローカル変数をつかって トランザクションマネージャを自作
242 :
デフォルトの名無しさん :2007/11/08(木) 22:48:52
ビジネスロジッククラスのインターフェースを考える場合に 業務フローからメソッドの定義を考えるのはおかしいでしょうか。 インターフェースを人に書いてもらえば実装はいくらでもできるのですが、 いまいちこのレベルまで落とし込む方法がわからずこまっております。
>>243 ありがとうございます。書籍を購入して勉強はします、が、、、
ほかにもいろいろ調べたりしなければならないので時間がとれなそうです。
ひがさんのblogは書いてあることの意味はなんとなくわかるのですが、
実践にもっていくには私には少し?難しいようです。
245 :
デフォルトの名無しさん :2007/11/12(月) 22:36:59
Http通信で、レスポンスがcsvだったりxmlでURIごとにいろいろなパターンを返すのですが、 この場合、View用の抽象クラスを用意してそれをパターンごとにsetterを用意しようと考えています。 もっとよいアイデアがあれば教えてください。
Http通信ワロス
おかしくもなんともないな。
>>245 同じデータを複数のフォーマットで返せるサービスなのか、
システムで使われるレスポンスデータが複数あるのかどっち?
後者なら設計のコンセプトを知りたい。
それ、HotJava (α)時代から提供されてる機能だから。
249 :
デフォルトの名無しさん :2007/11/15(木) 23:16:14
JavaなんだけどService Provider Interfaceスタイルをとる為に 特定の引数を持つコンストラクタをリフレクションで探すのってダメかな? ようはBuilderだけで完結させて、BuilderFactoryは作らない方法。
250 :
デフォルトの名無しさん :2007/11/16(金) 00:08:41
>>243 >ドメインロジックを()で囲っているのは、ドメインロジックを
>ドメインモデルに持たせた場合、ドメインロジックは、ビジネスロジック
この文のカタカナ率を計算せよ。
チラット見ただけでどんな人なのか全然知らないけど、
日本語をマトモに話せない(話そうとしない)ヤツは、
ろくでもないことが多い。
グラフライブラリィーを作りたいんだけど C++で書かれていて、デザインパターンを用いたお手本になるライブラリィソースって ないっすか?
boost
>>250 そいつの人間性はさておき、全然知らないってのは業界人としてどうなのよ・・・
Rubyを使用しています。 OOPの設計でとっても悩んでいます。 例えば、 壁にボールを当てる事を考えます。 壁クラス ボールクラス 投げる人クラスが あるとします。 壁にボールが当たって跳ね返ってくるのは どのクラスで実装しますか? Mediatorクラスを作るべきですか? あと、 メソッドのaugumentには 他の独自のクラスをとってよいのでしょうか? メソッドのaugumentには、 operandはおkで、optionはNO だというのがHeuristicだそうですが、 という事は、他のクラス 例えばこういう書き方をするか知りませんが method(MyClass object) のようなメソッドを実装してもいいのですか? あまりにも汎用性が失われるような気がします。
>>254 投げるという動詞が存在する以上、ThrowerとThrowableの関係はあっていい。
また、壁、玉、人らは、それぞれに衝突可能なObject(俗に言うMob)とする。
よって、おいらなら以下を土台とする。
GameField field = GameField.getInstance(); // ゲームマスター
field.add(new ConcreteWall(0,0,0,768);
field.add(new ConcreteWall(0,0,1024,0);
field.add(new ConcreteWall(1024,0,1024,768));
Thrower thrower = new ConcreteThrower();
thrower.set(new ConcreteBall());
field.startGame(thrower); // ゲームループの開始
また、以下の依存性も必要と思われる
Throwable extends Mob
Mob.collision(Mob) // ベクトルの変更のみ
この例だとGameFiledが進行を務めるから、Mediatorとは逆。
collisionの網羅前にMobにMediatorを渡すのはあり。
256 :
デフォルトの名無しさん :2008/03/08(土) 19:27:46
質問です。 設計者は開発者に対してpublicなAPIだけを 仕様として渡して、 開発者はそれをprivateなメソッドに 分解して最終的にpublicなメソッドのテストに通ればいいという事ですか?
257 :
デフォルトの名無しさん :2008/03/16(日) 23:55:02
データ形式が以下のようなブロック集合の組み合わせの場合 DATA( A or B or C or D) このようなデータを汎用的に書き出したいのですが どのように設計すればいいでしょうか。 [A,B,D]の場合もあるし[C,D]の場合もあるし かといってちまちまケース文で書き出すのは愚の骨頂だし 解らない。
というよりどういう用途・用法で扱われるのかわからないので想像しづらいんだが. 単純にビットフィールドってことでおk?
259 :
デフォルトの名無しさん :2008/03/17(月) 10:01:59
>>257 A 〜 D を自由に組み合わせて出力したいという程度ならまず、A 〜 D に
共通な「書き出し可能データ」というインタフェースを定義する。そして
A 〜 D がこれを継承する。
次に「データを書き出す人」という抽象を作り、「書き出し可能データ」の
集合(配列、リストなど)を受け取って、ひたすら書き出すようにする。
「書き出し可能データ」の集合を生成するために、制御役の抽象が必要に
なるかもしれない。
>>256 いいんじゃね?
設計者の設計粒度がどの程度かわからんけど
仕様としては外部からみた振る舞いが正しければいいわけだし
SRPについて質問です。 「クラスの変更理由を一つにしなさい」 という事は逆にいうと、 「もしクラスが変更される時はそのクラスの仕様をすべて変更しなさい。 もし変更されない仕様が混在するならばそれは変更理由が一つではない」 という意味ですか?
>>261 違います。変更理由が一つであることとクラス仕様全てを変更することに
相関はありません。
SRP は「クラスは単一の概念を表現すべし」というルールです。単一の
概念を表現するために複数のデータとメソッドが定義されるのだから、
部分的な変更をかけていく行為自体は、何ら SRP に反しません。
例えば、ある抽象概念を表現してみたものの、あとから足りないものに
気付いてメソッドを追加する、というごくありふれたケースを考えてみても、
クラスの既存仕様を壊さずに部分的な変更をかけていることが実感できる
でしょう。
あるクラスが SRP に反しているかどうか判断するには、異なる概念が
混在していないかどうかを常識的にチェックすれば良いのです。もし
混在しているのなら、それは二つのクラスに分離するべきなのです。
ただ、SRP に違反しているクラスが一概に悪とは言えないことも意識して
おくことは大切です。何事も行きすぎた原理主義はよくない。
>>262 あとから足りないものに
気付いてメソッドを追加する、というごくありふれたケース
といいますが、これはOCPが違反しませんか?
今、Head Firstのオブジェクト指向設計とかいう本を読んでいます。
そこにはSRPの例として、車のクラスを定義する場合に
そこにwashなどのメソッドを組み込んではいけないという事になっていますが、
例えば外部で
CarWasher#wash(AutoMobile)を定義した場合、
このCarWasherクラスはAutoMobileの例えばdirtというフィールドが存在している事を知っていないければなりません。
(例えばwashというメソッドがdirtを0にするものだとすると)
これは情報の隠蔽に失敗していませんか?
それに無闇にAutoMobile#setDirtを設定してこれを受け入れれば、
他でどんな悪用をされるか分かりません。
失敗した設計だと思います。
カプセル化についてどう考えていますか?
setterはなるべく実装しない方が良いように思うので、
データについてクラスを分離するのがいいと思うのですが、
この本には振る舞いについて分離せよと書いてあります。
>>263 拡張と一口に言っても、類似概念の追加と、メソッドの追加では意味合いが
違います。OCP を守るためにメソッドの追加ではなく継承で対応するの
では本末転倒でしょう。原則は絶対ではないのだから、柔軟に対応すれば
いいと思いますよ。
その本は読んでいないので状況が良くわかりませんが、車クラスが wash
を提供するべきではない理由が書いてあるのではありませんか? 車の主要な
責務は「人を乗せて移動する」であるとかなんとか。
まあ、いずれにしてもいい例ではない気がしますが、クラスでは概念を
完全に表現することができない以上、どこかに軸足を置く必要がある
わけです。それが「洗う」なのか「走る」なのかは目的によって変わって
くるでしょう。
カプセル化は言うまでもなくとても重要ですね。
大切なのは、自分が表現したいものをはっきりさせることです。そうすれば
自然と必要なデータや振る舞いが備わっていきますよ。
>>263 CarWasherクラスがAutoMobileクラスのdirtフィールドを知ってなければならない
のは当たり前。
そもそも、洗車機は車の存在を前提に作られるし、皿洗浄器は皿の存在を前提
に作れる。何を?どうする?の2つを知ってないと「する側」は作れない。
てか、洗車は例えとして分かり難いぞw
そもそも「汚れ具合」が定義されていなければ「洗う」ことも「汚れる」ことも定義できない.
267 :
デフォルトの名無しさん :2008/05/22(木) 06:02:42
OOPに最近参入した新参者です。 設計(特にクラスの設計)に関するオススメの書籍何かないでしょうか? 例えばショッピングサイト、レンタルビデオショップなどわかりやすそうなものから考えていこうとしたものの OOPへの理解が浅いせいかどうにも戸惑ってしまっています よろしくお願いします
>>267 デザインパターンとともに学ぶオブジェクト指向のこころ
MVC分割したときにUndoのロジックってModelの実装領域になると思うんですが、 大抵このUndoってコマンドパターンとかで実装されますよね? このとき、Modelに対する変更命令が全てコマンドで実行されることをコードレベルで保障するには、 Modelに対する変更命令を受け取ってコマンドを発行するクラスを作って、 更にModel内部のデータ構造に対するアクセスを制限するための 読み取り専用ラッパークラスを作って外に公開する、という感じになるのでしょうか? 実際このようなことって業務レベルの開発では行っていたりしますか?
>>267 個人的に、リファクタリングの実践が一番身に付きやすいと思う。
フリーソフトとかのソース落としてきてやりまくるといい。
ということで
・リファクタリング
実験で使用するシリアルポートから遠隔操作できる 温度調節機能付きの水質モニターを管理するプログラムを作りたいと思っています 1分毎に水質データと水温を取得する PCから温度の管理値を変更できる という機能を実現したいのですがこの場合 ポートの開閉やデータの送受信を管理するCommクラス 水質データの受信要求や管理値の変更命令をCommオブジェクトに送る、水質モニターの機能を実現するMonitorクラス Monitorオブジェクトから値を受け取り実際に表示するGUIクラス GUIがMonitorの参照を保持して MonitorがCommの参照を保持する このような構造でよいのでしょうか?
272 :
271 :2008/06/20(金) 00:31:37
それとも Monitorクラスの定期測定と管理値の変更は別のクラスの振る舞いにしたほうが良いのでしょうか
>>271 いいと思います。あとは、水質モニターのマルチベンダー化や多重化等が
確実なら、事前に拡張性を考慮するのもあり。
>>273 ありがとうございます
あと、新型のモニターを使用する場合も考えると
拡張機能を実装しやすいようにデコレータにしておいた方がいいですかね
>>274 数ヶ月以内に新型が導入されるならね。さもなくば、シンプルに徹する。
肝心なこと聞き忘れてました 二つの値を一つの文字列に合成してシリアル通信するのですが この命令の合成と返答の翻訳はMonitorとCommクラスどちらに実装するべきでしょうか 質問続きで申し訳ありません
>>276 "二つの値Constructor"に任せればいいんじゃない?
もしくはMul/Demultiplexerとか?
>>276 Comm クラスは汎用的なシリアル通信だけを行うユーティリティクラスで
いいんじゃないかな。制御プロトコルの知識は Monitor に持たせる。
>>276 おれだったら、合成と返答の翻訳を行うクラスを別途作るかな。
>>279 >おれだったら、合成と返答の翻訳を行うクラスを別途作るかな。
メッセージI/FとパーサーI/F又はどれか一つ用意して
メッセージの詳細はベンダー毎に実装するのが一般的かと思う。
281 :
デフォルトの名無しさん :2008/08/08(金) 03:31:53
>>271 ちょっとOO分析っぽいことやってみたかった.
# [実験]で[使用する][シリアルポート]から[遠隔操作できる]
# [温度][調節][機能]付きの[水質モニター]を[管理する]
# [1分毎]に[水質データ]と[水温]を[取得する]
# [PC]から[温度]の[管理値]を[変更できる]
必要な名詞(オブジェクト)
シリアルポート,温度,水質モニター,1分毎,水質データ,水温,温度,管理値
足りない名詞
タイマー
必要な動詞(メソッド)
操作,調節,管理,取得,変更
ここまでやったけど別に何を作ろうというわけではない
温度がオブジェクトかよー 1分毎もかよー 水温・温度もかよー。
当たり前すぎますよねー^^
284 :
デフォルトの名無しさん :2008/08/20(水) 20:05:43
クラスの設計に関して悩み中です。 例えば以下のような必要とされる要素が有ったとします。 (要素内容はでたらめです。) ・コード/名称/メッセージ/結果/色/高さ/幅 /追加日/更新日/削除日/…(全部で20要素ぐらい) 処理1 … コード/名称/メッセージ/結果 処理2 … コード/結果/色/高さ/幅 処理3 … 結果/色/更新日 処理4 … 削除日 各処理は、クラスに個別分類できる処理になり、各処理に少しずつ上記要素が 絡んでくる状態になります。 このような場合、どのようなクラス設計が適していますか? 現在は、コード/名称〜などの20要素ぐらいをBaseクラスにして、 処理1〜4までを継承させています。 ただ、こうすると必要の無い要素まで入ってしまい、もっとすっきり させたいなと思っています。
>>284 > ただ、こうすると必要の無い要素まで入ってしまい
この時点で継承を選ぶのがおかしい。意味のある単位に切り分けよう。
問題の切り分けじゃなくて、登場人物の切り分けを意識した方がいい。
例えば色/高さ/幅ってGUI上の属性情報なんじゃないの?
処理1と処理4でそれらの情報を使用しないってのなら、
ぱっと聞いただけでも処理1〜4は継承関係上の兄弟とは思えない。
> このような場合、どのようなクラス設計が適していますか?
適切な切り分けの単位は要件仕様やその他の背景によって異なるよ。
とっかかりがないなら、それらのデータモデルを構造体化して、
処理の引数に渡してしまえばいい。
>>285 どうもです。
いえ、GUIの属性とかではありません。
サーバーへコマンドを投げると上記の値が返ってくるイメージです。
処理1なら
1.「コマンド処理1」をサーバへ送信
2.「コード/名称/メッセージ/結果」がサーバより返ってくる。
3.処理1の処理を行う。
処理2なら … と同じ様な処理が複数あります。
サーバーにコマンドを投げるとかいつ説明したよ。
それで相手に適切なクラスの分け方を聞いたわけ?
一応必要なアドバイスは
>>285 に入ってるから、熟読して悩め。
>>286 の情報だけで何を悩めばいいかを挙げるなら以下くらいかな
・全ての処理で共通する送受信データの基本情報(必須情報)って何なの
・送受信データ全体を木構造に表すとどうなるの(構造体のメンバに構造体を持つかなど)
・送受信データに対して、それを継承するって適切なの
(データモデルとビジネスロジックは普通分けるがね)
恐らくだが、以下みたいな感じに落ち着くんじゃないか
・処理1,2,3,4ってのは、データモデルを引数に受ける関数ポインタ(Javaでいうリスナ)になる
・コマンド処理1,2,3,4と関数ポインタ(Javaならコマンド名のgetterとリスナをセットにしたクラス)と
送信データを引数とし、受信データを戻り値とする通信クライアントクラスが必要(C++なら受信データも引数で受ける)
・送受信データ中、基本情報以外の情報(構造体メンバの構造体)で使用しないものはNULLを入れる
基本情報以外が後からいろいろ増えるなら拡張情報をMapで持つ手もある。シリアライズ(デシリアライズ)がいるが。
最近の流儀だとXMLを使うのも悪い手ではない。(個人的にはJavaやC#ならこれにするな)
あなたのプロジェクトの答えを書いたつもりはないので、参考になるなら参考にして、後は悩め。
訂正 ×受信データを戻り値とする ○受信データを関数ポインタの引数にしてその関数を実行する
ちょっとここの主題とずれるかもしれませんが、 ブラウザ - Webサーバー - APサーバー - DB という一般的な構成でのエラーチェックで質問です。 入力データのチェックをするときに、未入力や不正文字はMVCのCで チェックして、DBに問い合わせないとわからないチェックはMでいいですよね。 注文入力をするときに、数量の未入力は前者、在庫チェックは後者です。 でですね、「数量の上限」や「不可能な注文の組み合わせ」みたいに 「ビジネスロジックだけどDBに問い合わせる必要はない」というチェックは APになげると余計な通信が発生するのでWebサーバーでやろうと思ってます。 Webサーバー側のpackageには原則Actionクラスしかないのですが、 このpackage配下にチェッカークラスを置くのに違和感を感じます。 注文形態が複雑でActionがいっぱいあるので、注文BaseActionを 作ってTemplateMethodパターンでフローを決めてるのですが、 だらだらとバリデートを書くのもフローがわかりにくくなって嫌です。 注文クラスそのものに書くべき?
TemplateMethod 使ってるなら、BaseAction に空の Validate メソッド 用意してフローに組み込み、具体的なチェック内容は派生クラスで実装 すればいいんでないの? なぜ「だらだら」になるかが知りたいところ。
そこまではやってるんだけど、さらにその中で「注文条件がこれだったら これは不可で」「数量をparseして文字列だったらこのエラーメッセージで」 みたいな処理が10以上あって、ロジックは共通なので、その個別のValidateを BaseActionに書いてたんです。個別Validateのどれを呼ぶかは Actionによって異なります。で、このチェッカーって切り出すべきだと 思うんだけど、actionパッケージの下にチェッカークラス置くのって 変だよなーと思って相談したわけです。
だらだらなのはBaseActionに個別のValidate処理がいっぱい並んでたから。 わかりにくかったですね。すいません。
なんとなく状況は把握できた。俺なら BaseAction には単一の Validate メソッドだけ用意し、チェックメソッドは別クラスにまとめる。たぶん、 このチェッカークラスは stateless になるんじゃないかな。 派生クラスではこのチェッカーを使って個々の Validate メソッドを実装 すれば良い。チェッカークラスの置き場所はまあ、プロジェクト的な決め事 でしょう。
そうなんだよね。 今は各Actionクラスの処理の切り出しのイメージだったから 個別ValidatorでsetFieldError()してるんだけど、チェック処理の 多さからいって全public staticなクラスに切り出すべきだと思ってる。 すでにリリースされてるプロジェクトの機能追加なのであまり リファクタリングしたくないんだけど。 で、最初の質問に戻るんだってば。actionパッケージの下には actionクラスしかなく、serviceパッケージの下にはリモート呼び出しを 前提としたクラスとそのドメインオブジェクトしかない。 今後のプロジェクトではserviceクラスのメソッドにアノテーションつけて ローカル実行とリモート呼び出しを分けられるようにしようかと思っていた。 そうするとやっぱ今回もあるべき論的にはserviceパッケージの下に ローカル実行用のサービスクラスをつくるのかな。でも単純な未入力チェック みたいのはコントローラーでやるべきだと思うし、うーん。
やっぱり、どの個別Validatorを呼び出すかみたいなロジックが Actionに入ってることがそもそもおかしい気がしてきた。 あ、いやでも注文形態によって入力パラメータの数が違うから 未入力チェックを行うならActionか。 もしかしてstrutsみたいに各フィールドのセッターでvalidationしよう っていうのが間違っているのか? Action -> 個別注文クラス生成 -> 個別注文クラス#Validate()呼び出し → OKならリモート注文ServiceのValidate()呼び出し こうするとすごくスッキリする。略してスッキる。ActionはModelの 生成だけでロジックにはノータッチになるし。チェッカークラスが 複雑で外だしにするとしても、個別注文クラスと同じpackageに いれればしっくりくる。略してしっくる。ドメインオブジェクトがアクセッサしか 持っていないようなドメインモデル貧血症なつくりにはしてないからね。
あげ
297 :
デフォルトの名無しさん :2008/11/27(木) 14:40:57
パブリックヘッダファイルとプライベートヘッダファイルの違いが分かりません、 パブリックヘッダファイルで提供する関数と内部で使う関数の分け方すらわかりません。
OOP以前の問題だな
パブリック複合
テンプレート・メソッド パターンの多階層継承はマジ勘弁。 追いづらい。 IService ← テンプレート・メソッド パターン ↑ AbstractLogic ← テンプレート・メソッド パターン ↑ BaseCollectLogic ← テンプレート・メソッド パターン ↑ FileBaseCollectLogic ← テンプレート・メソッド パターン ↑ DomainLogic カスが
それはやりすぎというより、なんか設計がおかしい気がする。
エントリーポイントを増やすのが目的なんだろうけど、 うざったいってのはよく分かる。 IService ← テンプレート・メソッド パターン ↑ AbstractLogic ← テンプレート・メソッド パターン ↑ DomainLogic としてBaseCollectとやらはコンポジションでもっとけと。
問題ない。次
IService はインターフェースで Run メソッドが定義されてる。 クライアントは、 DomainLogic dl = new DomainLogic(); dl.Run(); あれ?スーパークラス使わないの? IService はどうした? IService は? カスが
で、お前ならどうしたいのよ
黙れカスが
で、お前ならどうしたいのよ
309 :
デフォルトの名無しさん :2009/01/25(日) 05:15:15
>>1 > 全部publicでいいじゃん!ってならないようにするスレです。
あーあorz
プログラミングまだまだ初心者で、C#勉強している途中だけど、
このスレ開いて、
>>1 を読んでしまった・・・。忘れようとしても忘れられない。
意識しないようにすると意識してします。
将来プログラマになった際、仕事中「全部publicでいいじゃん」というレスが頭に思い浮かんで、
忘れよう忘れようとしても逆に頭にこびりついて、何かとんでもないミスをして入社早々首になりそう・・・。
逆に、記憶に逆らって、全部privateにしなきゃと意識するとコーディングが全然遅々として進まなかったり。
スレ開かなきゃ良かった・・・。
クラスを作らなければpublicもprivateも迷う必要は無いのだよ。
クラスベースのOOPLしか触ったことがないのですね
メンバ変数はprivateかprotectedが基本 メンバ関数はpublicが基本
>忘れよう忘れようとしても逆に頭にこびりついて、何かとんでもないミスをして入社早々首になりそう・・・。 そんな性格の人はこの職業向いてないよ。 このスレのおかげで早めに気づいてよかったね。
それは性格ではない
なる前からそんな心配してるのは性格じゃね?
人間の性質じゃないか!
>全部publicでいいじゃん!ってならないようにする こんなOOPで当たり前の常識をすぐ理解できない時点で向いてない
OOPで当たり前の常識のアクセス修飾子の存在を理解で来ていているのに OOPで当たり前の常識を理解できていないとな
メソッドの一部をpublicにしなかったとしてfriendがある時必要となったとする。おまいは その時どうしてんだ? friendにすぐにするのか。一瞬くらいは正しかったのか?って考えるだろう
320 :
デフォルトの名無しさん :2009/01/27(火) 23:36:38
てかfriendとかいらね publicかprivateで十分 早くpublic(in hoge::piyo, child)とか修飾できるようにならないかなー
>>319 クラスライブラリなら考えると思う。
実務の仕様変更で必要となったのならなにも憂慮することなく
すぐfriendにする。
最近C++やってないなあ。
Javaの同じパッケージのクラスからだけ呼べるデフォルトスコープは
わかりにくいよね。修飾子で明示的にして欲しい。
322 :
デフォルトの名無しさん :2009/02/27(金) 01:47:05
interfaceベースの設計は冗長だが作りやすいな。 迷うとinterface(規格)→abstract(ひな形)→具体クラスってのが多い。
ちょw
あるある
>>322 インタフェース指向設計にも載ってるやり方だけど、
結局、Java系OOPLの現状の中での最適解って感じで
果たしてそうあるべきものかと問われると
はなはだ疑問に感じる部分だよなぁ。
相互依存は悪!って思ってるんだけど、(C++とかだと互いにincludeしあってとかで) 今考えてるもので、なんか結局相互依存しちゃうクラス関係orz。 今考えてるのは、ネットワークプログラミングで、 コネクションを表すclass Connectionがあって、これをベースに class ServerConnection, class ClientConnectionがある。 で、こいつらを一つにまとめておくコンテナで、 class ConnectionManager; というものを作った。 最初に、 ConnectionManager ConnMgmt; ServerConnection SConn( ConnMgmt ); とかやって、 //コンストラクタで自分を登録 ServerConnection::ServerConnection( ConnMgmt ){ ConnMgmt.Add( this ); } void ServerConnection::Accept(){ //ここで、サーバーソケットに接続してきたクライアント用のインスタンスを生成 ClientConnection *CConn = new ClientConnection( Socket_.Accept() ); //で、このクライアントコネクションをコネクションマネージャに登録するのに、 ConnMgmt_.Add( CConn ); } みたいな、ConnectionManager <-> Connectionで相互依存っぽい気がする。 何か解決方法はないっすかね?
>>326 徹夜明けでjavaerの俺からすると
とりあえず
・ServerConnectionはそもそもConnectionなのか
・ServerConnectionの作成はServerConnectionFactoryにしたほうがよさそう
あとManagerなのになぜにMgmtなのか不思議
328 :
326 :2009/05/12(火) 20:53:27
徹夜明け乙でレスってくれてうれしいんだけど、 聞きたいのはそこじゃないw
そのサンプルだけから判断するとServer側はServerSocketでConnectionじゃない。 ServerSocketとClientConnectionはManagerを知らなくていいんじゃね? 利用側のクラスをConnectionEventListenerの派生にして ServerSocket.AddListener(this); EventLisner#doEvent()の中でMgmt.Add(ClientConnection); Managerはシングルトン
330 :
デフォルトの名無しさん :2009/05/20(水) 00:32:18
PCからマイコンを経由して表示機(7セグLEDやLCD等)を制御します 表示機クラスとして抽象化するとして、表示関数のインターフェイスについて質問があります 実際に使用する表示機は 7セグLEDなら1行4文字 LCDならサイズによって異なりますがY行X文字 これを踏まえると void myPrintf(int X , int Y , const char str); という形にして1行しか表示できないユニットに関してはYを無視する形にすればいいのかなと考えます。 しかし、今後カラーLCDを使用したり反転・点滅等のエフェクトを追加しようとすると void myPrintf(int X , int Y , const char str , int color , int effect); と、7セグLEDのような単純な表示機では使わないような引数がどんどん増えていってしまいます。 しかもインターフェイスに変更を加えることになってしまうのであまり宜しくないようにも思います。 こういう場合どういう風に設計すれば良いのか、今後の変更に備えるための工夫等はどうしたらよいでしょうか?
俺が(javaとかc#とかC++のテンプレのよーな機能のある言語で)作ると java: // 表示機 // L: "1行4文字"や"Y行X文字"といった機器ごとの表示位置の表現 abstract class Display<L extends Location> { public abstract void print(L location, char ch); } // 表示位置の表現(ただのmarker interface) interface Location { } // 7セグLED表示機 final class LED7Segment extends Display<Location7Segment> { public void print(Location7Segment location, ch) { location.getX()とgetY()をつかってchを表示 } } final class Location7Segment implements Location { public Location7Segment(int x, int y) {...} public void getX() {...} public void getY() {...} } // LCD->にたよーなもの. Locationは"表示の形式"ということで,もし,Windowsのウィンドウに表示するような場合などはFormatみたいな形でまとめるのもいいかも
引数を増やすんじゃなくて、コマンドを増やすべきだよな
>>330 ああ,エフェクト追加のために今後のことを考えて設計か
「エフェクト」ってのがどういう性質なのか決めないと何も始まらないので,
そっからはじめたら?
テンプレートって良くわからんよなぁ
>>331 なんておそらく難しいことはしてないと思うのだが
じゃあ、テンプレートはどういうときに使えるのか、どう実装するのか?っていわれたら自分なら全力で逃げたい
最近MVCパターンに変わってPACって言うのを良く聞くけど P→V+C C→M+α A→データ層? と言うように見えるけどPACのCに相当する部分がMVCのMに専念出来ないような +αの分、不必要な作業が肥大化していきそうに思えるのは気のせいだろうか?
>>335 まさかもう俺の考え付くソフトウェア構築モデルがあるとはしたなかった
ありがとん
Observerパターン っていうのがいまいち解らない よくModelとViewの関係で例えられるけど subjectからobserverにメッセージを送るシステムの骨組みだけ提供するから あとはそれを継承してModelとViewで好き勝手やってくれってこと?
338 :
デフォルトの名無しさん :2009/05/22(金) 21:03:48
observerは単なるコールバックの仕組みだ レベルが違う話をごっちゃにしたらダメ
>>326 管理責任はManagerにあるんだから、
Managerにジェネレータやファクトリーの機能を持たせればOKだと思われ。
>>335 ,336
PACなんて10年前からあんだろ
RADツールで作成するときとか既成のボタンとか流用するから
VとCは不可分じゃね?それにMVCのMは大ざっぱ過ぎね?
機能毎にグループ分けしてグループ間の行き来はレイヤーわけようぜ
って感じじゃなかったかな。
Web開発ならVとCはキレイに分けられるし、今はMVCつっても
サービス層、Dao層とかわかれてるしグループ分けならnamespace
(Javaならpackage)で行ってるし、PACがMVCの次の世代っていう
考え方は今は当てはまらないと思うよ。
MVCモデル自体がWEBのUI層の設計がやりにくく、 ロジック層との融合不可能な環境がでかくなった時代背景に 注目されたモデルだからね。 Delphi位に柔軟性があるRAD環境ではそれほどレイヤ間の分離を 意識しなくてよかったのはあるやね。 UIの強化、DB項目の追加、機能追加等に備えて無意識にPAC(って言うの?)的な 分けはやっていた人達も少なくはなかったけど。 VBだと何故か殆ど全部不可分だったけどw
MVCは1980年代のWebアプリなんてなかった時代にsmalltalkで発達して、 VB/Delphiのフォームにポトペタのコンポーネント思考には会わなかったけど WebではしっくりくるからWebサービスの発達と共に浸透したんだよ。 まあ確かにそれまではUIとロジック一緒にしても保守できる程度の規模の システムでしかなかったという見方は出来るけど。 Delphiが強力ったって、Delphiから入って仕事覚えた人はあんまりVBerと 変わらないっていう印象だなあ。フォームにポトペタで設計なんか考えない感じ。 クラス派生時に可視性を下げることしかできないっていうルールが 多態性とか検討するのを阻害するしね。Delphiの場合はTAbstractButtonみたいな ベースで考え得る機能をできるだけ網羅して、具象化するときに機能制限して使う。 コンポーネントのひな形を全部Delphi側で用意して開発者は利用するだけという考えなら 確かにクラス数が少なくていいけど、柔軟性にかけるよね。 あーなんか言葉足らずでうまく伝わらない気がするな。ちゃんと書くと長いからいいや。
>>343 GUIのためのMVCと、WebのMVCは全然別ものだよ。
一緒なのは名前だけ。
コピペ君って馬鹿だな、まで読んだ。
347 :
デフォルトの名無しさん :2010/03/05(金) 10:13:16
質問させてください。 EntryとEntryManagerという二つのクラスがあって、 EntryManagerが、複数存在するEntryインスタンスを生成、管理してます。 Entryが、他のEntryにアクセスできるようにしたいのですが、 そうなると、EntryManager<->Entryというお互いに依存関係ができてしまうと思います。 これは悪い設計でしょうか? また、このような場合のためのデザインパターンなどはありますか?
> Entryが、他のEntryにアクセスできるようにしたいのですが、 このような場合にインスタンスが、他の兄弟インスタンスや型を知るような依存はしたくない。 多数あるインスタンスが、多対多の関係になることは避けたい。 > そうなると、EntryManager<->Entryというお互いに依存関係ができてしまうと思います。 GoFのMediatorパターンでは、相互作用はMediatorに記述され、 ColleagueはMediatorとだけやり取りして、他のColleagueへは直接関与しない。 少なくとも一対多の関係にしておくことができる。
>>343 経験というかバックグラウンドがちゃんとあるひとなら伝わるけど
馬鹿に伝えるのは難しいよね
Delphiの強力(協力)な所は一応オープンソースな所かと。
351 :
デフォルトの名無しさん :2010/04/29(木) 21:41:13
何がしたいのかを先に言え
Bが正しいかどうかは解らないけど、Aはおかしく見えるね。
354 :
351 :2010/04/30(金) 18:37:48
色んなWebサイトの解析を行いたいです AはMFCを参考に Bはjavaを参考に考えました Webサイトの解析と、それを元に一定の処理を行うというものです 作っている段階でバージョンアップ(修正)もでてくると予想してます
IniFileという具体的なクラスをDataやOperationみたいな抽象的なクラスが 継承しているのは不自然に感じるけど、MFCにそんな構造あったっけ? もしかして、継承と関連の記号を取り違えていないか?
Cマガの人はBの設計を 「構造体に毛のはえた設計」と言ってました Cマガは現在廃刊になってます
社員研修での課題「社員管理DBのサーバークライアントプログラム」 DBーサーバーークライアントー表示 こういうのをクラス図として提出されてどうしようかと悩んだ 私の説明が端折り過ぎたのが原因だろうがこれはあんまりだ
ガンダムOO(オブジェクト指向)
DB -> なんて読む? オレは最初データベースと読んでいたが、 なんとアニメの欄にDBの文字が・・・ まさかデータベースのアニメ(!キバヤシ風) と思ってクリックしたらドラゴンボールだよ!
うんうん、自分だけにしか分からない面白いことってあるよね(にっこり
あれだよね 野球ってbatファイル ピッチャーが開始するまで誰も動かないor動けない んで、みんなピッチャーに依存してる ヒットも守備の重箱の隅をつつくようなところに打たないとでない でオブジェクト指向はサッカー 監督がこういうふうに試合をしてくれって指示だけだし あとはオブジェクトがメッセージ(ボール)をつないで試合を展開する感じ
>>362 その辺にしておかないと大変なことになってる
冗談は国会の中だけにしておけ
5月末までには・・・ ぁぅあんっぅあああああーーーーーーーーーー かい〜いぃぃいいい〜〜〜さああああん
OOPで組んでると少しは逆アセンブラ対策になる?
370 :
デフォルトの名無しさん :2010/09/05(日) 13:57:48
全部privateで良いじゃん!
デザインパターンとバッドノウハウって何が違うの?
>>371 場当たり的に逃げ道を探して回避する(根本的な問題は完治しない)のがバッドノウハウ
本質的な部分を見直して考慮された見通しの良い(とされている)考え方がデザパタ
>>372 なるほど
ところでデザパタに対して含みを持たせてるのは、
本質的に解決できていないものも含まれていると感じているから?
だとすると、問題を解決する方法として見たとき、バットノウハウとデザパタの境界は
案外曖昧だったりするのでしょうか
違う側面からの解説もキボンヌ
デザパタに含まれないものがバッドノウハウ
バッドノウハウは「緊急時のおけるやむをえない場合のパターン」とも考えられる。 それが急を要しない状況で使われたとき「バッドノウハウ」と呼ばれる気がする。
バッドノウハウって具体的にどんなの?
ブラウザのバグを回避するために特定のブラウザの時だけ本来すべきではない スクリプト書いて対処したりとか、プログラムの美しさを損なうやつ。
それって「●●パターン」って名乗るには恥ずかしすぎるな
>>377 WEBプログラムのクライアントサイドこそバッドノウハウの宝庫だな。
あとはJavaのVMごとにあるバグの回避で実装変えたりとかな。
>>379 >JavaのVMごとにあるバグの回避で実装変えたり
したことないなあ。どんなのあった?JVMにバグがある場合は
アップデートで乗り切ってるなウチは。tomcatのHttpSession#getSessionId()で
バージョンによってセッション切れの時の挙動が違って回避プログラム書いたけど
まさにバッドノウハウだよね。OOとも何の関係もない
SUNのVMとWEBLOGICのVMで一部ちがったところがあったりな。 でも8年くらい前の話だ。
382 :
デフォルトの名無しさん :2010/10/10(日) 00:44:37
MVCアーキテクチャの質問です。 例えば運動方程式を解いて物体の運動を視覚的に表示するプログラムを考えます。 DirectXやOpenGLのようなものは使わず、普通のウィンドウシステムの上で動かすとします。 このとき、フレームレートとか画面の大きさというような情報は誰が持つべきなのでしょうか? Mがフレームレートの情報を持って、自分からイベントループにコールバックを登録する構造なら、 物体が自律的に運動するさまを自然に表現できますが、 反面、Mがウィンドウシステムに依存することになり、何か変な感じもします。 逆にこれをCが持つとすれば、Mは位置と運動量と時刻くらいしか持たないことになり、 ちょっとMの仕事が少なすぎる気がします。 画面の大きさに関しては、常識的にはVの領分でしょうが、現在の位置に加えて軌跡も表示したい場合、 どこかに画面と同じ大きさのビットマップを持つ必要が出てきます。これはMにあたるでしょう。
仕事が多いとか少ないとかを分担の基準にするべきじゃない。 つか、ビットマップはVだろ… いや軌跡をビットマップにプロットするモデルと、ビットマップを表示するビューに分ける、 とか考えられなくもないけど、そこまでするほどの例題とも思えない。
>>382 Mに持たせるインターフェイスのデザインをどうするか、どんなものが好ましいのかにもよりますが、
VCペアが問い合わせてくる、ある時刻での物体の正確な位置を返す仕事であれば、Mの責務です。
画像で返す必要があるのかってこと。 モデル側にあるってことは、交換可能な全てのモデルに位置を画像で返す機能をつけることになるが…。 数値だけ返して、画像への描画は別の部分が担当するのではまずいの?
物体の運動に直接影響するものは全部モデルだろ ウィンドウサイズなどの情報を抽象化するMを設ける
多段MVCかPACにご興味のあるかたはいらっしゃいますか!!?
>>382 Model(M)からは、軌跡の集まりを返すだけにし、その表現はPresentation Model(PM)から返すようにするってのは?
V <-- PM <-- M
PMが不要なプロパティを表示する時は、単に無視するか、透過的に扱うようにする。
389 :
382 :2010/10/12(火) 21:36:29
>>388 軌跡が初等関数で書けるようなものであれば係数を求めて渡すだけですが、
そうでない場合、まさか全ての時刻での座標を覚えておくわけにもいきませんから、
ビットマップを埋めることで軌跡を「求める」ことになるでしょう。
もっと極端な例では、マンデルブロ集合のモデルは必然的に解像度の情報を持つことになります。
いまやプログラミングはマルチパラダイムの世界なのに純粋なOOPが役に立つの?
>>389 > まさか全ての時刻での座標を覚えておくわけにもいきませんから、
むしろ、保持しておいた方がいいと思うけどね。
オンメモりに乗らないくらいの巨大データなら、ファイルなり、DBなりに保存(キャッシュ)する。
または、間引いて保持する。
また、適当な間隔で間引かれたサンプリングデータをもとに、
オンデマンドで表示領域分のデータを計算すれば、全領域を保持する必要はなくなると思うよ。
この辺は、OOPとは関係ない実装の泥臭い部分になるけど。
ビットマップにとっておいてる時点ですべての座標を記憶してるじゃん。 ビットマップの方がメモり喰うのわかってないの? MVCのVがモニタだろうがプリンタだろうがMは影響を受けないように作るべきで、 どんなサイズでどういう風に表示するかはVが決める。表示内容はMだけど 見た目はVが決める。ビットマップで持ったらVで見た目決められないし
>>392 は
>>391 に対するレスか?
全ての座標とは、軌跡上の全ての座標を保持するという意味で書いたんだ。
軌跡以外の点までは保持する必要はないってことね。
例えば、放物線なら、放物線上の点の集まりのみを保持する。
うまく伝えられなくてゴメンね。
>>393 だとまだ誤解受けそうだから補足。
座標とは、UI上の座標ではなく、ある時刻の計算値のことね。
運動方程式なら、パラメーターを設定すれば、(時刻, X, Y, Z)の集合が計算できるので、その値を保持。
表示する際は、範囲と倍率を考慮して、UI座標に座標変換する。
1024×768ドット16色のビットマップは384kb。3点のXY座標を単精度で持てば1時点あたり24バイト。1/30秒ごとに記録すると9分程度でビットマップの大きさを越えることになる。
なんだか全く関係ないな
データサイズうんぬん言ってる時点でOOと大分関係ないんだけど 最終的に1034x768のbmpに納めればいい情報ならshortのx,yの2点でいいし、 bmpで持つくらいなら1024x768のbooleanの配列で持った方がまだマシ。 同じだけの情報記録できてサイズが小さくてデータが利用しやすいから。 Viewの実装がなんだろうとModelのビジネスロジックは変わらない、 それがMVC。Mの時点で最終表示系を決めたらVの仕事はなんだよw
boolean使うくらいならbyte使うだろ 扱いが面倒で記憶域の無駄遣い
>扱いが面倒で記憶域の無駄遣い おまえは何を言っているんだ?w
booleanだったら「ビットマップと同じだけの情報」にはならないだろ 要求がはっきりしないけど、例えば同じ座標を通った回数を区別する必要がある場合はどうする? その必要がないとしても、boolean使ったからってそれほど節約にはならないよ。1バイトなんだから。 そもそも、軌跡を描画するなら普通に考えてビットマップに描いていくのが効率がいいので 内部で二重にバッファ持つ意味がない
>>400 UIで、スケール変更して、拡大表示するときは、どうするの?
ビットマップから切り出して、拡大表示させる?
ジャギーでるよ。
その都度、再計算させる?
再計算のコストが高かったら?
レスポンス悪くなるよ。
軌跡の計算結果をもつことは、メモリ効率を悪くしてるかもしれないけど、
最悪、拡大時は補間してレスポンスの悪化を防ぐことも一応可能よ。
ビットマップもジャギー出さずに、補間して拡大するアルゴリズムあるのかな?
>>401 ビットマップである以上拡大すればジャギはでる。
あきらめろ。
レスポンス問題は昨今なら別スレッドを使用すれば、
そこそこ隠蔽できるだろ。
GPU使えるならそっちを使えばよいとおもうけどな。
つかぜんぜんOOPと関係ねえからやめろ。
加えて、 曲線上の点を選択して、その値を調べたいときは、どうするの? ビットマップに落とし込んだ時点で丸められてるから、 正確な値取れないよ。 その程度なら、再計算すればいいっていわれそうだけど、 運動方程式(微分方程式)の解が漸化式になつてしまったら、単純にその値だけ再計算できないよね?
404 :
400 :2010/10/15(金) 21:23:01
booleanの配列で持てというのに対して反論してるだけだよ。 軌跡を描画に使うだけならビットマップで十分な場合は多いだろうし ちゃんとしたシミュレーションで軌跡のデータが必要ならそのまま保持しといたほうがいいだろうし 要件がわからないのに議論しても仕方ない。
あきらめろじゃなくて、MVCの話をしてるのにMでビットマップにするのが おかしいって事だよ。なんで主題と関係ないトコで広げてるんだ?
思ったけど、現実的な提案をするにはもっと詳細が必要だね。
そりゃそうだ。 だがMでビットマップを作ることがMVCらしくない事には変わりない。 このスレでOOPとしてあるべき姿の話をするのか、効率を含めた妥協点を 探る話をするのかと言えば前者だろ。
Mには指定フォーマットで圧縮(されてなくても良い)データを。 VはVRAMに表示する為に決められたフォーマットのデータを。 CにはMを展開してVに適用する手続きを。 おれはこう考えたが・・・。
これが画像を生成するためのフォトレタッチソフトならそうかもしれんが
どんなソフトが前提だっけ?
MからVへの変換にプロクシかまして、ビットマップをキャッシュすれば良いんじゃね?
お前はどこまでいくねんw
設計って一人で悩んでどうにかなる問題だと思う?
ある程度の経験とセンスがあれば新しい物でもできる。 経験がないとセンスがあっても難しい。 センスがなければ経験があっても応用は難しい。
>>413 一人で悩んでも良いけど情報収集は必要。
要件の分析や、他人の解説や設計を読んだりして新しい視点が見つかることも多い。
一人で設計ばかりしていると思考の堂々巡りに陥ることがあるのが辛い。
そんなときは、実際に作ってみたり、誰かに話してみると改善点が見つかったりする。
大規模なものは知らないけど、一人で設計やってるものとしては、こんな感じ。
堂々巡りわかります。 とりあえず作ってみるってのはいいですね。 だぶったっていいわけだし
保険商品と契約の関係を構築しようとしてるんですが、 保険商品ってあるカテゴリで共通してる属性があったり、 その商品単独でしか持ち得ないような属性もあったりします。 Javaではinterfaceで共通部分を定義して、abstractで一般的な値を設定、 特有の属性や例外的な処理はそれぞれ具象クラスでってパターンにしようと思っていますが、 この保険商品をDBのテーブルで表す際にどうするか悩んでいます。 1.1つの「保険商品」テーブルに入れてしまう。joken1、joken2みたいなカラムで固有属性をカバーする → 明らかにおかしい 2.商品ごとにテーブルを分ける。 → 数が多くなりすぎる。保険商品一覧を取りたい時に大変。 3.共通部分のテーブルと固有部分のテーブルで分ける → joinが多発する(5〜8テーブル位)。商品固有テーブルだけでも10テーブル位作らなきゃだめそう。 個人的には3しかないかなと思っていますが、何かいい案はありますでしょうか。 ちなみに会社の人間は1を勧めてきました。
属性の型がStringとかなら、「固有属性」を1カラムにしてカンマ区切りで持たせるという手もある。 1の派生型だけど、固有属性の多い商品が増えたからといってDDL変えることもないし エンティティクラスのアクセッサでその属性を管理してあげればいいだけだから簡単。 固有属性が結構複雑で属性名も大事だったりするなら「固有属性テーブル」を一つだけつくって 保険商品ID、属性名、属性値の3カラム構成、PKは保険商品ID+属性名。 エンティティクラスではMap<属性名, 属性値>という型で固有属性マップを持つ。 このどちらでも属性tのget/setのために具象クラスにわける必要ないよ。 計算式とか含むなら分けた方がいいけど
>>417 RDB?とJava(オブジェクト指向)のデータの持ち方で悩んでいる?
それなら「O/Rマッピング」の製品や書籍があるからそちらを参考にしてみては。
基本は製品を買ったほうが工数も掛からないし信用性もあるからいいと思いますけど
なかなか製品購入を許してくれる会社も少ないからな...
ここからは個人の意見で(何がベストなのかは環境によっても違うと思うので)
>2.商品ごとにテーブルを分ける。
これがいいと思う、データは会社の経営資源(リソース)だけどシステムは道具に過ぎない。
データは正しい構造(正規化)でもっていなければならない。道具に合わせたデータ構造は間違ってと思う。
>→ 数が多くなりすぎる。保険商品一覧を取りたい時に大変。
viewやプロシージャでも作っておけば?データに関してはDBMSに任せるのも手だと思う。
俺的にやっぱりベストなやり方は、RDBは正しく正規化で作り、システムも正しくオブジェクト指向で作り
「O/Rマッピング」の製品を買って繋ぎ合わせるのが一番だと思う。
420 :
417 :2011/01/18(火) 00:17:36
すみません遅くなりました。
>>418 >保険商品ID、属性名、属性値の3カラム構成、PKは保険商品ID+属性名。
>エンティティクラスではMap<属性名, 属性値>という型で固有属性マップを持つ。
なるほど、こうすれば雑多な項目を格納できそうですね。
属性名(属性ID)を外部キーとして属性マスタを作れば正規化も満足できそうです。
そういえば以前に関わった案件ではこのやり方でした。
>>419 「Javaでは…」のせいで質問のポイントを不明瞭にしてしまいました。
すみません。蛇足でした。
>2.商品ごとにテーブルを分ける。
>これがいいと思う、データは会社の経営資源(リソース)だけどシステムは道具に過ぎない。
うーん、そうですね。それは正しいように思います。
テーブル数が相当数になりますが、だからといって、
それを少なく管理しようとする試みも、また合目的的ではなさそうです。
もちろん、結果的に少なくなったというのであれば、それは歓迎すべきでしょうが…。
商品毎にどれくらい項目が違うのかわからないけど、 商品名、担当部署とか共通の項目が多いのであれば商品毎のテーブルは OO的にも正しくないと思うよ。固有属性専用テーブルはいわゆるサマリ-詳細テーブルの 関係だからよくある形じゃないかな
マルチプラットフォームのクラスライブラリを作る場合 例えばWindowクラスのOS別実装するときどうしますか? ソース互換にするためには Window w = new Window(); ってやりたいんですが、Windowの実装はWin32Window、LinuxWindowとか 別クラスで実装するのが普通なんでしょうか この場合Windowをインターフェースにして Window w = new Win32Window();とかになるんでしょうか でもこうするとソース互換なくなるしWin32Windowを後悔しちゃうとOS依存の内部実装が見えてしまうので 良くないですよね?普通はこういう場合どう設計するんでしょうか
Window型を返すWindow.Createって感じのクラスメソッドを作る。 その中で、環境別にWin32WindowなりLinuxWindowなりをnewして返す。
>>423 C#のGraphics.FromImageみたいなものですか・・なるほど・・
>>422 >Window w = new Win32Window();とかになるんでしょうか
そこでDIですよ
ageちまった…
428 :
デフォルトの名無しさん :2011/02/09(水) 16:24:43
組込みでOOPに切り替えたらuITRONやFreeRTOSを使用しなくなってしまった なんで? ヒープが少々必要な事と Cでのコーディングは少々手間が掛かるが完成後のメンテは楽チン
429 :
デフォルトの名無しさん :2011/02/16(水) 13:23:49
楽か?
430 :
デフォルトの名無しさん :2011/02/20(日) 11:39:01.75
>>429 メンテと新規機能の追加は楽です
ARMとdsPIC専門で16KB以上のSRAMがあるマイコンの場合に限定して採用していますが
ヒューマンインターフェースが入るファームウェアはPCアプリ感覚が生きてきますので
今までより開発スピードと質がワンランク上がりました
RTOSが必要無くなったのは 必然的にイベントベースになり クラス間が
スタティックカップリングからダイナミックカップリングに変わる為ですね
同時に意図的にですが かつてのウォータフォールスタイルの開発も無くなりました
小さいPICマイコンでは今までの構造化ですが w
機能追加(メソッド追加)に付いての質問です。 既存クラスに機能追加した時に、OCPを守った上で一番良い方法は? スーパークラスも機能追加したい場合がよくあると思いますが OCPだと既存クラスに手を入れるのは基本NGになる。 そうなると、やっぱりメタクラスで実装するのが一番なのか? しかし、メタクラスを実装していない言語も多い。 あとは、スーパークラスをNULLオブジェクトとして設計する。 既存クラスに手を入れるが、NULLオブジェクトだからロジックには手が入らない。 実用上問題ないと考える。 みなさんはメソッド追加を見越して、どのようなクラス設計をしていますか? そもそもスーパークラスにメソッド追加自体を許さないとか?
継承を前提にした設計を可能な限り減らす がまずは第一だと思うよ
まずinterfaceの抽出からだな。 複数の実装クラスで同じロジックを一杯実装しなきゃならんようになったら、abstractでデフォルト動作を規定して、それを継承って感じ。
既存クラスにメソッドを追加してはいけないというのがまずおかしいでしょ 既存のメンバの動作を変更しない限りは別に問題ない
>>431 「メソッド追加を見越したクラス設計」って、
何かよくわからんが嫌なにおいがする。
もしかして抽象メソッドを追加する場合のことを言ってるのか?
それなら妥協して普通の仮想メソッドにして既定の実装を提供しておくだけ
たぶん
>>431 の言葉でいえばNULLオブジェクト
>>432 >継承を前提にした設計を可能な限り減らす
その理由は? たまに継承を使うなと言う人がいるけど納得出来る理由を聞いたことがない。
>>433 >まずinterfaceの抽出からだな。
説明が悪かったのかな? 既存の動いているシステムに機能追加する場合を想定している。
また親・子クラス関係なく多態で扱いたい。
>>434 >既存クラスにメソッドを追加してはいけないというのがまずおかしいでしょ
なるほど、たしかに既存動作に影響しないけど、それを証明するのは?
まったく手を入れなければ、証明する必要もないけど、手を入れた以上は
影響が無いと思ってもコーディングミスもあるし既存機能が正しく動くことを
証明しないと。
OCPではそれも含めて修正は禁止していると思っているんだが。
>>436 >もしかして抽象メソッドを追加する場合のことを言ってるのか?
逆で、システム開発後に動いているスーパークラスに具象クラスを追加して
既存処理に影響が出ないかたちでスーパークラスのメソッド(多態)として使いたい。
何か話が噛み合っていないような。
OCPの原則は、動いているシステムに適用するものだと思っているのだが
ほとんどの返信内容が新規作成時の事を言っているように感じる。
>親・子クラス関係なく多態で扱いたい。 >既存動作に影響しないけど、それを証明するのは? >既存処理に影響が出ないかたちでスーパークラスのメソッド(多態)として使いたい。 単体テストをしっかり書いてからリファクタリング クラス設計だけじゃ無理だと思うよ
>たしかに既存動作に影響しないけど、それを証明するのは? そんなことを言い出したらOCPの教義である多態を使って拡張したとしても同じことだろ どっちみちテストは必要
>その理由は? たまに継承を使うなと言う人がいるけど納得出来る理由を聞いたことがない。 最初からクラスを継承禁止にしておけば君の心配は全て解決するじゃん。これ以上わかりやすい理由はない。 継承を許している以上、新たにサブクラスが追加されることによって既存のコードが動かなくなる可能性は 常に存在する。
>>438 >単体テストをしっかり書いてからリファクタリング
>クラス設計だけじゃ無理だと思うよ
余計なテストをしなくて済む為のOCPだと思うけど。
>>439 >どっちみちテストは必要
余計なテストをしなくて済む為のOCPだと思うけど。
>>440 >継承を許している以上、新たにサブクラスが追加されることによって既存のコードが動かなくなる可能性は常に存在する。
既存コードに影響が無い作りをする為のOCPでしょう。
それに、サブクラスが追加しても親クラスには何ら影響はないでしょう。(あるなら教えて欲しい)
俺が聞きたいのは、OCPを適用したら既存部分はまったく影響ないけど
既存コードを修正したい場合があるから、OCPが崩れる。
その影響を最小限にするクラス設計をみんなどうしているのか?を聞きたい。
ここまでOCP,OCP言う人初めて見たわ。俺、そこまで深く考えてないわ。
>余計なテストをしなくて済む為のOCPだと思うけど。
変更時に既存動作に影響がないか確認するためのテストファーストです。
リファクタリングしようがしまいがテストは書かなきゃ駄目。
余計なテストなんてものはない
>影響を最小限にするクラス設計をどうしているのか?
だから
>>438
メソッドを追加するだけなら、影響が及ぶのはそのクラスだけ。 でも、サブクラスが増えると、それが混ざる可能性のある場所全てが誤動作する可能性がある。 程度問題だが、そういう見方も可能。
正しくOCPを守れていれば
>>444 のような問題は起こらないよ。
それが「修正に対して閉じている」ということだから。
でも、それをどうやって証明する? 結局テストするしかないじゃないかw
>>442 >ここまでOCP,OCP言う人初めて見たわ。俺、そこまで深く考えてないわ。
んっ? 質問だけど、クラス設計の時は何を目指してやっているの?
例えばデザインパターンを使って設計していても根底にはOCPがあると思うけど。
>>443 >変更時に既存動作に影響がないか確認する
OCPは変更(修正)しては駄目と言う原則だけど。
機能追加する部分はテストファーストやTDDでやってもいいけど、質問している事と違うだが...
>>444 >でも、サブクラスが増えると、それが混ざる可能性のある場所全てが誤動作する可能性がある。
「サブクラスが増える」と「それが混ざる」 何が混ざると?影響が混ざると言うこと?
>>445 >でも、それをどうやって証明する? 結局テストするしかないじゃないかw
機能追加だけ行えば既存機能は影響がないと思うけど。
言語にもよるけど、継承元クラスのコードが無くても(バイナリで提供)
継承したクラスを作ることが出来る言語もある。
親クラスをバイナリ・レベルで提供だから、動作には変更が無いことを証明していると思うけど。
447 :
442 :2011/03/03(木) 08:06:53.95
>>446 >んっ? 質問だけど、クラス設計の時は何を目指してやっているの?
普通に
>>432 とか
>>433 とか。OCPは単なる原則であって規制だという認識じゃないんで、
OCPを守る為に設計、OCPはテストをしなくて済む為のもの、とかまで拡大解釈してない。
サブクラスが混ざるというのは、例えばスーパークラスのインスタンス を受ける既存メソッドの引数に、新しいサブクラスのインスタンスを渡すこと。 それによってそのメソッドが正しく動作しないケースは実際にある。 LSPって知ってる?
>>447 それは手法であって、目的や目標がじゃない気がする。
設計に目的や目標は、いらないと考えている?
>>448 Liskovは知っているけど、それを守る為のOCPでしょう。
機能追加はもちろんテストしないといけないけど
それ以外に影響を出さない為のOCPで
LSPはモジュールを置き換えたときに適切な動作しないといけないと言うだけで
当たり前の事を言っているだけ(だから原則なのかもしれないけど)
そのことは、今回来ていない。
何か話しが噛み合わないな...
設計の目的…だと…?
だからLSPが守れていることはどうやって証明するの? なんでその証明は不要なのに、既存クラスにメソッドを追加したときに その既存クラスの動作に影響を与えないことの証明は必要なの?
452 :
451 :2011/03/03(木) 15:38:42.43
伝わらなそうなので整理 431が主張する「サブクラスが追加されても既存のコードは正しく動作する」はLSPが大前提なわけ。 でもそれって自明なことじゃないでしょ? やってみないとわからない。 サブクラスの実装に問題が無くても、既存のコードが暗に既存サブクラスの細かい仕様外の動作を前提にしてしまっていて それがサブクラスを追加することで明るみに出るかもしれない。 それって、既存クラスにメソッドを追加することのリスクと本質的に何が違うの?
>>450 普通OODだと、変更に強い設計にするとか再利用しやすい設計とか。
>>451 ,452
>だからLSPが守れていることはどうやって証明するの?
機能追加にLSPは関係ないと思う。、
修正なら使っているクライアントにLSPを保障しないといけないけど
機能追加は、その時点で誰も使っていないから「置換」は発生しない。
431の例で誰に対するLSPを証明するの? LSPは関係ないと思うけど。
>サブクラスの実装に問題が無くても、既存のコードが暗に既存サブクラスの細かい仕様外の動作を前提にしてしまっていて
もし前提にしてたとしても、それはその時点で実装されているメソッドに対してでしょう?
新しく実装されるメソッドを前提にクラスが作られているとは思えない。
>>437 >機能追加する部分はテストファーストやTDDでやってもいいけど、質問している事と違うだが...
じゃあ確認するけど
>既存クラスに機能追加した時に、OCPを守った上で一番良い方法は?
>みなさんはメソッド追加を見越して、どのようなクラス設計をしていますか?
>既存の動いているシステムに機能追加する場合を想定している。
>OCPではそれも含めて修正は禁止していると思っているんだが。
>既存処理に影響が出ないかたちでスーパークラスのメソッド(多態)として使いたい。
これでいいよね?
メソッドの追加はOCP違反なんでしょ?
だから、既存部分の動作が変わっていないか確認するためにテストを書いたら、と言ってるんだよ
OCPを守っていればテストが不要というわけじゃないけどね
>何か話しが噛み合わないな...
OCPはこうあるべきという原則であって、守っていれば既存の動作が変更されないということを
保証する技術じゃないよ。かみ合わない原因はこれ
いや、設計方針を聞いているのにテストと言われても。
ふと「置換」とか曖昧な概念で議論せずにDbCの(事前|不変|事後)条件(*)を使ってよとか思って >機能追加にLSPは関係ない に対して考えてみたけど 機能追加を最小単位のメソッド追加まで分割したとき、 その機能追加で追加されるあるメソッドfの事後条件が他のメソッドgの事後条件でも言及されている識別子vを含むとき (例:fの事後条件にv=aが、gの事後条件にv=bが含まれる) vを利用している式eの(*)に影響しこの式eを含むメソッドhの(*)が変化する hがクラスBを基底とする派生クラスCのメソッドでありBにそのインタフェースであるh'があるとき この変化の前後でhの事後条件がh'のそれより弱められてしまった場合またはhの事前条件がh'のそれより強められてしまった場合 LSPは満たされなくなる とかいう文章が浮かんできて うん、やっぱ使わなくていいやという結果になった
なぜ、こんなに話が噛み合わないかな... まず第一点目として、OCPを守っていれば既存コードには影響ないと思っている。 >OCPはこうあるべきという原則であって、守っていれば既存の動作が変更されないということを >保証する技術じゃないよ。かみ合わない原因はこれ マルチスレッドとかで動いているとか無い限りOCPを守れば既存機能は保障される。 次に第二点目として、OCPを守っていれば単体テストの範囲は追加機能分だけ 余計な単体テストは不要になる、その為にもOCPを守って作った方がいい。 俺の質問を言い換えれば、テストなどをどうすれば簡略化出来るか? と言う質問にもなるのに、それを「テストをしなさい」と言われても... 話が噛み合わないのでこの質問はこれで終了します、レス有難うございました。
話が噛み合わないのは、
>>459 はOCPが守られていることを前提にしているから。
機能追加に伴って顕在化するようなバグや設計上の問題が
既存コードには全く存在しないことを仮定している。
それに対して、他の人はその前提がおかしいと言っている。
そういうことを前提にしていいのであれば、カプセル化の原則が厳密に守られていることを前提にすれば
メソッドを既存クラスに追加しようが全く問題ないことになるよね。
>>459 >なぜ、こんなに話が噛み合わないかな...
なぜ噛み合わないのか?それは聞いた場所が悪いんじゃないのか。
OCPやカプセル化すら理解出来ていない奴に聞いてもしょうがないだろう。
ここじゃなく知恵袋で聞いて来い。
あっちは一瞬で京大の問題まで解いてくれるから、まともな答えが返ってくるぞw
>>459 もう何度もいってるし460もいってるけど前提が間違ってる
OCPは動作が変更されないことを保証しない。
追加したメソッドがメンバ変数(あるいはグローバル変数)に干渉していて
既存メソッドが正常に動作する前提を崩している可能性がある。
これはスーパークラスに追加した場合でも継承してサブクラスに
追加(君の言うOCPを適用)した場合でもかわらないし、追加メソッドのテストだけでは確認できない。
別に反論してくれなくてもいいけど、反論するなら
>OCPを守っていれば既存コードには影響ないと思っている。
みたいな感想ではなく、根拠をしめしてね
ついでに、勘違いしてる人と定義論争したくないから今まで黙ってたけど
君のOCPの定義は間違ってるよ
>OCPは変更(修正)しては駄目と言う原則
とか
>OCPを守っていれば単体テストの範囲は追加機能分だけ
>余計な単体テストは不要になる
とかはメイヤーさんが聞いたら泡吹いて卒倒するレベルだからよそでは言わないほうがいいよ
こっちは反論を受け付けません。ちゃんとしりたかったらメイヤーのオブジェクト指向入門読んでね
Strategyパターンなどで機能を追加したときに既存クラスの不適切な実装のせいでうまく動作しなかったら それは結果としてOCPを破ってる(正しく開かれてない)と言うこともできるんじゃないの? どっちにしろ彼は既存コードが拡張に対して絶対に正しく動作するという理想的な状況を仮定しているわけだから そんなものを作れる完璧超人が既存クラスにたかがメソッド一個追加するときに 誤って既存メンバの動作を変えてしまうようなヘマをするとは思えないけども
>>461 他の所で聞いてもいいけど、別に正解だけを聞きたいだけじゃないからな。
正解は複数あると思うし、その環境にベストな答えは自分で考えないといけないと思っている。
>>462 君は間違っている。
逆に聞くが、何の言語を使っているか知らないが、言語に標準や共通ライブラリーが実装されていると思うが
その標準ライブラリーのクラスから継承してクラスを作った場合に、君は標準ライブラリーのクラスまで単体テストしているのか?
もっと言えば、その標準ライブラリークラスのまた親など全ての親クラスに対して単体テストをしているのか?
>追加したメソッドがメンバ変数(あるいはグローバル変数)に干渉していて
>既存メソッドが正常に動作する前提を崩している可能性がある。
OCPの理解がまったく出来ていない、フィールドに既存メソッドが想定していない値が入るようになった場合
そのメソッドは継承して処理するのがOCPだから、既存メソッドの処理は変えないし単体テストをする必要もない。
>とかはメイヤーさんが聞いたら泡吹いて卒倒するレベルだからよそでは言わないほうがいいよ
メイヤーと言うなら、形式手法は知っているのか? メイヤーの考えを正しく理解したいなら
そのあたりから勉強しろ。
>>463 >どっちにしろ彼は既存コードが拡張に対して絶対に正しく動作するという理想的な状況を仮定しているわけだから
上でも書いたけど、正しく動作しないメソッドが有った場合は、そのメソッドを継承する。
それがOCPだと思うけど。それと知っていると思うがOCPはバグなら修正を認めている。
>Strategyパターンなどで機能を追加したときに既存クラスの不適切な実装のせいでうまく動作しなかったら
元の話に戻るけど「Strategyパターンなどで機能を追加」は考えてみたけど
その場合に、今度を機能追加や継承が多いと「デメテルの法則はどうなるのか?」と考えてしまう。
でも基本的には「Strategyパターン」で実装するのが一番最適な正解だとは思うど
そのあたりの、参照や依存関係が複雑化するのはどう考えるか聞きたい?
>フィールドに既存メソッドが想定していない値が入るようになった場合そのメソッドは継承して処理する (*) 基底メソッドが想定していない値を派生先のメソッドで処理するということは 派生先メソッドの事前事後条件が派生元のそれより弱いということになる これは派生クラスの事後条件が基底クラスより弱くなってはいけないという意味のLSPに反する 形式手法というかDbCに対してはOCPよかLSPの方が相性いいなと思った OCPは拡張とか修正とかいう曖昧な概念をどうやって論理に翻訳すればいいかわからない できることを増やすという意味の拡張ならとりあえず全体としてはより弱い事後条件になり より安全にという意味の修正では事前条件が弱くつまり緩和されるわけか? ただ計算機による支援なしでまともにDbCとか使えるわきゃねぇから (*)のやり方そのものが問題になることは殆んどないだろうな
>フィールドに既存メソッドが想定していない値が入るようになった カプセル化も破ってるな 絶対に既存クラスが修正されないなら勝手だが、 標準ライブラリのような外部のパブリックなAPIを使うケースを引き合いに出すなら不適切だろ
だんだんOCP関係なくなってきた感じがするなー
長くなったので二分割
>>464 >標準ライブラリーのクラスから継承してクラスを作った場合
自分が作ったクラスならテストしてるよ。
勘違いしてるみたいなんで訂正するけど、既存メソッドといってたのは
サブクラスを経由している既存メソッドという意味ね。親クラスまではテストしない。
>OCPの理解がまったく出来ていない、フィールドに既存メソッドが想定していない値が入るようになった場合
>そのメソッドは継承して処理するのがOCPだから、既存メソッドの処理は変えないし単体テストをする必要もない。
過去の発言をそのままお返します。
>なるほど、たしかに既存動作に影響しないけど、それを証明するのは?
後半 >既存コードに影響が無い作りをする為のOCPでしょう。 >OCPを守れば既存機能は保障される >メソッドは継承して処理するのがOCPだから よくこんな感じの発言するけど、OCPはただの原則。 「モジュールは開いていると同時に閉じているべきである」 これだけ サブクラスを作ってスーパークラスに手を加えないのも Strategyパターンあたりを使って機能を追加するのも OCPを実現する手法・技術ではあるけどOCPそのものじゃない。 その手法・技術も単独では既存動作を保証しない。テストが必要だというのはこういう理由。 なぞの技術OCPを使えば既存動作は保証されるというわけじゃないんだよ。 >メイヤーと言うなら 確かにメイヤーのくだりは要らなかったな。大人気ない煽りだった。申し訳ない。 主張は変えないけどね >君は間違っている。 根拠を書いてね
>>465 >派生先メソッドの事前事後条件が派生元のそれより弱いということになる
>これは派生クラスの事後条件が基底クラスより弱くなってはいけないという意味のLSPに反する
反論じゃないが事前条件が弱くなるのは許されている、事後条件が弱くなるのはOCPにも違反している。
>形式手法というかDbCに対してはOCPよかLSPの方が相性いいなと思った
LSPが具体的な原則で、OCPはもっと広い意味での原則でLSPも含んでいる。
クライアントが相手の型を意識させた場合、それはクローズしていない事になる。
まっ認識の差だけで、多分考えている方向性は同じだと思う。
>>466 論外の意見だな。
>>467 >サブクラスを経由している既存メソッドという意味ね。親クラスまではテストしない。
意味が分からん 462の
>追加(君の言うOCPを適用)した場合でもかわらないし、追加メソッドのテストだけでは確認できない。
「親クラスまではテストしない」「追加メソッドのテストだけでは確認できない」は何のテストを行うのか?
これが相手に伝わる文章だと思うっているのか?
>過去の発言をそのままお返します。
本当にOCPを理解しているのか? >既存クラスにメソッドを追加してはいけないというのがまずおかしいでしょ
既存クラスにメソッドを追加するのがOCPだとでも思っているのか?
OCPは既存クラスを修正しては駄目だと言うことだ。
>「モジュールは開いていると同時に閉じているべきである」 これだけ
そんな認識だから駄目なんだろう、修正に対して閉鎖していて、機能追加に対して開放されていると言うことだ。
まったく、まともなレスをくれるのは
>>465 ぐらいしかいない。
メソッドの追加自体は修正とちがうんでない? 追加したメソッドが既存のメソッドの動作を変更しうる場合が修正? 動作を変更しないことを証明するのは難しいから追加も修正とみなして禁止? よくわからん
wikipediaの開放/閉鎖原則の頁に参考資料として「和訳 The Open-Closed Principle
(開放-閉鎖原則)」というPDFがあるから、
>>431 (と分かってなさそうなその他数名)は
読んどけよ
相当やさしく書かれているから、これで理解できなければ救いようがないわ
>>470 >動作を変更しないことを証明するのは難しい
そういうことでしょ
特に、修正は原則として既存クラスのメンバをオーバーライドして動作を変更する
(つまりカプセル化を破る)ことで行うというポリシーが前提なので
細かい動作の変更が大きな影響を及ぼす恐れがある
そのポリシーの是非は今は問題にしていない
>>469 >何のテストを行うのか?
サブクラスがスーパークラスから継承しているメソッド(非オーバーライドも含め)
ほかにもいろいろあるけどもういいや
OCPを適用した場合に省くことできる「余計なテスト」の例とその根拠だけ解説してくれ
あればweb上で参照できるソースも
>>470 >メソッドの追加自体は修正とちがうんでない?
クラス単位で見た場合に修正となる。
>動作を変更しないことを証明するのは難しいから追加も修正とみなして禁止?
追加を修正とみなして禁止ではない、実際メソッドの修正なら元のソースを修正するが
追加なら元のソースは無くても出来る。(言語にもよるが)
大雑把に言えば現在のソースに直接手を入れるのが修正。
>>471 なぜ自分の意見で書かない自信がないのか?
>open-closed principle を満たすプログラムでは新しいコードを追加するだけで機能を追加すること
>になるので、既存のコードを変更することはありません。ですから、この原則を満たさないプログラム
>で見受けられるような変更の連鎖を経験することもないのです。
「変更の連鎖を経験することもない」この意味が分かるか?
OCPを守っていれば、「変更の連鎖がない」つまり親クラスに影響を与えないと言うことだ。
>>472 >特に、修正は原則として既存クラスのメンバをオーバーライドして動作を変更する
>(つまりカプセル化を破る)ことで行うというポリシーが前提なので
「オーバーライドして動作を変更する」オーバーライドしたら、それは修正じゃないだろう。
CLOSを使ってみたら、オブジェクトがメソッドを抱え込んでることが疑問に思えてきたんだけど、 あんたら的にはどう思う?
476 :
471 :2011/03/08(火) 23:43:52.62
>>474 お前は誰と戦ってんだよ?
俺はOCPを誤って理解してる馬鹿がいたから分かりやすい文書を教えてやっただけのこと
くだらん煽りはいいから早く続きを読め
まだ途中までしか読んでないんだろ?
お前が引用した箇所のすぐ下、「戦略的閉鎖」まで読めば誤りに気がつくだろ
(普通はもっと早く気がつくだろうけど)
俺はこのPDFほど優しく教えられないからな、素直に読んでくれることを望むよ
>>473 >open-closed principle を満たすプログラムでは新しいコードを追加するだけで機能を追加すること
>になるので、既存のコードを変更することはありません。ですから、この原則を満たさないプログラム
>で見受けられるような変更の連鎖を経験することもないのです。
下にも書いたこれでいいか、影響範囲が特定出来れば「余計なテスト」はいらない。
>>475 俺は知らない。
>>476 まったく、メイヤーを読めとかマーチンを読めとかお前が読めよ。
理解出来ていないのは、お前だから早く気づけ。
自分の言葉で説明出来ない黙っていろよ。
今日は、まともなに話が出来る人間はいなかったな。
478 :
471 :2011/03/09(水) 01:13:47.95
>>477 462は別人。471のPDFを読めば馬鹿でも分かるように書かれている。読むべき箇所も示した。
それでももっと噛み砕いて説明しないと分からないのか…。
いちおう試みてみるけど、まぁ俺には無理だなw
> はっきりしておかなければならないこととして、100%閉じたプログラムというものは
> あり得ないということがあります。
(中略)
> 一般的には、モジュールがどんなに頑張って閉鎖したつもりでも閉じていない部分が
> 必ずあって、それに対して何らかの変更が起きてしまうものなのです。
と書いてあるだろ?
お前が
>>431 から話しているのは、閉じていないものをどうやったら外見上閉じているもの
として扱えるか?という本末転倒な話なの。メタクラスで追加なんてその典型。
既存のソースコードを変更しないから閉じているのではなく、OCPを満たした閉じている
プログラムは必然的に既存のコードの変更が必要なくなるということ。
意図せず開いてしまったものは、当然だけど変更せざるを得ない。
PDFのShapeの例だと「Listing 2」はその時点ではOCPを満たしていると考えられるが、
描画順序というルールの導入に対しては開いていて、「Listing 3」への変更はコードを
変更することでしか対処できない(そしてPDFでもメソッドの追加という変更をしている)。
この「Listing 2」から「Listing 3」の変更は
>>431 の状況の具体例と考えられる。
頑張ってみたけど駄目かねぇ…
しかし間違いに気づいたら素直に認めてくれよ。俺も認めるからさ。
>>478 ようやく自分の意見を書いたのか。
最初に書いて置くが、同じ文章をよんでも知識や経験で理解する内容は違う。
同じ人間でも今日読んで理解した内容と、数年後に読んで理解した内容は違うだろう。
それに、なぜその文章で議論しないといけない?
>相当やさしく書かれているから、これで理解できなければ救いようがないわ
明らかに主観で薦めているものを前提にしている、客観性がゼロだ。
まっ、しかしマーチンを選択したのは良いと思うが。(ただしC++を対象にしているから抽象化が弱いが)
>お前が
>>431 から話しているのは、閉じていないものをどうやったら外見上閉じているもの
>として扱えるか?という本末転倒な話なの。メタクラスで追加なんてその典型。
ほら最初から理解が違う、マーチンの言っているのは将来にわたって全て閉鎖するのは不可能だと言っていだけ。
だから、その時点で閉鎖されているモジュールはいくらでも存在する。
それとメタクラスを理解出来ているのか?「メタクラスで追加なんてその典型」なぜ”追加”と言う言葉を使う?
メタクラスはクラスの抽象化だ、クラス自体を入れ替えると言うことで、実装の入れ替ということだ、追加じゃない。
wikipediaをあまり信用していないから引用するのも嫌なんだが、そっちが出したから出してみる。
>ポリモーフィックな開放/閉鎖原則
> 1990年代、開放/閉鎖原則とは一般的に抽象インタフェースの利用を指すように意味が変わっていった。
> その定義では実装はもはや固定ではなく、複数の実装が存在可能となり、互いにポリモーフィックに入れ替えることができる。
「実装はもはや固定ではなく、複数の実装が存在可能となり、互いにポリモーフィックに入れ替える」
この入れ替えを、メタクラスで行おうとする話だが、なにが「本末転倒な話」なのか詳細に説明してくれるか?
つづき
>既存のソースコードを変更しないから閉じているのではなく、OCPを満たした閉じている
>プログラムは必然的に既存のコードの変更が必要なくなるということ。
>意図せず開いてしまったものは、当然だけど変更せざるを得ない。
次にこれだ、「OCPを満たした閉じているプログラムは必然的に既存のコードの変更が必要なくなる」
自分が引用している部分と矛盾するとは思わないのか?「100%閉じたプログラムというものは あり得ない」
OCPを満たしているから修正が必要ないんじゃなく、現時点で修正の必要がないからOCPを満たしているんだろう。
>PDFのShapeの例だと「Listing 2」はその時点ではOCPを満たしていると考えられるが、
>描画順序というルールの導入に対しては開いていて、「Listing 3」への変更はコードを
>変更することでしか対処できない(そしてPDFでもメソッドの追加という変更をしている)。
>この「Listing 2」から「Listing 3」の変更は
>>431 の状況の具体例と考えられる。
次はこれ、ほら〜また俺との認識が違う、この「Listing 2・Listing 3」の話は開発時の設計方法だと認識したが。
ここで書いてある「戦略的閉鎖」とは、
>完全な閉鎖というのがありえないとすると、これを戦略的に行わなければならないことになります。
>つまり、設計者は、どのような種類の変更に対応すれば、その設計を閉じられるかということを
>選択しなければならない
つまり、いかに閉鎖したクラス設計するかが書かれている。それに対してOCPとは(wikipedia)
>つまり、あるクラスが一度コードレビューやユニットテストなどの品質検査を通過し実際の運用に入ったならば、
>そのクラスを修正してはならず、拡張によって対処しなければならない。
運用が始まったものに対する原則だ。 俺の書いた
>>431 は運用が始まった後のことだ。
まったく、俺の聞いたことの入り口すら理解出来ないのか?
481 :
471 :2011/03/09(水) 21:26:35.22
>>479 > それとメタクラスを理解出来ているのか?「メタクラスで追加なんてその典型」なぜ”追加”と言う言葉を使う?
431は機能追加についての話だったからその意味で"追加"と書いたがおかしかったか?
この話でメタクラスが出てくること自体がおかしい(ついでにNullオブジェクトの方も
意味不明)が、お前が具体的にどういう方法を考えているのかなんて知らない。
もしかしたら俺がものすごく勘違いをしているのかもしれないな。
それなら本末転倒といったのは先走りすぎたかも知れない。
> 「実装はもはや固定ではなく、複数の実装が存在可能となり、互いにポリモーフィックに入れ替える」
> この入れ替えを、メタクラスで行おうとする話だが、なにが「本末転倒な話」なのか詳細に説明してくれるか?
しかし、これをよんでも相変わらず意味不明。
とにかく憶測で話をしても埒があかないから、メタクラスでの方法の正当性を主張したいなら
Shapeの例などで具体的に
>>431 を説明してくれ。
482 :
471 :2011/03/09(水) 21:27:14.66
>>480 > 次にこれだ、「OCPを満たした閉じているプログラムは必然的に既存のコードの変更が必要なくなる」
> 自分が引用している部分と矛盾するとは思わないのか?「100%閉じたプログラムというものは あり得ない」
> OCPを満たしているから修正が必要ないんじゃなく、現時点で修正の必要がないからOCPを満たしているんだろう。
違う。OCPを満たしていれば修正の必要は無いが、修正の必要がないからといってOCPを
満たしているとは限らない。OCPはOOPだけの概念ではなくグローバル変数などについても
いえることだが、グローバル変数を使用している(=OCPを満たしていない)としても修正の
必要があるとは限らない。何か矛盾することを書いたか?
> 次はこれ、ほら〜また俺との認識が違う、この「Listing 2・Listing 3」の話は開発時の設計方法だと認識したが。
中略
> 運用が始まったものに対する原則だ。 俺の書いた
>>431 は運用が始まった後のことだ。
じゃあ「Listing 2」の段階で運用が始まり、その後描画順序というルールを導入する必要が
でてきたとしたら?同じことだろう?
描画順序というルールを始めから想定するなんて不可能で、設計段階でどんなに頑張っても、
運用段階では閉じていない部分が必ずでてきてしまう。だから完全な閉鎖がありえないと
書かれている。
そこで、経験や勘でなるべく有り得そうな変更を予測して、戦略的にOCPを適用する必要が
あるということ。
お前は注意深く設計されたクラスは全てに対し完全にOCPが適用され、完全に閉鎖されている
という前提で話をしているからおかしいの
もちろんOCPが満たされている範囲では、wikipediaの引用部分に書かれていることは全て
当てはまる(そして逆に言えばOCPが満たされていない場合は、当てはまらない)。
あるモジュールが変更に関して閉じているかどうかは、変更内容によって変わりうる。 たとえば、図形処理モジュールが 「図形一般をあらわすインタフェース(or 抽象クラス)があって、 円や矩形などの具体的な図形はすべてそれを継承している」 ように設計されていたとする。 このモジュールは新しい図形の種類(三角形など)の追加に関して閉じているが、 新しい図形の操作の追加に関しては閉じていない。 431は後者のときに、既存クラスに手を入れずに対処する方法を質問したのではないかと思う。
そんなもん最初から想定してないと無理だろ 追加したい操作にもよるだろうが、究極的には最初からクラス間の依存関係を全てインターフェイスで扱うか 全てのフィールドはprotected、全てのメソッドをオーバーライド可能にしておいてカプセル化を壊すかしかない
485 :
471 :2011/03/09(水) 23:55:34.50
>>483 ,484
それと同じことを直前で書いたつもりなんだけどなw
やっぱ俺の説明が下手くそなんだろうな
>>481 ,482
見事に話が噛み合っていない。全部に対応するのは疲れるから本筋のところだけ書く。
(メタクラスやNULLオブジェクトは自分で勉強してくれ)
>じゃあ「Listing 2」の段階で運用が始まり、その後描画順序というルールを導入する必要が
>でてきたとしたら?同じことだろう?
だから書いたんだ。同じ物を読んでも同じ認識にはならないと、それなのにお前はただ読めと、まったく...
本題にはいるが、マーチンが書きたかったのは運用に入る前の設計方法で
俺が聞いているのは運用後の設計方法、まったく違う。
運用前の設計では、マーチンが書いているようにOCPを適用しやすく設計方法で
運用後はOCPをいかに守るべきかの設計方法を聞いている。
>お前は注意深く設計されたクラスは全てに対し完全にOCPが適用され、完全に閉鎖されている
>という前提で話をしているからおかしいの
またそうやって決め付ける。自分の認識が間違っているとは思わないのか?
書いた本人の俺が違うと言っている認識についてどう思うんだ?
>>483 その通り、理解できる人がいると嬉しい。
そこが入り口で、その場合にどう設計すれば良いのかを聞きたかったんだが、その入り口にもなかなか立てない...
>>484 >そんなもん最初から想定してないと無理だろ
なぜ無理だと決め付ける?
>追加したい操作にもよるだろうが、究極的には最初からクラス間の依存関係を全てインターフェイスで扱うか
>全てのフィールドはprotected、全てのメソッドをオーバーライド可能にしておいてカプセル化を壊すかしかない
なるほど、それを気にして今までカプセル化が崩れると言っていたのか、納得した。
だが自分でも「インターフェイスで扱う」とか解決策を考えているじゃないか?「フィールドはprotected」もgetter/setterを書けば良い事だし。
まっ、それでも「最初からある程度は想定していないと」と考えるのは分かる、だから俺もメタクラスと書いた。
(メタクラスならクラスごと入れ替える訳だし、想定しなくてもなんとかなる場合が多い)
>>485 >それと同じことを直前で書いたつもりなんだけどなw
>やっぱ俺の説明が下手くそなんだろうな
説明が下手じゃなく書いている内容が違うんだろう?
>お前は注意深く設計されたクラスは全てに対し完全にOCPが適用され、完全に閉鎖されている
>という前提で話をしているからおかしいの
> 新しい図形の操作の追加に関しては閉じていない。
> 431は後者のときに、既存クラスに手を入れずに対処する方法を質問したのではないかと思う。
が同じ? 「完全に閉鎖されている」と「追加に関しては閉じていない」が同じだと? 駄目だ俺には正しく読み取れない。
堂々めぐりだからもういいよ メタクラスによる機能追加というのは具体的にどうやるつもりなのか示してくれ
489 :
471 :2011/03/10(木) 01:35:05.87
>>486 > (メタクラスやNULLオブジェクトは自分で勉強してくれ)
俺はNullオブジェクトというと書籍の『リファクタリング』などに載っているものを想像
するんだけど、
>>431 はどうもそれとは違うようだから勉強しようにもできないんだ。
それからメタクラスによって
>>431 を解決する方法は431自身しか知らないよな?
だったら勉強しようがないだろ。
繰り返すが、自分の正当性を示したいのなら具体的に説明しろ。
できないならちゃんと認めろ馬鹿が。
> 本題にはいるが、マーチンが書きたかったのは運用に入る前の設計方法で
> 俺が聞いているのは運用後の設計方法、まったく違う。
ではそのマーチンなら運用後の設計方法はどうすると思う?そんなの本人しか分からない?
確かにそうだけどおかしいとは思わないか?
OCPは20年以上前からあり、
>>431 のような疑問も当然現れてくるはず。なのに運用後
のことは何も言及されていないということになる。
マーチンだけじゃない。OCPに関してはたびたび目にするが
>>431 のような質問は俺は見た
ことも聞いたこともない。ここで初めて目にした。
もし既にあるというのなら教えて欲しい(そして何故そこでの解決法で満足せずここで
質問したのかということも)。
最後に一つ答えて欲しい。お前は
>>480 の最後で
> まったく、俺の聞いたことの入り口すら理解出来ないのか?
と書いているが、お前は天才で、20年以上にわたり誰も考えつかなかった
>>431 の解決策を
世界で初めて考え出し、それを理解できない多くの凡人の方がおかしいということか?
ここで「はいそうです」と答えてくれると嬉しいね。話が噛み合わない原因がはっきり
するから。
>>484 それってまんまSmalltalkとかRubyの事だな
ところで、メタクラスという言葉はクラスのクラスの事を指してるんだよな
なんでクラスを入れ替えるとか機能追加とかそういう話になるんだ?
もしかしてこの認識がなんか間違ってるのか
Shapeインターフェースにdraw()メソッドがあって、TriangleやCircleなどの 具象クラスがそれを実装してるとする。draw()の他にrotate()を追加したいとする。 OCPに従うならRotatableShapeインターフェースを新規作成して RotatableTriangle等の具象クラスを作成する。でも仕様変更ですべての具象クラスが Rotatableになる必要があるならリファクタリングしてShapeに手を入れた方がいい。 OCPはOOPの基本的な原則であって、予測してなかった仕様変更に対してまで 頑なに守るようなルールじゃないし、あらかじめShapeにメソッドが追加されることを 前提にしたところでShapeの設計は変わらない。 >たまに継承を使うなと言う人がいるけど 継承を使うなは論外だと思うけど、継承より委譲が大原則。理由はより疎結合になるから。 サブルーチン的な発想で共通機能をベースクラスに押し込んで継承するのは間違いなんだけど 割とやりがち。Shapeの例だとそれぞれのインスタンスをファイルに保存することが出来たとして、 AbstractShapeクラスを作ってそこにsave()メソッドを実装して継承するのは駄目で、 ShapeSaverクラスを作ってそっちに委譲する、というイメージ。
フィールドのgetter/setterを書くって矛盾してるぞ 絶対に変更しないんだろ? だったらフィールドをそのまま公開してるのと同じだ
OCPは設計時に達成すべき目標を示したものであって、 インタフェースを用いるというのはその実現手段のひとつでしかない。 もし操作が追加されると予測されるなら、switch〜case方式にする手もあるし、 操作の共通インタフェースを導入するという手もある。 メタクラスを使ってクラスごと入れ替えるというのも、 乱暴だが、選択肢のひとつではあるだろう。
クラス入れ替えるって 既存クラスのソースファイルをビルドから除外して かわりに別のファイルに差し替えるのとどう違うの?
>>493 switch〜case方式に戻してどうすんだよ
OOPにおけるOCPは「いかにswitch文を除去するか?」が最重要テーマと言っても良いくらいなのに
OCPが分からないなら黙っておいた方がいいよ
496 :
431 :2011/03/11(金) 02:04:56.19
個別に対応は神経的に疲れて良くないから、質問をもう少し具体的に書いて整理してみる。 共通モジュールServiceAクラスがあり それがClientBクラスなどいろいろな箇所で使われている。 ClientBクラスはServiceAクラスをコンポジション(委譲)して使っている。 なので、ClientBクラスはServiceAクラスのインスタンス生成・破棄を管理している。 ある日仕様変更があり、ServiceAクラスに新機能を追加することになった。 現在使用しているクライアントにも、新仕様を適用したクラスを使用させたい。 この場合、修正のやり方として一番簡単なのはServiceAクラスを直接修正。 新しいメソッドを追加する、しかしこれではServiceAクラスがOCP違反になる。 次にServiceAクラスを継承して修正した場合、ServiceAクラスはOCPを満たすが ClientBクラスなど修正が必要になりOCP違反になる。 では、ServiceAクラス・ClientBクラスともに継承して修正すれば良いのではと考えるが しかしこれも「依存するモジュールに変更が連鎖して広がっている」のでOCP違反。
497 :
431 :2011/03/11(金) 02:05:38.53
つづき では、なぜ変更の連鎖が起きるのか? ClientBクラスとServiceAクラスとの関係がDIP違反だから起きている。 ClientBクラスがServiceAクラスをコンポジションしているから ClientBクラスが上位(高次)モジュールなのに ServiceAクラスと言う下位モジュールの具象クラスに依存している。 DIPを守るには、上位と下位の繋がりを抽象化すればいい。 これを解決するには一つの方法は、クラスを抽象化(メタクラス)すればいい。 ここでメタクラスを簡単に説明すると、普通クラスからインスタンスを作成する。 これがメタクラスだと、クラス(オブジェクトじゃなく型自体)を入れる変数を想像してくれ その変数を使ってインスタンスが作れる、変数だからいろいろなクラスが設定出来る インスタンスを作る方では、実際にどのクラスからインスタンスが作られたのか分からない。 つまり、クラスが抽象化される。
メタクラス関係無いじゃん
だったら最初からそう言えよ で、DIによって実装クラスを入れ替えるのが 既存クラスにメソッド一個追加するよりも既存コードの動作への影響が少ないというの? 何を根拠に?
いまいち理解出来んが > 431(と分かってなさそうなその他数名)は読んどけよ の471が一番理解出来ていないのはわかった 最近多いよね、民主党みたいに墓穴掘るやつw
>>498 なぜ関係がないと思うんだ? まっ一つの方法でしかないが。
>>499 >だったら最初からそう言えよ
>で、DIによって実装クラスを入れ替えるのが
最初から言っている、具体例にしただけだ。
ところで、DIって何だ? わからないんだが。
>>500 >いまいち理解出来んが
簡単に書いたつもりだが...
しかし、東北から関東まで大変そうだな。
DI = Dependency Injection >496のような問題が起きないように設計するための手法で、 その例だとClientが使うServerオブジェクトを外から与えてやるようにする。
なんでこうも次から次へとアホなことを書けるのかね…。
そもそも
>>431 と
>>496 ,497では同じことを書いているようには読めない。
OCPを誤解しているのは相変わらずだし、抽象化やメタクラスの説明もめちゃくちゃ。
DIをわからないというのも意味が分からない。
さすがにもういいや。
>>500 は…
>>461 →
>>464 を読んだときも感じたんだけど、なんだろうな?この違和感…w
502だが、>431と>496は同じこと書いてると思うよ。 既存クラスには絶対手を入れない、という方針の是非はともかく。 >496の例ならDIですむが、設計時に予測していないような修正だったら メタレベルでクラス間のつながりを変更するしかないかもしれん。 なんかもっと難しそうな例はないのか? >496
OCPやLSPやDIPは知ってるのにDI知らんて どういう勉強したらそんなことになるのか
>>502 ,504
>メタレベルでクラス間のつながりを変更するしかないかもしれん。
なるほど、だからDIと書いたのか。
Dependency Injectionは知っているが文脈的に別の意味だと思った。
DIはメタクラスじゃない、メタクラスは言語の仕様だから。
DIで実装してもいいが、それは変更があると分かっているで
メタクラスなら無条件にインスタンス生成は
クラスからじゃなくメタクラスで行うと決めていればいい。
メタクラスは設計と言うレベルじゃなく実装できるが、DIは設計しないと。
>>503 >さすがにもういいや。
助かる。
>>505 ”通訳”しないと分からない時点で...
まぁ俺には関係ないが。
>>506 >OCPやLSPやDIPは知ってるのにDI知らんて
OCPやLSPやDIP知ってると認めてくれるのか、有難い。
ただメタクラスをDIと言われてもピントこないしな。
(DIをメタレベルとか普通に使っているのか?)
間違えた。 DIで実装してもいいが、それは変更があると分かっているときで メタクラス実装なら無条件に、インスタンス生成はクラスではなく メタクラスで行うと決めていればいい。 メタクラスは設計と言うレベルじゃなく規則レベルで実装できるが DIは設計がともなう。
>>508 > メタクラスは設計と言うレベルじゃなく規則レベルで実装できるが
これって一つ間違えるとクラスシステム全体が………
に, なっちゃわね?
clos/mopとかつついてる, と時々,
何やってるんだ? >俺
に, なるんだが………
OOPのスレでDIを「文脈的に別の意味と思った」とか言い訳する時点で まともに話して通じるとは思えない。DIコンテナなんか何一つ使ったことないんだろう。 OCPに固執するのは会社のルールで明文化されてるのかな
>>497 に対するレスでDIと書かれているのを
文脈的に別の意味と思うのは難しいな
>>510 ,511
低いレベルだな、がっかりだよ。
>さすがにもういいや。
なんだろう、もう相手しなくていいから。
略称がDIで意味の違う単語てOOP的に他になにがあるかな?
クラスを差し替えるなんてそれこそ既存コードを破壊する大修正だと思うが
>>513 http://ja.wikipedia.org/wiki/DI 無い。
>>514 >>497 の例で言えばServiceAを継承して1メソッドの動作を変えたServiceA'を
作成してClientBは無修正に適用できる。こんなことは自動ユニットテストで
当たり前のように行われてること。でも
>>491 の例にあるShape#rotate()を
追加するようなときはClientB側も変更範囲なのは当たり前の話で
こういうのは変更の連鎖といわない。連鎖はたとえばServiceAのメソッド引数に
パラメータを追加して、挙動に変更のないクラスまで修正を強要すること。
>>515 それはもっともだが、
>>431 の言う既存クラスにメソッドを追加してはいけない理由はそもそも
「既存クラスにメソッドを追加する際に既存クラスの他のメンバの動作を変えてしまうかもしれないから」
だ。テストすればいいというなら既存クラスにメソッドを追加すること自体は何の問題も無いよね。
メソッド一個追加するのを避けてクラスごと差し替えるなんて本末転倒じゃん。
差し替えるのは元のクラスを継承して1メソッド変更したものに置き換えるだけ。 既存のソース部分はそのまま使うので全然本末転倒ではない。 テストすればいいっていう話はOCP守ってそんな見通しの悪い クラス構成でメンテしていくより綺麗にリファクタリング、つまり元のクラスに手を入れちゃって それが仕様通りであることをテストで保証すればいいってことじゃないかな。 実際にはUnitTestですべてまかなえる訳じゃないし理想論に過ぎないかもだけど、 見通しのいいソースを維持できる。OCPを守ることが義務づけられでもしていない限り OCPにこだわってわかりにくいソースをメンテし続ける方が高コスト。 今後のメンテ回数がすくなければOCPの方がいいケースもあるかもしれない。
継承によって追加するメソッドは、既存スーパークラスのプライベートなメンバにアクセスしないの? アクセスしないのであれば、クラスの外に静的メソッドとして作ればいいわけだから 当然プライベートメンバへのアクセスが必要なケースということだよな? そこはどうするの? 最初から全部公開しておく?
あらかじめ全部protectedなアクセッサを用意しておくという解もあるかもしれないけど、普通はしないよね。 既存ソースを変更しないルールに沿うならprivateメンバーに依存するようなメソッドは全部オーバーライドしないといけない。 そもそもOCPにこだわるのが時代遅れ。
OCPのための継承は、そこを設計の目的としちゃいけない気がする。 ポリモするのもそりゃいいさ。case書きまくるのにくらべ段違いにいいさ。 でも、クラス階層が不用意に、アンバランスに育っていく気持ち悪さってないぞ。 そうなるくらいなら、クリクリッとした、よく設計された使いやすいクラスが、 フラットな場所にコロコロ転がってるほうが使いやすい。 不用意な継承も、protectedもいらない。 使わない!として無理したほうがキレイな糞がひねりだせそう。 継承してOCP♪、protected使って継承迎合♪ 糞が軟便になってしまう。
継承って、それ自体が親クラスに対する強い依存性だからな。 使う積極的な理由がないなら、極力使わないほうがいい。
継承するかしないかはオブジェクトの持つ意味合いで決めるべきで、モデリングの時点で決まる。 共通処理をスーパークラスにおくのは愚の骨頂
OCPはエンバグを防ぐというよりも 既存クラスを使用するクライアントに影響を与えないようにするためのもの 既存クラスを使用するクライアントが無いのなら OCPにこだわるメリットはあまりなさそう。というか思いつかない
なんかOCPがどうのこうの言い出してから、 「相談」がしにくい雰囲気だよね。
kigarunisoudansitekudasai
OOスレが消化されて、そっちの面子がこっちに移ってきてるんだろう。
曖昧な質問をしておきながら話がかみ合わないと逆切れだからな 内容がどうであれあんな態度を取られたら空気も悪くなるさ
委譲先のインスタンスが委譲元知りたいってなると相互参照することになるのですが そもそも設計間違ってます?
相互参照自体は別に問題ない 委譲元の一部の情報がほしいだけなら引数オブジェクト使うとかでもいいけど 委譲元そのものを知りたいなら相互参照するしかないしね
observer使ったGUIのイベント処理なんかだと確実に相互参照になるよ(間接的な場合もある) フォームがボタンのクラスに依存するしボタンのインスタンスを参照する ボタンはフォームのクラスには依存しないけどフォームのインスタンスを参照する
もっと俯瞰で見て、多対多の参照が見えてくると問題。 一対一でやれてるかぎりはまだ平気。
委譲って多くの場合相互参照じゃね? 利用側(委譲先)がコンポーネント(委譲元)を参照するのは自然なこと
C++だとポインタの管理めんどくさいんですよ
ポインタはめんどくさくない deleteがめんどくさいんだ
あとダングイングポインタですかね、 委譲メソッド追加するのもメンドクサイし継承がいいかもしれない・・・
漢民族が他民族への蔑称。 東の民族→東夷 西の民族→西戎 南の民族→南蛮 北の民族→北狄 東夷族なんて”族”は無い、あるのは大和民族や朝鮮民族などの民族。 これだと漢民族と4つの民族しかいないことになる。 それに、たしか韓国の主張だと朝鮮民族は文化の遅れているえびす(夷)には入らないと言っていたが 自分達をえびす(夷)だと認めるのか?
ここど真ん中に道を作ろう、これを基準にして色々作っていこう、 と考えてそれを半分くらい作ったところで、 他の箇所からちょっと飛行機臨時便飛ばすことにしたから、 なんかあったら乗っけていいよ、みたいな手はずになってしまい、 そっちを通すようにしてたら、飛行機の着陸する空港が臭くなってしまい、 ちょっとまてよ、ちょっと飛行機やめよう、ターミナルバスも、滑走路も、 全部ひっこめよう、となって、そういえば、と元のど真ん中の道を思い出し、 そっちを開通させてみると、なんと見通しのいい頼れる一本道であったことか。 ということってよくある。
>>534 多くの場合、ってほど多いとも思わないが…
普通は相互参照しないなあ。
ポインタの管理がめんどくさくなるような構造になっちゃってる時点でなんか設計が間違ってる
>>541 クラスの相互依存と混同してないか?
普通にobserverやるとたいがい結果的に相互参照になるぞ
Javaや.NETなどのようにGUIのイベントにobserverが使われる場合
コンポーネントからのイベントを受け取ろうとするたびに確実に相互参照が増える
0点、もう少しがんばりましょう。
そもそもObserverって委譲なのか? Observerを相互参照というのもピントがズレている。
10年ドメインオブジェクトモデルを信奉して頑張ってきた。 シンプルで少数精鋭の時はそれでいいけど人数多くて開発者のレベルもマチマチだと駄目だ。 トランザクションスクリプト派に乗り換えよう。趣味のプログラムだけ頑張ろう。
質問、OO設計のキモは抽象化/汎用化だとおもうが(思わない人間は無視してくれ) どのレベルまで行うか?個人的な基準があれば聞きたい。 あと、レベルの低い回答は無視するから。
使いやすいと思うレベル
>>547 自分の作ったクラスの何パーセントくらい再利用してる?
俺は10%位のような気がする。
550 :
547 :2011/06/28(火) 22:55:08.02
汎用化って再利用を促す言葉じゃないの?
552 :
デフォルトの名無しさん :2011/06/29(水) 02:16:16.48
553 :
547 :2011/06/29(水) 13:28:33.55
>>551 それは構造化的な汎用化を言ってないか?
構造化の汎用化は、共通処理のモジュールを作り再利用するが
OOの汎用化は操作を”汎用”化する。
例えば(オブジェクトが相手のオブジェクトにメッセージを送る)
運転手(オブジェクト) → ハンドルを右(メッセージ) → 乗り物(オブジェクト)
乗り物が車オブジェクトなら、タイヤを右にする。
乗り物が船オブジェクトなら、舵を右にする。
乗り物が飛行機オブジェクトなら、尾翼を右にする。
こんな風に、メッセージを統一するのがOOの汎用化。
使われるモジュールを統一するのが構造化的汎用化で
使うほうが統一したメッセージを送るのがOO的汎用化。
554 :
551 :2011/06/29(水) 13:35:27.53
>>553 実装レイヤーよりもうちょっと上の話か。難しいな。
リアルで会話してると抽象的な会話は誤動作や副作用を生みやすいが、まー、いったん実装すればそれでいいからなー。
ふむ〜。
メッセージってなに? 関数呼び出し?
>>552 OO以外だと元のソースに手を入れないで拡張するのが難しい
ソースをコピーするっつー方法もあるけど、後々地獄を見るのは確実
>>555 概念を言うと、メッセージってのは、オブジェクトに与える指示の事。
オブジェクトはメッセージを受け取ると、対応するメソッドを実行する。
C++の系譜を汲む言語は、ほぼメッセージの概念が消失してて、
直接メソッドを呼んでる感じになってる。
今メッセージを意識できるのはダックタイプだな。
ダックタイプは明確なメッセージ実装のひとつだ。
あと、Windowsのウィンドウメッセージの仕組みもOOPの
メッセージに由来している。
558 :
デフォルトの名無しさん :2011/06/30(木) 01:00:44.68
デフォルト実装以外の実装継承の価値が解からん。 大抵完全抽象化クラスを使えば済むし、大体それが正しい場合が多い。 なんせ実装継承したら、親クラスの実装を交換する術がない。 protectedが使える、templateメタプログラミングができるってのは、 別にオブジェクトとして重要じゃないし。 実装継承がどうしても必要なケースってどんな状況かねぇ。
559 :
547 :2011/06/30(木) 10:49:08.55
>質問、OO設計のキモは抽象化/汎用化だとおもうが(思わない人間は無視してくれ)
>どのレベルまで行うか?個人的な基準があれば聞きたい。
もう少し具体的な例を書いてみる。
例えば、
>>558 >なんせ実装継承したら、親クラスの実装を交換する術がない。
OO技術者なら分かると思うがいくらでも親クラスの実装を変える方法はある。
例えばBrigteパターンで実装ロジックの分離できるし
メッセージも極端な例ではInterpreterパターンを使えば何でも送れる。
しかし、全てのクラスをこのように作るのは抽象化しすぎで、いわゆる「抽象化中毒」だ。
OOである以上抽象化は必須だと思うが、「抽象化中毒」もよくない。
個人的なバランスの取り方を聞きたい。
(これが完全な正解と言う答えはないと思っているから、個人の意見を聞きたい)
560 :
デフォルトの名無しさん :2011/07/01(金) 01:02:05.84
>>559 BrigteってBridgeパターンの事?
まぁ、それはいいとして、わざわざBridgeの為に親を実装継承して何に使うの?
必然性がなくてあんまり効果無くねって思う。
例えば、こういう感じのコード。
BinalyArray pixelArray = new ColorArray();
Screen screen = new DrawingScreen();
BinalyWritable adapter = new ScreenAdapter(screen);
pixelArray.WriteTo(adapter);
DrawableAdapterはBinalyWritableの完全抽象化クラスを実装しているだけで、
ColorArrayとは直接接点がない。DrawaingScreenは、Screenを実装してるだけで、
Adapterとは直接接点がない。ましてや、ColorArrayは一切関係がない。
こういう作りにしておくとColorArrayとDrawingScreenのような全く関係ない
クラス同士を結び付けられるようになるじゃん。
で仮に、Bridgeなんかを使うと、少なくともBinalyWritableとその直系はScreenに依存するようになる。
例のコードだと依存してるのはScreenAdapterっていういかにも使い捨てなクラスだけなんだけどね。
そう思うとやっぱりわざわざBridgeまでして親用意しても邪魔なだけじゃねって思う。
まぁ、あなたのおっしゃる「抽象化中毒」なんでしょうけどね。
>BrigteってBridgeパターンの事? 間違えたすまない。
562 :
デフォルトの名無しさん :2011/07/02(土) 23:37:05.08
カプセル化の説明ってあとで実装を変えられるとか微妙なのが多くない? まぁ、たしかにそりゃそうなんだけど、元を辿るとオーバーライドできないからって事なんだよな。 そこに言及した話がない。 int getUnitCost() { return Math.parseInt(arguments["unit.count"]); } public int unitCount;みたいに親クラスで公開されてると↑みたいなコードに オーバーライドできん。なぜプロパティが許されるかってのもそこなんだよな。 ※ただ個人的にgetter/setterは糞だと思ってる。
>>554 ∨∨∨∨∨∨
>>>>>>>>>>>>> 実装レイヤーよりもうちょっと上の話か。難しいな。 <<<<<<<<<<<<<(キリッッッッ!!!!きリッ!!
∧∧∧∧∧∧∧(キリッ!キリ
∨∨∨∨∨∨∨∨∨
>>>>>>>>>>>>>> リアルで会話してると抽象的な会話は誤動作や副作用を生みやすいが、まー、いったん実装すればそれでいいからなー。 <<<<<<<<<<<<<<(キリッッッきリッッッッッ!!!!
∧∧∧∧(キリ!
ゴミ量産機
きも
565 :
デフォルトの名無しさん :2011/07/03(日) 19:54:31.14
>>562 >オーバーライドできないから
違うよ
抽象メンバやインターフェイスメンバとして宣言されたオーバーライド前提のものならともかく、
オーバーライドされることが想定されてないアクセサを正しくオーバーライドするなんてまず無理
できたとしてもスーパークラスの実装にべったり依存した形になるからカプセル化を破ることになる
>>565 惜しいな。最初からインターフェースありきで設計すればいいんだよ。
スーパークラスはどうしても拡張が必要だとか余程のことがない限り使わないようにする。
別にスーパークラスが存在しても構わないけど、基本的にインターフェースに束縛して使用する。
568 :
デフォルトの名無しさん :2011/07/03(日) 20:51:48.30
>>566 それが徹底できるなら理想かもしれないが、問題はインターフェイスで宣言するかどうかじゃなくて、
クラスを実装するときにプロパティがオーバーライドされる可能性を想定しているかどうかだよ。
>>562 のようにスーパークラスのgetUnitCostを呼び出さないオーバーライドを許すなら、
当然スーパークラス内でgetUnitCostの後ろのフィールドには直接アクセスしてはいけないし
スーパークラスで前提としてるgetUnitCostの細かい振る舞いについて仕様を決めなきゃいけない場合もある。
ですべてのプロパティについてそこまで考えてるのかって話
>>568 >>562 書いたの俺だけど、あれはインターフェースのオーバーライド前提に書いたよ。
スーパークラスはオーバーライドしづらいから、初めから継承する事を前提にしてないよ。
じゃあ宣言が非抽象のプロパティは無意味ってこと? オーバーライドされることを想定していなくて非抽象なプロパティも一般的には多く使われてるのは事実なんだから アクセサ使う目的を一般的に説明するなら、やっぱりあとで実装を変えられるようにするためでしょ。 多態使うのは元を辿ると実装を変えたいからだと言うならわかるが、逆は不自然じゃないか?
それは、間違いではないと想うよ。ただ2つある側面の片側でしか無いと思うし、そっちばかり強調してんのが今のプログラミング説明だと想う。 あと、すごく個人的な意見だけど getter/setter とプロパティは嫌い。正直意味ないと思う。 もともとIDEでGUIの値を簡単に変えられるようにした枠組みだもん。 Delphi、VB、Java beanとね。JavaやC++に長らくプロパティが存在しなかった原因は、 ホンというとSmalltalkで確立したオブジェクト指向に反してるからだと思う。 例えば、 interface RGB { void change(double red,double green,double blue); void change(int rgb); void to(RGB rgb); } っていうインターフェース用意しておけば、相互でchange呼び出せば済む話だし。
久々に同意。 Javaなんかはまだ可愛げがあるが、 C#でプロパティ用意しちゃってるあたりで、 もうたまらない。インタフェースというより、 構造体的に扱う事を強いてる。 設計段階で悪いほうに導いてるように見える。
プロパティはアクセッサにフックかけるみたいなAOP的な使い方するのには向いてると思う
PropertyDescriptorとAttributeでメタプログラミングするのが.NET流のフレームワークで、 プロパティは.NET Frameworkに不可欠な概念なんだからそこに文句を付けるのはナンセンス
Javaだろうとプロパティのある言語だろうと、実装変えるためのアクセサは現実に非常によく使われてるんだから 非常に頻繁に利用され、決まりきってて、有効性もわかってるパターンは 言語に組み込んで統一するっていうのは当然の進化だろう 何を言おうが「現実に使われてる」わけで、バラバラに各自のルールでやってるよりはずっとマシ
「プログラミング.NetFramework」っつー本で プロパティはイヤ、プロパティ嫌い、と繰り返しててワロタw
577 :
デフォルトの名無しさん :2011/07/04(月) 22:04:56.46
>>571 をちょっと弄るが
interface RGB
{
void change(double red,double green,double blue);
void change(int rgb);
RGB to(RGB rgb);//引数で取ったオブジェクトが帰る。
}
こういうインターフェース面白いよね。
void change(RGB source)
{
RGB fillter = source;
fillter = fillter.To( new NegativePositive() );//ネガポジ
fillter = fillter.To( new Edge(0.9) );//強調
fillter = fillter.To( new Sepia() );//セピア
fillter.To( this.color ); //最終結果をメンバーへ
}
フィルター化して幾らでも機能を拡張できる。
アクセサ中心でこういうの書こうとするとホント汚くなる。
別にプロパティだけで実装しろとはだれも言ってないだろ
∧_∧ / ̄ ̄ ̄ ̄ ̄ (ω・ )ゝ < 聞こえない ノ/ / \_____ ノ ̄ゝ
>>577 って具体的なデータ構造を暈してるけど、RGBにはゲッターが無いから結局何もできない妄想だよ
>>580 ゲッターなんていらない。
受け取り側がRGBインターフェースを実装するか、
RGBを実装したアダプターを作ればいいだけ。
ゲッターが必須と考えるのは思慮が浅い。
メンバ変数ありきのクラス設計、 セッタゲッタありきのクラス設計。 いただけない。 オブジェクト指向 != データ指向 カプセル化でインタフェースを突き詰めると、 そんなにプロパティ公開すべきもんでもないと気づく。
で、何が問題なわけ? オブジェクト指向の教義に反するとかコードが汚いとか俺が気に入らないとかじゃなくて具体的な問題点を挙げてよ
>>580 実装は自由だからどうとでもなるよ。
class PixelDevice implements RGB
{
private Graphics device;
public PixelDevice(Graphics device)
{
this.device = deveice;
}
public void drawLine(int x1,int y1,int x2,int y2)
{
device.drawLine( x1, y1, x2, y2 );
}
public void change(double red,double green,double blue)
{
device.setColor( new Color(0xFF * red,0xFF * green,0xFF * blue) );
}
public void change(int rgb){省略}
public RGB to(RGB rgb){省略}
}
>>584 要らんもの書いてないでchangeとtoを書けよ
>>571 の
>相互でchange呼び出せば済む
これがよく分からん
インスタンスAとBがあってAをBと同じ色にしたい場合はどうやってやるの?
>>583 同じ値が複数存在するところじゃね。
例えば、getter,setterを排除した
>>577 だと、
同じ値は、基本的にオブジェクトの中に留まる。
(まぁ、同じ値でコンストラクタ呼べば作れるけどそれは別問題)
別のオブジェクトに引き渡され場合、
引き渡した先のオブジェクトがファイルやデバイスで無い限り変更される。
同じ値はオブジェクト間を右から左へ渡されることがない。
つまり実装が極めて隠蔽される。
でも、getterで取れる値は、setterに入れた値と大抵同一。
実装が外にはみ出してると言われ手も文句は言えないよね。
ネーミングセンスがクソだから何も伝わらない 素直に名前を付ければinterface RgbReceiver{ void ReceiveRgb(...); }ぐらいが適切だろ でもそれにToが必要とは思えない あと同じ値が〜とか言ってるけど、複数のインスタンスの値を集約する場合はどうなるんだよ 受け取り用インターフェイスを複数定義してプライベート変数使うの? それとも処理フローに沿って別のクラス&インスタンスを量産するの?
>>585 changeは書いたろ。
まぁ、デバイスの場合toは要らんけどな。
あのインターフェースはtoを分離したほうがいいでしょ。
ちなみに、toを使うフィルターの場合は、
こんな感じ。
class NegativePositive implements RGB
{
private int rgb;
public NegativePositive(){}
public void change(double red,double green,double blue){省略}
public void change(int rgb)
{
rgb = 0xFF - ( 0xFF & rgb );
rgb |= 0xFF00 - ( 0xFF00 & rgb );
rgb |= 0xFF0000 - ( 0xFF0000 & rgb );
}
public RGB to(RGB color)
{
color.change(rgb);
return color;
}
}
>>588 オブジェクトはメッセージを受け取るものなのに、Receiverって・・・。
>>588 >受け取り用インターフェイスを複数定義してプライベート変数使うの?
いってる意味がよくわかんないけどこんな感じ。
interface Vertex
{
void move(Point point);
void change(Color color);
Vertex to(Vertex vertex);
}
含まれる要素がいくら増えようと、結局処理と処理結果で成り立つから、
おんなじパターンを淡々と作っていけば済むよ。見慣れてないと、
どこかで値を取れなくなりそうでgetterを作りたい不安にかられるかもしれないけど、
割と堅実に破綻はしないんだよ。
toの中ってさ書き換えてみると、 public RGB to(RGB color) { color.setRGB(getRGB()); return color; } ってやってる感じに近いんだ。 これによってgetRGBが公開されるのを防いでる。 本当にgetRGBが存在するとは限らないからね。 特にtoの所属するオブジェクトが外部からの入力関係だとね。 あと、setRGBってここでは書いたけど、 実際はsetterとは全然違うんでsetRGBとは書いちゃいけない。 setterと違って引数のcolorがtoの所属する値を持つ可能性はまず無いから。
間違えた × setterと違って引数のcolorがtoの所属する値を持つ可能性はまず無いから。 ○ setterと違って引数のcolorがtoの所属するオブジェクトと同じ値を持つ可能性はまず無いから。
えーと、changeとかtoの壊滅的な英語センスは置いとくとして、そもそもゲッター/セッターが必要かどうかって話ですよねぇ? なんかColorとかPointとか未定義の型が出てきたんですけど、こいつの値はどうやって取得するの? フィールドがパブリックになってんの?
Hoge get_hoge() { return m_hoge; } void set_hoge(Hoge x) { m_hoge = x; }みたいな馬鹿なもの書くぐらいなら 単なる複数の型の直積、直和の意味しか持たない型はパブリックフィールドでいいと思うけどね
>>594 同じ形式のインターフェースをもってればいいでしょ。
簡単な話しじゃん。
interface Point
{
void move(double x,double y);
Point to(Point point);
}
interface Color
{
void change(RGB color);
void change(HSV color);//HSVも同様。
Color to(Color point);
}
ColorにXYZ系のchangeをあとで追加したくなったらどうするの? インターフェイスに追加はできないよね
ちなみにPointとかVectorをこの形式で作ってるとけっこう面白いよ。 Pointの(0,0)地点ってどの空間に所属してるかで実際は変わってくる。 move(1,1)が呼び出されたPointがどの空間に所属し、どういう体系で座標系を 持ってるかで、move(1,1)が呼び出されたオブジェクトが持つオブジェクトの座標は全然変わってくる。
>>597 >>591 の様な感じじゃ無いんだね?
インターフェースの機能追加自体はあり得るよ。本当に必要ならね。
最初に、既存のクラス設計と同じように最小限の最大公約数を目指して用意するんだけどね。
#最小限の最大公約数って変ねぇ。
あと、本当にColorへの追加が必要かは考えなくちゃね。
例えば
>>589 の様に実装するクラスが持ってれば十分な事もあるし、
XYZ系というように構造が違うならXYZ系用のインターフェースをColorとは
別途もてば十分かもしれないしね。
601 :
600 :2011/07/05(火) 00:46:30.25
任意のベクトルに対する差分ベクトルに変換する変換クラス用意したらいいだけじゃん なんでもかんでも一つのクラスに詰め込むなよ
>>600 単なる値クラスなら、HSVだろうとXYZだろうとColorクラスへのメンバ追加だけで対応できるよね
それについてはどう思う?
1つのクラスに詰め込んでるつもりは無いんだけどねぇ。あくまでインターフェースだから。 同実装するかは、クラス次第だし。 >任意のベクトルに対する差分ベクトルに変換する変換クラス用意したらいいだけじゃん >なんでもかんでも一つのクラスに詰め込むなよ 一応聞くけどなんで?というかどういう経緯でそう思うの?
>>603 そのColorクラスは閉じてるんだよね。
こっちの場合は、必要なだけインターフェースとクラスを増やせば
元を弄る必要なくなるから楽なんだよ。
>>577 みたいな感じでね。
RGBとHSVだと前書いたtoの分離でもうすこし面白いことができる。 HSVからRGBへ変換できるクラス、RGBからHSVへ変換できるクラス、 RGBからRGBにしか変換できないクラス。用途に応じて変換パターンを支配できる。 それから、RGBを作った数カ月後にHSVを定義しても、RGBからHSVに変換するような 処理を簡単に組み込めるよ。 interface RGB { void change(double r,double g,double b); } interface HSV { void change(double h,double s,double v); } interface RGBConvertor { RGB to(RGB color); } interface HSVConvertor { HSV to(HSV color); }
Point pが所属する空間Sによってある観点におけるの値vが変わるということは vはpとSに依存し、それを与える写像が存在するということだろ これはそのまま関数に対応する
それは特にその方法の利点にはならないだろ プロパティと値オブジェクトでも同じようなことはできるし、別にそれが汚いとは俺は思わない むしろ抽象的すぎるクラスやインターフェイスが増殖するほうが気持ちが悪いと感じる
キモイ抽象クラス増加させなくても一つの関数と値オブジェクトでいけるということだ Genericsやtemplate, 依存型があると尚良し
名前さえ合ってれば特定流れの手続きに突っ込めるってことか。
関数を書き散らすが如く、インターフェースだけ最利用してクラスを
使い捨てにするような感覚が無いとキモイかもね。
オブジェクト = 関数の結果みたいな感じの設計デザインだし。
ただ、
>>577 みたいな感じで部品をぺきぺき組み合わせていくやり方は、
拡張が楽だし、きもちいいよ。
>>608 そう思うならそのやり方でいけばいいんじゃない?
個人的には構造体みたいな形で値が滞留するのが気持ち悪いと思うけど
逆のことを思う人は当然いるだろうし、そういう道でいいと思うよ。
>>610 ん。そうなのかねぇ。
とりあえずこんなことができるのは面白そうだな。
void change(RGB source)
{
RGB fillter1 = source;
HSV fillter2;
fillter1 = fillter1.To( new NegativePositive() );//ネガポジ
fillter2 = fillter1.To( new Edge(0.9) );//強調
fillter1 = fillter2.To( new Sepia() );//セピア
fillter1.To( this.color ); //最終結果をメンバーへ
}
>>608 >プロパティと値オブジェクトでも同じようなことはできるし
できるのか・・・。今までの流れだと無理臭い気が・・・。
>>614 中身見たが、流れるインターフェースっていうけどそれカリー化じゃね?
>>614 変数省略してこう書いたのとは何が違うん?
void change(RGB source)
{
source
.To( new NegativePositive() )
.To( new Edge(0.9) )
.To( new Sepia() )
.To( this.color );
}
>>613 >>612 のように書くと合成されたフィルタができてるように見えるけど違うぞ?
フィルタを順番に即時適用してるだけだ
色を引数に取って変換後の色を返す関数を順番に呼んでるのと一緒
フィルタの実装次第では遅延評価にもできるけど、それは関数でもそういう風にはできる
むしろ高階関数使うアプローチの方が自然
>>617 value = lambda();
lambda()( value );
こうやってんのと同じってのは解るよ。
いや、プロパティと値オブジェクトって書いてあったから
もっとsetから入った値がgetで別の値に変わってるような
斬新な方法駆使してんのかと思ったから無理じゃねって書いたの。
>>613 実現しようとしてるアプリケーションは作れるんじゃね?
大規模開発では
>抽象的すぎるクラスやインターフェイスが増殖するほうが気持ちが悪いと感じる
こういう人も紛れ込むし、頭いい方に合わせて底上げしようとしても
崩されたりモチベーション下げたりしてみんなが不幸になる。
割り切って構造化して「プロパティと値オブジェクト」にした方が
結果としてうまく行く場面も多いと思う。たとえ非OO的でソースが3倍にふくれあがってでも
代替要因が用意できて管理できることの方が重要なプロジェクトはある。
やりたくないけど仕事なのでそうも言ってられない
色と色コンバーターがくっ付いている方が抽象化が進んでいるという発想は理解できない
色コンバーターの結果が、色に抽象化されてるだけじゃん。 というか操作とデータが一緒であることが理解できないっていうとOO全否定じゃね。 まぁ、OOの観点から言えば、データは余計で全部結果を生む動作でやるのが ただしいようだけど。smalltalkの標準ライブラリとか。
>>617 インターフェースの引数を構造体みたいなもんで代用すればいいって言いたいんでしょ。
カプセル化の範囲絞り込みが出来ず原始回帰してるだけにしか見えん。
624 :
デフォルトの名無しさん :2011/07/05(火) 07:53:29.87
>>606 を見ると、自分で色と色コンバーターに分けてるんだね
しかし状態変更メソッドしか用意されてないRGBをどうすればコンバーターで操作できんだよ
結局引数を見ずに自分の情報でchangeを呼ぶしかないけど、それすら保証されていない謎インターフェイスになってるぞ
それを言ったら下駄で内容無視してnull返しても同じじゃん。 あくまで要求仕様は存在するでしょ。
626 :
デフォルトの名無しさん :2011/07/05(火) 08:34:37.87
そっちは別にどうでもいいんで、どうやって引数をコンバートするのか説明してください
どうやって変換前の値を取得するんだろうな
流れるようなインタフェースって、 Builderパターンとかによくハマる。 ビルダオブジェクトに対し、コネコネ、 グニグニ操作を加えていくのが楽しい。
630 :
デフォルトの名無しさん :2011/07/05(火) 18:31:04.62
>>629 お前がコードか日本語を読めないのはわかった
>>621 > というか操作とデータが一緒であることが理解できないっていうとOO全否定じゃね。
CLOS全否定だなwW
ソフトウェア工学を追いかける奴とソフトウェア哲学を追いかける奴のせめぎ合いか... orz OOPか... 森羅万象 オブジェクトとしての整理できる?
そんな高尚な話じゃないぞ 自分で定義したインターフェイスで何ができるかも把握できてないのにドヤ顔してた馬鹿が叩かれてるだけだ
>>631 CLOSこそデータと処理が一体化してるだろ。
処理自体がデータだし。
俺は
>>630 がおかしいとしか思えないけと。
あんまりインターフェースの事解ってないように見えるし。
正しく理解できてなかったら教えてほしんだが
>>606 に従ってRGBをHSVに変換するとして、
class RGBToHSVConverter : RGB, HSVConverter { void RGB.change(略); HSV HSVConverter.to(HSV hsv); }
みたいにすればいいの? これどうやって実装すんの?
changeに渡された値をフィールドに保持したら結局値オブジェクトになってしまうから無意味だよね
コンストラクタかなんかでRGBConverterへの参照を渡してフィールドに持っておくとしても、
結局値オブジェクトを経由してRGB値を取ってくることになると思うんだけど
それとも、既存のRGB実装クラスにHSVへの変換をサポートさせたかったら
それぞれHSVConverterを実装しないといけないの?
で HSV to(HSV hsv) { hsv.change(Helper.rgbToHSV(this.argbval)); }みたいなのをコピペしてまわるわけ?
>>635 レッテル貼りはいいから、
>>606 で
interface RGB{ void change(double r,double g,double b); }
interface RGBConvertor{ RGB to(RGB color); }
って定義されてるRGBConvertor(笑)が何をできるか考えてみろ
結局colorは呼び出し元に情報をもたらさないから、colorに依存しない値でchangeを呼び出すことしかできないだろ?
つまりRGBConvertorは手持ちのRGB情報を押し付けることしかできないインターフェイスだ
当然ネガポジだのセピアだのと言った変換も出来ない(出来るとしてもRGB側に実処理を書く必要がある)
このゴミ設計をどうしても使うとしたら、RGBConvertorをRGB値として使い、
RGB値を必要とするクラスでRGBを実装してロジック内で呼び出し、フィールドなりなんなりを書き換えて処理を行う必要がある
でもそれはスレッドアンセーフだから、結局別のRGBインスタンスにRGBのゲッターを公開してもらって使わないといけない
class ConverterImpl implements RGB { HSV dest; void RGB.change(r, g, b) { dest.change(convertRGBToHSV(r, g, b)); } } HSV HSVConverter.to(HSV color) { RGBConverter rgb = this.rgbSource; rgb.to(new ConverterImpl { dest = color }); return color; } 意地でも値のコピー作らないならこんな感じ? 汚っw
>>638 は論外として、なるほどな。
>>636 と
>>637 はConvertorって名前に騙されてんだ。
まぁ、名前のつけ方が変ってのは確かかもな。
>>589 を見ればtoで値をいじっちゃいけなくて、
change側で変更するって事が一目瞭然なのに。
>>606 をこう書き換えてやれば彼らは納得すんじゃない?
interface RGBConvertor
{
void analize(double r,double g,double b);
}
interface HSVConvertor
{
void analize(double h,double s,double v);
}
interface RGB
{
RGB to(RGBConvertor color);
}
interface HSVConvertor
{
HSV to(HSVConvertor color);
}
あミスった interface RGBConvertor { void analize(double r,double g,double b); } interface HSVConvertor { void analize(double h,double s,double v); } interface RGB { RGBConvertor to(RGBConvertor color); } interface HSV { HSVConvertor to(HSVConvertor color); }
>>641 その理解は
>>588 ですでに達してるんで
で、複数のRGBをもとにanalize(笑)するときはどうすんのって話
素直にゲッター付けろよ
あと(笑)ってのは「英語力が足りないんで中学からやり直してね」って意味だからね
Converterって書いた人もいたのに何も学ばないのね
なんだずっと粘着してたのか。必死度メーターが振り切れてるぞ。
>>643 >複数のRGBを元にanalize
?
いくら、自分が誤解してたからって
>>643 の言い訳は見苦しいわなぁ。
setter/getterのためにだけにここまでアイデンティテが傷ついてる人って。 ぶっちゃけ引き下がるに下がれなくなったんだろうな。
>>645 たとえばBitmap CreateLinearGradientImage(RGB, RGB, int, int)って処理を実装したい場合どうすんのかって話
引数別にクラスを分けるの?RGBが4つだったら?
って考えると素直にゲッター付けとけって話
やっぱり下駄と雪駄に、こだわるのって一種好みなんだろうね。 どうにもプログラムを英語らしく書こうとしたりする人やら、 型判別がある言語でメソッド名に型名いれたがる人とかと同じ感覚なんじゃないかな? そんな事したらオーバーライドしづらくなるんだけど、言語機能より人間の直感での わかりやすさが大事らしい。
もしかして: オーバーロード
好み、というかある程度は先に分類があるかも。 構造体的に使うクラスってやっぱ無くならないと思うし。 例えばpairみたいなやつね。 getしたりsetしたり、ってのがほとんど目的になるから。
>>648 RGB,RGBはなんとなく分かるけどint,intって何に使うの?
>>653 縦と横?
(ベクトルならまだしも、なんであんなところに登場すんのか意味が解からん・・・。)
Bitmap CreateLinearGradientImage(RGB begin, RGB end, Vector vector) { GradientArea gradient = new GradientArea( this.colorArray, vector ); begin.to( new GradientBegin( gradient ) ); end.to(new GradientEnd( gradient ) ); } つかメソッド名がきたねぇよ。なんだよCreateLinearGradientImageって。 Gradient.Paint(・・・)でいいだろうが。
>>655 それは
>>648 で予想してるとおりの実装だから書かなくてもいいよ
そのGradientBeginって中途半端なクラスを処理フローごとに分けるのが適切なのかって話をしてるわけ
その分だとRGBを使う画像ライブラリはよく分からん中間クラスで埋め尽くされるよ
>>656 それ別人
関数だったら良くてクラスだったらダメなのか。
void Paint(GradientBegin begin, GradientEnd end, Vector vector) { GradientArea gradient = new GradientArea( this.colorArray, vector ); begin.to( gradient ); end.to( gradient ); } てかこうやっとけばいいじゃん。 引数でグラデーションだと一目で分かるし。 メソッド名が汚くなくて済むし。
>>658 俺はフローのステップ別にクラスを作るなんてコストは払いたくない、まあこれ以上は個人の嗜好だけど
>>659 colorArray持ってるのならコンストラクターを呼んだ時点でGradientAreaは完成させられると思うけど
それにcolorArray[i].to(this)を複数回呼ぶのが嫌だから
>>655 になったんだろ?
あと引数で全部渡したのはこれ以外の値を使うなって意図もあったんだけど、伝わらないもんだね
>>660 colorArrayがRGBの配列とは限らんけどな。
俺は、C++でBlt転送する時につかうBGR配列のようなもんを想定して書いた。
まぁBGRであることは重要じゃないけど、デバイス直属のデータ領域に転送できるって重要だかね。
InputからOutputまで完結できるってことだから。
>あと引数で全部渡したのはこれ以外の値を使うなって意図もあったんだけど、伝わらないもんだね
まぁ、雰囲気は伝わるけど、適当な形が設計レベルで違うんだからどうしようもないさ。
void method(int,int)のメソッドで値を返せって命題を投げられても無理じゃん似たようなっもんさ。
void Paint(GradientBegin begin, GradientEnd end, Vector vector) { vector.to( this.gradient ); begin.to( this.gradient ); end.to( this.gradient ); this..gradient.update();//さっき書き忘れてた } やや不恰好だったんでもう少し整えた。 メモリ8バイト程度のメモリを無視するなら、 最初からgradientをコンストラクタで作っとく手もあるね。
663 :
デフォルトの名無しさん :2011/07/09(土) 10:45:25.83
>>662 単に高階化したら?
void Paint(RGB begin, RGB end, Vector vector)
{
GradientHolder gradient = new GradientHolder();
begin.To( gradient ); //内部でnew Gradient(int red,int green,int blue)を呼ぶ
gradient.analize( end ); //内部でGradientのanalizeを呼ぶ
}
665 :
デフォルトの名無しさん :2011/07/11(月) 11:55:11.51
ふと思ったので質問させてください。 C#やJavaで抽象クラスを使うべき状況ってどんな場合なのでしょうか。 これに関する設計を行う場合、以下の4つの使い分けがあると思います。 ・抽象クラス ・集約 ・別々のクラスに設計、クラスの分割を見直す。 ・インターフェース ・インターフェース+集約 これらを比較した場合、抽象クラスは利点より分かりにくさの欠点のほうが目立ってしまうように思います。 実際のところどうなんでしょうか。
その四つを並べて見せることに違和感を感じないか?
すいません、4つじゃなくて5つでしたね。 まぁ違和感は感じるんですが、自作クラスで抽象クラスが旨く使われている例が殆ど無かったもので。 いや集約でいいでしょこれ?みたいなのがほとんどなのです。
機能だけ見た場合、どれでも良いと思うけれども 使い分けは、ドメインモデルからコードに起こす際に発生するんじゃねーかしら? 抽象クラス ・実体として見た場合も、継承関係が発生する物 ・例としては、 「抽象クラス:自動車」 を継承した 「クラス:乗用車」「クラス:タクシー」「クラス:トラック」 等 集約 ・独立して存在出来る物を、他の実体にも内包したい場合 ・例としては、自動車に搭載するカーオーディオとか インターフェース ・独立して存在出来ないが、機能としては共通する物 ・例としては、自動車でも電車でも飛行機でも良いので 「エンジンを掛ける」 という行為 俺ならこんな感じかしら? 自分で見てもちょっと微妙だけど
抽象度のレベルが違うだろうに。 集約?←→継承 「OOPにおいて機能を再利用するためによく知られた二つの技法に、 クラス継承とオブジェクトコンポジショがある」という言い方。 インタフェースは広い意味ではオブジェクトの特性を定義したもの。 抽象クラスはそれに部分的な実装を与えたもの。 四つのうちから一つを選ぶようなものではないし、 四つ並べて語るようなものでもない。
>>669 そのレベルの話で済むなら、
>>665 みたいな疑問は出て来ないんじゃないか。
何かしら、例が有った方が良いんじゃないかね。
671 :
667 :2011/07/12(火) 17:29:18.58
みなさんレスありがとうございます。
>>668 原則としてはこの説明がしっくり来るんですよね。
抽象概念に対して具象、あるいはその逆でもあれば抽象クラス、部品を持つようになっていれば集約、行為を追加したければインターフェース。
>>669 抽象度のレベルが違うのですか。
個人的には継承でなければ旨みが無いという状況でない限り、設計でも再利用でもオブジェクトコンポジションにしたくなるのです。
設計で継承しようとしたら、.NETのコントロール関連の仕組みに匹敵するプログラム的な仕組みを作らないと旨みがない気がしますし、
再利用で継承を利用しよう、という考えは割と最初に放棄してしまいます。
>>671 抽象化クラスは、クラスであるためアクセス制御ができる。
やや変則的な話だけど、これを応用すると、ある抽象化クラスを
継承したクラスのオブジェクトのみしか参加できないネットワークを
構築することができる。
abstract class ChildNet
{
protected int abstract int privateValue();
protected int callPrivateValue(ChildNet group)
{
//子クラスは他の子クラスから値を抉り出す。
return group.privateValue();
}
}
これに加え、抽象化クラスなんで当然ネットワークに存在するオブジェクトに
義務を持たせる事が可能になる。
補足するけど、別に親クラスがダイレクトに自分の子クラスに 他の子クラスが持ってる値を渡してやる必要はなくて、 自分で噛み砕いた値を自分の子に渡してやってもネットワークは成立するよ。
元の「抽象クラスを使うべき状況」に関して言うと、
もうこれはケースバイケースとしかいいようが無いような気が。
ただ、
>>671 の言うとおり、上手く抽象クラスがフィットするケースじゃない限り、
コンポジションで間に合うし、そのほうが無難な事が多い。
C++とかの例で言うと、継承の場合ヘッダ(.h)は *必ず* 抽象クラスのヘッダに依存するが、
コンポジションの場合、実装(.c)が部品のヘッダに依存しても、
コンポジションしたオブジェクトのヘッダは部品に依存させないようにできる。
部品の実装やインターフェースに変更が入っても全体を再コンパイルする必要はない。
抽象レベルでの話題であることは分かるんだけど、
結局これから実装するものは実装レベルでの話も考えないと依存しまくりになる。
C#とかの依存の話は詳しくないので識者がいたらPLZ。
コンポジションじゃ多態できないじゃん なんでもコンポジションって、オブジェクト指向っていうよりただのコンポーネント化だよね
何で原理だけで結論つけてんだよw コンポジションオブジェクトのコンストラクタで部品の抽象ファクトリ渡すとかどうでもできるだろw
痛いくらいのニワカ臭。
>>676 それ続けていくと OOPの複雑さだけが協調されて インテリセンスが無いと手に負えないOOPの世界になるんでは?
まっ ツールがあるから使えという事も言えるが... チームプロジェクトの難易度が上がるような気がするが?
>>675 実装を使い捨てにしてインタフェースを再利用すれば
多態性を持たせるのは十分だろ。
>>678 >ツールがあるから使え
俺は正にこれ派だなあ
インテリセンス無しじゃ書く気がしない、とまでは言わんが
仕事としてはやりたくないレベル
俺は最近OOの設計も断捨離で行っている。 つまり 断=入ってくる要らない物を断つ 捨=家にずっとある要らない物を捨てる 離=物への執着から離れる これを 断=今必要なない実装をやめる 捨=使っていないクラスを破棄する 離=既存クラスへの執着から離れる(見切りをつけ新規につくる) いま必要なOOの実装だけを行い。 将来必要なるかもしれないと言って実装をしない。 あれは使うかもしれないとクラスやロジックを残さない。 とにかくシンプルに作る。これがOOの設計では一番。
っ[ YAGNI ]
YANAGI
YAGNIの再発明か…こうして独自ワードが増えていく
しかし、断捨離はヨガからきているから YAGNIの方が再発見かもしれない。 つまり真理とは古今東西、昔から変わらないということか。
みんな好きに呼べばいいのさ 俺は泥縄と呼ぶことにする
しかし、戦略もなく戦術だけで戦うのがいいことなのか? 単なる消耗戦にならないか?
戦略=将来起こりえる問題の解決/対処法。 戦術=目の前の問題の解決/対処法。 既存プログラムを改修するときは、現実の問題に集中すればいいが 最初にベースとなるプログラムを作るときは、将来への対応も必要。 例え、90%の労力が無駄になっても、戦術で行うにはそれ以上の労力が掛かる場合が多い。 よく経験するだろう、元の作りが悪いから修正しにくいとか もし、ソフトが永遠につかわれたなら、そのコストが莫大になうぞ。 まっソフトの寿命なんて大半が5年もないが。
うまく例えがはまってない感じだな。
俺用語を一々使いたがる奴とは、円滑な話がし難い
それはすまない。 目の前の現実と、将来への対応と言う意味で 戦略と戦術が俺のなかでは一番ピンときたから使った。 あきらかに俺の主観だな、別の言い方を考えるは。
10年くらいは普通だろ 無理にCのをC++に(better Cではなく)置き換えてるせいで OOP原則?ナニそれ? みたいなソース触った経験ある
業界に寄るし、年代に寄るんじゃねーかしらね。 昔作った物は、10年超えても稼動し続ける (稼動し続けさせられる) 様なのが多かったとしても これから新しく作る物は、そんなに長く稼動し続ける物はそう多く無い様な気はする。
昔作ったときも、そんなに長く稼動し続けるとは思いませんでしたw
>>696 まあ確かになw
俺は、10年も前に出来た様なソフト (Webアプリ) の保守・アップデート案件で
ここ3年くらい専業テスターやってるけど、3年前と今年は丸々リファクタリングだわ。
出来次第だろうな…。 俺が五年前にフルスクラッチで書いたクラサバは、 今も各所で元気に稼動しております。
5年なんて普通もいいとこ
5年というのは税制上の理由からくる場合も多い。 減価償却が5年だからな、馬鹿な経営者はソフトを作り変える。 まっ仕事も増えるから批判もできんが。
状態方程式ってのは OO 屋にはどう説明すりゃいいの? 話が噛み合わないっつか, 「ブラックボックスでええんちゃうの?」 つても、 「モデル化できへん」とか 言い出すやからと仕事する羽目になったんだが
>>702 入力と状態を引数に取って出力と次の状態を返す関数だよ、くらいでいいだろ
俺には「天文学をアメリカ人にどう説明すりゃいいの?話が噛み合わない」と言っているのと同レベルの質問に思える。
>>702 ええんちゃうの(笑)
できへん(笑)
そんな気持ち悪い言葉を使っているから意志の疎通ができないのでは?
ポリモーフィズムなんか使ってたら、ソースコードを読むだけでは実際に はどの派生クラスのメンバー関数が呼ばれてるのか分からなくて解析が 困難になるから困ると思う人は俺以外にもいるかいな。
>>707 それは思うが、メソッドのコメントアウトで結構どうにでもなる。
そもそろ論だけど、ポリモーフィズムを使うのは 既存ソースを変更しない為だから、既存のソースを読む必要はない。(機能が分かればいい) とは言っても、既存のソースを読まなければならなくなるのも現実だから 最低限トリッキーなコードは書かないぐらいの対応はすれば十分だと思う。 だいたい、読みやすい読みにくいは、その個人の技術力や経験に関係するから 誰にでも分かるよようなコードだと、初心者向けのコードになるけど、それは違うと思う。
IDEのメソッドの定義にジャンプする機能がないとコーディング出来ないのは事実だよな。
>>710 それはお前が馬鹿なだけw
ただ、あると便利なのは事実だな。
最近はポリモーフィズムとかで
メソッドの候補が複数あるとき、
ちゃんと候補を出してくれる。
>>707 どんだけレベル低いんだよ。クラス図見ろよ
といいたいところだけど、ロクに設計されずドキュメントも起こさず
思いつくままにダラダラと派生クラス作成してる現場も沢山あるよな
と思った。
幸いにもそれで困ったことは一度も無いが、 だがしかし、簡単に想像はつくな。 チームでやっててアホな展開にどんどん突き進むような場合。
クラスAを元にクラスBのインスタンスを作る場合、 間に生成クラスみたいなのをはさんだほうが良いでしょうか?
言語ランタイムの設計思想に関してはお答え致しかねます
質問です。外部データ(DBやファイルなど)を扱う時に そのまま扱う場合と、オブジェクトにマッピングして使う場合があると思いますが (この場合のマッピングは、機能のラッピングではなくフィールドへのマッピングです) どのような設計基準で使い分けるといいでしょうか?
ORMするのがほとんどだと思う というのも最近の開発環境ではIDEを使うのが一般的で、 IDE上ならメンバ名の自動補完やヘルプを参照しやすいのでプログラミングし易いから 対してそのままSQL的にアクセスするのはメンバが不定/未定な場合に使うときがある すっごく稀なのでヒューマンエラーをものともしないテスト以前の動作確認のときに使うかな ただし個人的意見なのであまり参考にならないな
そうですね。基本的にはオブジェクトが良いと思いますが レスポンスやスタックオーバーフローとかの問題でどうしても そのままのデータを使用しないといけない時がありますよね。 開発の途中で問題が発生した場合など影響が大きいので あらかじめ配慮してつくるべきなのかなと思っています。
>>311 >ありがとうございます
いいぇ、私は何もしていません。自分自身で解決していると思います。
>data_d:array[0..10000000,0..30] of double
Integerの場合は、「data_d:array[0..10000000,0..60] of Integer」と定義しても大丈夫なんでしょうか?
>>312 >静的配列と動的配列はメモリ確保の方法が全く違うんだが
すみません、"全く違う"とはどう違うんでしょうか?教えて下さい。
>>313 >ローカル変数として確保しようとしてスタックオーバーフロー起こしただけだったりして
すみません、ローカル変数の確保がなぜ”スタック”オーバーフローになるのか、教えて下さい。
delphiってローカルの配列にもヒープ使うんだっけ スタック消費するならオーバーフローするのは当たり前な気がするが・・・?
722 :
デフォルトの名無しさん :2011/09/15(木) 00:28:47.64
Singletonの例としてよく出てくるクラスメソッドでオブジェクトを返すデザインの意味が解からん。 実体を持つstaticフィールドを1個だけもち、全てのインスタンスが、そのフィールドに問い合わせ するようにしても同じじゃん。 classs Logger { private static LoggerCore core; public Logger() { if( null == core ) core = new LoggerCore(); } }
>>722 何が便利なんだか、わからん。
ただ、LoggerでLoggerCoreの全てのメソッドを、いちいち委譲しなきゃならなくなった
だけなのでは?
>>723 Core自体は処理をもたなくてもいいんだよ。
言語によっては構造体でいい。
あと、シングルトンで継承しない場合はともかく、
したほうが良い場合でも、staticメソッドを使う場合は
上手く継承できない。
更に言えば、コンストラクタでオブジェクトを生成するのを
前提としたインターフェースに対し、staticメソッドでオブジェクトを返す
シングルトンオブジェクトだけは特別扱いしなきゃならない。
object.exampleNew(Logger.class); //Singletonも他のクラスと同様に生成できるべき。
725 :
デフォルトの名無しさん :2011/09/18(日) 17:37:53.97
>>722 new LoggerCore(); でインスタンスを生成されると困るから
Singletonにするのでは?
LoggerCoreをLoggerのprivateメンバーにすりゃいいだけじゃん。
それはファクトリ
実体が一つしか無いのにファクトリとはコレいかに?
Monostateパターンのこと?
>>724 「Coreが処理を持たない」って、データだけ持つの?それで隠蔽化できてるの?
あと、シングルトンであるべきか否かはクラスの責務で決まるはずだから、継承したら変わるのでは?
まぁ「コンストラクタでオブジェクトを生成〜」は分からんでもない。シングルトンオブジェクトを
ラップするクラスを作る必要があるので、確かにこれに似た状態になるな。
と書いてから、
>>725 が一番正しい事に気がついた。コンストラクタをprivateメソッドにしたいんだ。
>>726 が実現できるのは、内部クラスを作れる言語だけだ。
特にstaticメソッドで実体拾うクラスに劣るところはないと思うけど。 class Logger { private static class LogField { int data1; int data2; } private static LogFiled core; public Logger() { if( Logger.core == null ) { Logger.core = new LogField(); //必要なら初期化 } } //他coreを操作するメンバー }
PACパターンって最近知ったんですが 例となるクラス図が載ってるサイトありますか?
>>732 確かにそれでもシングルトンにはなるけど、
new Logger()だと中身が共有されてるってことを想像しづらいから、staticメソッドを使うんだと思う。
new Loggerみたいなことを制限させるためのシングルトン、という観点も考えたほうがいいんじゃないかね。
736 :
デフォルトの名無しさん :2011/09/20(火) 11:49:03.57
new出来ない事に意味はあるの? むしろシングルトンと通常のオブジェクトを インターフェース的に区別する必用がある?
737 :
デフォルトの名無しさん :2011/09/22(木) 01:05:30.38
>>736 すべてのクラスは引数なしのコンストラクタを持つべきって主張してるわけじゃないよね。
シングルトンなんて使わずにモノステートを使おうよって話?
例にあるLogger自体はシングルトンじゃないから、シングルトンの説明に使おうとするなら根本的に間違ってると思うけど。
738 :
デフォルトの名無しさん :2011/09/22(木) 09:47:13.61
>>737 引数があるかどうかはどうでもいいんだけど、
他のオブジェクトとインターフェースは同一にすべきとは考えてる。
リフレクションとか使う既存のリソースを再利用できるからね。
シングルトンと違うってのは、staticメソッドを使わないから違うって事言ってるの?
それとも空のインスタンスが生成されるから機能面で違うといってるの?
739 :
デフォルトの名無しさん :2011/09/22(木) 09:57:37.36
>>737 モノステートとはちょと違うね。
例では分かりづらいけど、全てインスタンスメソッドだから。
monostateってstaticなのはフィールドだけじゃなかったっけ?
>>733 PACパターン で画像検索
>>739 なるほどねー。ググったらstaticメソッドだらけのクラスを
モノステートと呼んでる所があったから違うと思ったけど、
ググり直したら全部インスタンスメソッドのものを
モノステートと呼んでる所があった。
これからはモノステートを
調べる事にするわ。
monostate と singleton でググたかんじ 完全に monostate が singleton の上位みたいな感じだな よっぽど継承を封じ込めたくてfinalも無いような環境か アドレスレベルで比較して同一と判断しなきゃならない場合を除いて 基本的に monostate を使っとけばいい感じだな。
最近気づいたんだけど state/strategyとFactoryMethod使うと OOっぽさが6割増し位になるよね
どっちかというと関数型的じゃね
数独ソルバを、UML を丁寧に書いて設計する例が載ったWebページはないでしょうか 自販機とかの架空の例や、顧客どうのこうのといった大きな例じゃなく、 小さなアプリを UML の記述から始めて OOP で作って完成させる例がほしいです 解説する言語も、プログラミング言語も問いません 数独ソルバ程度の小さなアプリであれば数独ソルバでなくてもいいんですが、 数独ソルバの例だとありがたいです
宿題スレに逝け。
>>746 いや、宿題じゃなくて・・・
関数型言語スレで、関数型言語だとUMLは書かないのかという質問があって、
OOP と FP でアプリの作り方(完成までの道のり)にどれくらい違いがあるのか興味が沸いて、
比較してみようと思いました
それで、既に UML を使った OOP での例があるなら、
OOP の方はそれを拝借した方が手っ取り早いと思っただけです
無いのでしたら、自分で両方の言語で試してみます
なぜ数独ソルバにこだわるのかな? 一般的なUMLベースのOOP入門という題材なら「いくらでも」ころがってる 目的と手段をはき違えているように見える もしどうしても数独ソルバにこだわりたいのなら、宿題スレへ逝ケ
>>748 「数独ソルバでなくてもいい」
>>745 で言いました
> 一般的なUMLベースのOOP入門という題材なら「いくらでも」ころがってる
UML を使ってゼロから設計してアプリケーションとして完成させている例が無いです
「いくらでも」と言うのなら 10 例くらいWebページを挙げてほしいです
UMLで図を描いて終わってるページや、ソースコードだけのページはありますが
数独ソルバなら、パラダイム間で設計手法を比較する例としては
登場すると思われるクラスの数も多すぎず少なすぎず、
またデータが入力されたら解の出力まで処理が一直線なので、
クラス全体の関係を比較的見通し安いと思ったからです
今のところ他にいい例が思い浮かびません
また、FP の方では数独ソルバを既にゼロから設計して完成させているので、
OOP の方でも同じ例の方が楽です(別の例なら FP の方でも新規に作る必要がある)
べつに拘っては無いので、何度も言いますが、数独ソルバでなくてもいいです
> 目的と手段をはき違えているように見える
目的は
>>747 のとおり設計手法の比較で、手段は(今のところ)数独ソルバですけど
履き違えてるように見えたのですか?
馬鹿には無理
>>750 無理かどうかはどうでも良くて、そういうWebページがないかどうかです
いくらでもあるそうですけど・・・
そもそも論として、オブジェクト指向的なモジュール化の恩恵が薄い題材だと、 そういう題材でサンプルを作ろうという話がそもそもない、というのはあるかもよ。 調べてないから想像だけど。 試しに、軽く自分で設計してみたらどうか。
>>752 その軽く設計ってのを省けるなら省きたいって質問なんだと思う。
すでに数独ソルバで片方やっちまってるからOOP版があれば欲しい、
ないなら数独ソルバには拘らないからOOPで設計実装してるの何かない? ってことだと思うんだが。
あとどうでもいいけどFPって聞くと見積りの方が先に出てきて変な感じだ。
>>754 その数独ソルバってのがよく分からないんだけど、多分アルゴリズム系だよね?
題材自体が、責務でインタフェース切ってオブジェクトに分割して、という方法論と
合わない気がするなぁ。
それ以外でもいいということなら、なんか著名な書籍を一冊買ってくるとかの方が早いかも。
>>754 もの凄く分かりやすい代弁ありがとうございます
私も3行で自分の発言をまとめられる人間になりたい
>>755 私にとってはアルゴリズム系という意味の方がよく分からないのですが・・・
トイブログラムとか実験プログラム、検証プログラムとかの類じゃなくて、
ユーザーが数独の初期配置を画面に入力し、解答ボタンを押すと、
その数独の解答が表示されるというアプリです
当然、問題自体が間違っていて解答が複数存在すれば複数表示されますし、
解無しなら解無しと表示されます
すいません、その「著名な書籍」を一冊教えていただきたいです
今まで買ったオブジェクト指向の入門書や方法論的な本、UMLの本などは、
使えるアプリケーションとして完成させるまでに至っていませんでした
コアの部分をサンプルや例題として使ってオブジェクト指向的に考えたり、
アプリの全体的な設計図をUMLで表す道筋を何かのサンプルで示す、
というものばかりで、どちらも解説は丁寧ですが、「ゼロから完成」が無いんです
Webページも上記のパターンのどちらかのしか私は見つけられませんでした
いくらでも転がっているそうですけど
自分で作ってもいいんですが、私のようなオブジェクト指向未熟者じゃなく
お手本となるようなページを探してましたが、無さそうなので、とりあえず諦め、
拙いなりに自分でゼロから作る事にします
ありがとうございました
もしかしてと思って調べてみたら、「代弁」の使い方間違ってましたね 正しい意味を始めて知りました
>>757 すいません、意味合ってました
これだから電子辞書は ヽ(`Д´#)ノ ムキー
>>756 ああなるほど、そういう「アプリケーション」レベルの設計の話か。
残念ながら、俺も「あるなら教えて欲しい」という感じなので力にはなれそうもない。
ただ、どんな手法でもウェブ上で「アプリケーションを一から設計して〜」というサイトは見たことが無い。
「ウェブは暇人によって支えられている」とは誰かの言葉だが、そういうメディアじゃないんだろうな、ウェブは。
なので本で探した方が確率は高いとは思う。
個人でちょっと作れる規模のシロモノなら、一々設計書なんて書かないというか TDDやプロトタイピング等で、ソースコードを設計書代わりにしちまうしなあ
数独解くなら、設計レベルか知らんけど、 1マス1マスをオブジェクトにするとかあるな。 マスに当てはまる候補を格納したり、 マスに所属するグループ持たせたり、 グループをオブジェクトで表現したり、 枠の判定を多態で表したり。
ネコ目(食肉目) Carnivora ・ネコ亜目 Feliformia ・ネコ科 Felidae : ネコ類、18属37種 ・イヌ亜目 Caniformia ・イヌ下目 Cynoidea ・イヌ科 Canidae : イヌとその類縁、10属35種 この分類納得行かないよなw イヌ科の元がネコ目だなんてw
どこの誤爆だ
764 :
デフォルトの名無しさん :2012/01/12(木) 23:56:38.89
QueryInterfaceのパターンってdynamic_castより柔軟で便利なのはわかるんだけど オブジェクト指向的な考えからするとdynamic_cast同様あまり良い設計とは言えないものなのかな?
どのへんがdynamic_castより柔軟なの? プロセス超えるからわざわざ書いてるだけで 面倒なだけだと思うけど。
766 :
デフォルトの名無しさん :2012/01/13(金) 00:39:51.73
>>765 dynamic_castだとインターフェース以外にも正常にキャストできるけどQueryInterfaceはそれを制限できる、とか
直接的な継承関係がなくてもインターフェースを継承しているメンバのアドレスを返すことで代替できる、とか
767 :
デフォルトの名無しさん :2012/01/13(金) 20:27:05.48
>dynamic_castだとインターフェース以外にも正常にキャストできる どいうこと!?
継承関係にあるすべてのクラスに問題なくキャストできるって意味じゃないの?
公開してないインターフェースにキャストしようがないでしょ
QueryInterfaceのほうが10倍早いのが利点だね
速度が気になるところで使うか?
ゲームの衝突ハンドリングとか?
衝突で使うことなんて無いわ
いや、使うだろ
バンディングボックスと三角のベクター、ベジェ、楕円。 この4つぐらいしか判定要素に使わんからワザワザ型判定する必要もない。 衝突判定対象要素の全に対し、この要素を取得できるようにしとけば済む。
>>775 衝突するかどうかの処理じゃなくて
衝突した後どうなるかの処理だろハンドリングって書いてあるし
ハンドリングならますます使わんだろ
各オブジェクトに衝突後の軌道パラメータを設定するのが普通だよな ハンドラなんかいらない
物理シミュレーションならそれでいいだろうけどゲームではそうはいかないだろ 例えばタンクと下半身の壊れたガンダムが良い感じの角度と速度で衝突した時は特定のモーションを経て合体してガンタンクになる というような処理は全オブジェクトに共通する通常の衝突処理フローでは実現できない
特定の相手に対して、特定の振る舞いをしたい場合、 オブジェクトを生成した際に特定オブジェクトのセットへの参照を 持たせておいて、衝突判定が降りた際、その衝突した 対象のID(もしくはポインタ)がセットの中に存在するかチェックすればいい。 そのほうが処理が早いし柔軟性も効く
781 :
デフォルトの名無しさん :2012/01/15(日) 01:42:58.29
そのやり方はとても現実的とは思えない 特殊処理が必要な型が増えるたびに冗長なコレクションを増やして、 しかも衝突するたびにそのコレクションから検索する、だなんてどうみても安くはつかないぞ
まぁまじめにやると > そのやり方はとても現実的とは思えない なるだろうけど、らしく振る舞うだけなら省略できる部分がたくさんあるわな つか、 計算しなくても済むところまで計算してるだろ?
特殊動作の対象が100や200も居るわけじゃない。 現実には0〜5程度。現実にはdynamic_castなんかより setの方がコストは低いよ。とくにHash setにしてしまえば歴然。 あと、setであれば、その型が何かで限定する必然性は無くなる。 set<Tank*>, set<Gundom*> なんて分ける必要なく、set<Unit*>ひとつでいい。 入れられるオブジェクトを制限したい場合は別だろうけど。 コレにより、人間の見たキャラでクラス分けしなくて済むようになる。 機能でクラス分けすればよくなる。
・ある機能を持っているオブジェクトは生成時に共有レジストリに登録しなければならない あるオブジェクトがその機能を持っているかどうかの問い合わせはそのレジストリから検索してあたりがあるかどうかで調べる オブジェクトが死んだらレジストリから削除しなければならない 拡張によって特殊な機能が増えと新しいレジストリを作らなければならない ・ある機能を持っているオブジェクトかどうかそのオブジェクト本人に問い合わせる 拡張によって特殊な機能が増えてもその追加された機能を継承するクラスだけQueryInterfaceメソッドに1行追加するだけで良い どっちが目的を明確に表していて、シンプルで理解しやすく、効率がいいのか、一目瞭然だろう
組織より一般犯罪者のほうがコナン追い詰めてるじゃねーか
786 :
785 :2012/01/15(日) 13:15:35.28
すいません誤爆しました
明確かどうかより拡張性さがるのが問題 パターン1個追加するたびに、関係するクラス全部変更ってのは不便。 人間始点ベースで組むと得てして拡張性は下がる。 たとえば、画面上のキャラ座標(固有ステータスも含む)と、 キャラクラス(形状データ、アクションデータ)はオブジェクトとして 一緒にしないでしょ。キャラ座標に、キャラクラスへの参照を持たせる。 拡張性を考えるなら見た目と、データ構造は一致し無いのが普通。
>>784 >拡張によって特殊な機能が増えてもその追加された機能を継承するクラスだけQueryInterfaceメソッドに1行追加するだけで良い
無理
>>787 >明確かどうかより拡張性さがるのが問題
>パターン1個追加するたびに、関係するクラス全部変更ってのは不便。
QueryInterfaceは拡張性ぜんぜん下がらないよ
むしろレジストリに登録する方がクラス間の参照関係、依存関係が増えて拡張性が下がる
そもそも、ある対象から、ある対象に対する動作を、 駒となるオブジェクトに持たせる必要が無いんだよ。 散々トポロジーの分野で使い古されてるネタだけど、 ある駒から、ある駒へのノードそのものをオブジェクトにして そこにアクションを持たせておけばいい。 もちろんフルコネクトで繋ぎあわせると組み合わせが莫大になるから その辺は、論理上のクラス(OOのクラスじゃない)で分けるんだけどね。
>>789 そもそもQueryInterfaceをどうやって使う気なんだい?
クラスとオブジェクトのデータ構造が見えないから、
先入観で悪い使い方してるようにしか見えない。
>>789 登録方式ならクラス間の依存性は増えないよ
他のクラスの事なんて全く知らないからね
>>791 いまの流れで言ってるのは能力照会だよ
すごい適当に擬似コード書くならこんな感じの
衝突後処理(a, b)
合体可能インターフェース * p = 0; a->QueryInterface(合体可能インターフェースID, &p);
合体可能インターフェース * q = 0; b->QueryInterface(合体可能インターフェースID, &q);
if(p && q) { 合体処理(p, q) ; } // 両方共合体能力を持ってるなら合体
else { 通常処理(a, b); } // そうでないなら普通に衝突
>>792 クラス同士がお互いのレジストリクラスのこと知らないとだめじゃん
const Kind tank; const Kind gundom; NodeSet set; set.Register( new NodeActionA(), &tank, &gundom ); Unit unit_a( &gundom ), unit_b( &tank ); set.Conflict( unit_a, unit_b ).ActionDriven(); ノード制御ならこの3つを増やすだけだから楽だぞ >const Kind xxxx; >set.Register( new NodeActionA(), &tank, &gundom ); >new NodeActionA()
>>793 それだったらQueryInterfaceやdynamic_castの類を使う必要はないよね。
単にIDを持ってるかどうか判定できればいいだけじゃん。
合体可能インターフェースなんて、クラスの依存性が増えるような物も必要ないじゃん。
796 :
794 :2012/01/15(日) 14:08:48.56
>.ActionDriven(); 衝突情報を渡すの忘れてた。まぁいいか。
>>794 あぁなるほど
RTTIオブジェクトのペアから衝突処理へのテーブルを用意するのか
ちょっとためしてみるわ
>>797 もしかしたら誤解されてるかもしれんから
補足するけど、RTTIじゃなくアドレスをキーにしてるだけよ。
KindがRTTIの役割をするってのはそうだけど。
しかし、OOP’erって凄いよな。 昨年、俺らハードグループに配属(左遷)された癖の強いプログラマーがやってきて、 Cでさらさらとテストプログラムを完成させていくのを見るにつけ異人種だな! あちきは、PICマイコングループだが、あんなメモリ量しかないのにようやるわ。 ソース見てもコメントのステートとかストラテジーとかブリッジとかちんぷんかんぷん。 わしらの今まで書いていたテストプログラムはいったいなんだったんだ?
クラス
「move a b」みたいなコマンドが何行も続いたスクリプトもどきを解析する奴が作りたい 仕様 ・条件分岐やループ関連のコマンドはなし ・変数も使えない ・区切り文字はスペース、先頭の単語はコマンドを表し、それ以降はコマンド子固有のパラメーター とりあえず、ファクトリーパターンでコマンドごとにIOperanインターフェイスを継承したオブジェクトを精製し、それに処理させるという形を考えてみた これより拡張がしやすい設計の仕方があったら教えてほしい
なんだかんだでswitch文の方がメンテしやすいことも多い
↑OOPがわからない素人にとってメンテナンスしやすい という意味でした。
ちょいあげますけど、WindowsプログラミングにおいてMVCがどう当てはまるのか、
誰か教えてもらえないっすかねぇ。
http://ja.wikipedia.org/wiki/Model_View_Controller の「MVCのシナリオ」のフロー通りに見ていくと
1&2で、まずWM_LBUTTONDOWN辺りのメッセージが、コールバック関数に送られてきますよね。
このコールバック関数があるスコープを仮にMainと呼んだとして、これをControllerと解釈していいんですかね?
3で、左クリックのイベントに対し、先のコールバック関数から、ModelクラスのHogeを読んで数値を+1したとします。
そしてHogeはObserverとして持っていた、Viewクラスに変更を通知します。
4で、Viewクラスが、例えばオフスクリーンサーフェスを更新して、InvalidateRect()します。
するとWM_PAINTを受け取ったMainがフリップします。Controllerが画面描画しちゃいますが。
こんな感じでいいんですかねぇ。なんかあまりすっきりしないというか、素人目には当たり前に見えてしまうというか。
上げ忘れてましたが、まぁ上げないほうがいいっすかね。
なんでこんなに偉そうなんだ?
806は天文学部か帰宅部か
Win APIでならこんな感じでコントローラーを実現したなぁ。 HWND window = CreateWindowEx(・・・); Binder binder( window ); // CallbackをフックしてObserverに委譲するバインダー CloseController control( window ); // 引数で受け取ったWindowを閉じるコントローラー binder[WM_LBUTTONDOWN] += &control; // WM_LBUTONDOWNイベントにコントローラーを登録
809 :
デフォルトの名無しさん :2012/06/24(日) 18:50:30.45
>>724 >staticメソッドを使う場合は 上手く継承できない。
SingletonとMonostateの比較でよく言われるけど、これってどういう現象を指してるんだ?
>>810 オブジェクトで振る舞いを定義してるところ。
どうでもいいが、WindowsのWindowClassってのは、
Windowsの中じゃ唯一まともにOOPを実現できてるところよ。
CreateWindowでオブジェクトを作り、SendMessage,
PostMessageで、Smalltalkや、Objective-Cと同じ
メッセージパッシング機構を実現した。
どんくさい環境での妥協案ではあったが、なんとか
そこだけはパロアルトの意志を継いでる。
そうだね 継承も出来るし
そう?個人的にはWindowsのAPIって全体的にOOPしてると思うよ ポインタや参照をハンドルって形にしてるだけで 全然別種のオブジェクトを同じAPIで使用や解放する辺りも多態っぽい
>Windowsの中じゃ唯一まともにOOPを実現 COMの方だろ。
>PostMessageで、Smalltalkや、Objective-Cと同じ >メッセージパッシング機構を実現した。 全然違うwww
どこが? object x:10 y;10. 形式じゃないとメッセージ文に非ずと? 重要なのは、メッセージをメソッドと独立したデータとして扱える点だろ。
>>814 COMはC++風OOPで、Smalltalk系統とは違うからなぁ
>>814 WindowsというかWinAPIね。
>>813 Windowと違ってユーザーが拡張できんからねぇ。
WindowClassなら、他のOOと同じく、移譲・集約・継承による
拡張ができるじゃん。当然、既存のウィンドウの子ウィンドウを
差し替えられて、ブリッジパターンの様な事すら可能だ。
しかもプロセス間においてもメッセージ送信が可能でSmalltalkや
Objecitive-Cのメッセージパッシングに非常に近い。
SmalltalkやObjective-Cって、PostMessageの様な メッセージの遅延送信ができてキューイングも出来るんだよな よく似てる
嘘を嘘と見抜けない人は2chに向いてない
NSInvocationをキューに突っ込んでやればいいぶん 汎用性が段違いだがな
824 :
デフォルトの名無しさん :2012/07/01(日) 17:54:50.46
質問スレで質問してたのですが、場違いっぽくて触ってももらえませんでした。
移動してきました、よろしくお願いします。
スレ立てるまでもない質問はここで 119匹目
http://toro.2ch.net/test/read.cgi/tech/1337067149/912 912 名前:デフォルトの名無しさん[sage] 投稿日:2012/06/30(土) 09:43:05.16
observerパターンで大規模なmodelとviewを繋いでいるとき、更新を通知されたviewは
どのようにしてmodelの変更を取得するべきでしょうか?
model小規模な場合は、逐一全部読み直してもいいと思うのですが、
たとえば、例として、リモートで複数人のユーザによる同時編集が可能な
テキストエディタの実装を考えた場合、以下の点が問題になると思います。
・更新予定箇所の予測は不可能
・1文字更新が入るたびにすべてを読み直すことは、現実的に不可能
解決方法として、
・push型observerにして、commandパターン的な発想で差分を通知する
・更新IDを保持していて、通知時に保持しているIDからの差分をダウンロードする
あたりを考えたのですが、model,view双方の実装が若干複雑になってしまいます。
modelをシンプルに保ちたい場合、なにか賢い解決策はないものでしょうか?
テキストエディタなら無限undo実装するんだろう? それ流用すればいいだけじゃないかな
>>824 俺だったら後者の差分ダウンロードにして、
リアルタイム同期が必要になったら差分ダウンロード型のままcomet化する
上で出てるけどundoとかもあるから、どのみちヒストリ型にしておいた方が
後々高機能化にも良いんじゃないかな?
そもそも、画面に表示してなきゃいけない文字も多くないだろうに。 画面から何文字必要なのか送ってやりゃトラフィックも多くはならんだろ。 あと、メモ帳ならベクター系のデータ構造じゃなく、行単位とか n KByte単位のブロック構造をリストでつないでデータを管理してるはずだろ。 ビューにキャッシュさせて編集が影響したブロックだけ転送してやればいい。 ビューはモデルとの同期は必須だが、別にデータをもってちゃいかんわけじゃないから。
ふと思ったんだけど、 オブジェクト指向厨にテトリスを作らせたら ■■ ■■ ←このブロックをどこまで細分化する? ↑ ちゃんとやるなら こうなるんだろうが class Block_main ← 4つの塊 class Block_object ← 1個1個のブロック end end テトリスごときでどんどんソース冗長していくよね ほんとにオブジェクト指向はゴミだなと実感する
ゴミが設計するとそうなる
830 :
uy :2012/07/04(水) 10:28:04.55
>>829 この問題はゴミとか関係ないよ
一番いいのはオブジェクト指向では作らないことだが、
オブジェクト指向厨はさてどうするのか
最後まで完璧にオブジェクト指向をつらぬけば
>>828 こうなる
ある意味、優秀だからこそそこまで貫ける
しかしオブジェクト指向でテトリスかくんだったら途中で妥協して
class Block_main
end
のクラスのみで作ったほうがソースはマシになる
自分がゴミじゃないとよく喚くゴミ。
>>830 OOは全てをオブジェクトにするのでなく
問題領域をオブジェクトにするもの
1個1個のブロックをオブジェクト化して何の「問題」を解決するのか?
問題領域を考えずに闇雲にオブジェクト化すれば何の役にも立たないゴミが出来上がる
つまり
>>828 は貫くとか妥協とかでなく単にOOを理解していない奴が書くゴミ設計
ブロック同士の相互作用としてテトリスのロジックを記述するのが理想だが俺には無理
Factoryの生成物として、オブジェクトの配列を返す場合 ファクトリークラスのインターフェイスは、 1 std::vector<IHoge*> createProduct(); 2 std::vector<std::shared_ptr<IHoge>> createProduct(); どっちがいいんでしょうか。 心情的には、2にしたいんですが、いかんせんかっこわるい気がします
>832
ほんっとーにわかってないゴミだな
■ ← これひとつで画像オブジェクト1個なわけで
当然その画像オブジェクトを格納する為の変数が必要になる
それを配列で管理するか、クラスオブジェクト*4で管理するかという話
問題領域w とかいう話ではなくて
お前は問題が発生してから設計しなおすのかよバカ
理想は■1つ1つをクラスオブジェクトにして、x,y座標を持たせてタスクにする事だろう
>>833 そういう事
普通に考えたら面倒で無理だ
優秀な奴ほど完璧にやろうとしてこれにハマる
>>832 みたいなゴミには縁の遠い話か
と自己弁護を重ねるゴミ
優秀なやつは適切な妥協ができる人間だから こんなショーもないことでハマらないよ
>>832 あぼ〜んになってる奴を擁護するわけじゃないが、
振る舞いを変えたいものは、振る舞いを変える単位で
オブジェクト化すべきで、別にブロックがオブジェクトでも構わんと思うぞ。
例えば、ブロックを単純な点からアニメーションアイコンにしたい場合、
ブロックを差し替え可能なオブジェクトにしておいて、
アニメーションブロックオブジェクトに変えることが出来る。
オブジェクトを使わずベタ書きしていれば、ブロック周りの操作を
書きなおさなきゃならないが、オブジェクトなら新しいファクトリークラスと
アニメーションブロッククラスの作成、そしてそれらを組み合わせるコードだけで済む。
あと、デザパタ本じゃ、理想は文字一つ一つもオブジェクトであるべきだとか言ってたしな。
839 :
uy :2012/07/04(水) 23:54:51.69
>>837 適切な妥協をしてしまう奴は、技術者としては優秀だけど
処理能力的にはスペックが低い
>>838 文字一つ一つもオブジェクトってそれはFONT読み込みとFONTの作り方を知らないただのバカだろ
本当に優秀であれば妥協したテトリス設計と
妥協しないテトリス設計の両方をかけるのであまり俺様には関係ない話
>>838 こういうこの程度の話題に長文書いてしまう奴にとっては、大変重要な問題かもしれないが
コイツはおそらく妥協しないソースコードをかくタイプの奴であろう
そしてテトリス程度(笑)で2000行とか超えるソースコードをかいてしまう
841 :
uy :2012/07/05(木) 00:31:45.21
(笑)
842 :
デフォルトの名無しさん :2012/07/05(木) 06:55:23.86
優秀な香具師は車輪の再発明なんてしません
843 :
uy :2012/07/15(日) 03:06:36.61
キリッ
OOPの説明の時に馬鹿の一つ覚えみたく 動物から派生させて、人、クジラ 図形から派生させて、三角形、円 なんて説明するひとって馬鹿なの? 実際にUnix上でプログラムを作成する際に それらの例があてはまるか?
>図形から派生させて、三角形、円 描画用ならこれはよくあるぞ
ねぇよ ObjectARXみてみろよ 実際にそんな実装はありえない
853 :
デフォルトの名無しさん :2012/07/15(日) 21:34:05.04
>>834 そのポインタ入ったvectorはどのくらい広範囲にコピーされるの?
再発明ってなんですか?
辞書にはない
>>845 実際問題現実じゃ使いづらい。
aut painter = meta->CreatePathPainter();
painter->PathMove( Vector<2>( 10, 10 ) );
painter->PathTo( Vector<2>( 10, 10 ) );
painter->PathCurve( Vector<2>( 10, 10 ) );
aut painter = meta->CreateFigurePainter();
painter->DrawRect( Point<2>( 0, 1 ), Point<2>( 0, 0 ), Point<2>( 1, 1 ) );
実際こんな感じで描画用インターフェース作って、
描画デバイス別に実装変える形式になるからな。
メタ情報を維持したままデバイスに書き込んでやらないと、
メタ情報が劣化するんで描画速度が落ちたり容量が増えたり不便なことになる。
>>857 ほっといてやれよ
サンプルコードを動かしてるだけでOOPやってると勘違いしてるアフォなんてw
>>857 で、現に非常によく使われてることについてどう思うの?
定義だけしてあって実用性が殆ど無い。 Qtにしろ、Androidにしろ、CanvasやQPainterばかりが強化され 利用されてるのが現実。確かに複合図形をオブジェクト化する事には メリットがあるが、単純図形をオブジェクトにしたってすぐにCanvasや QPainterにあたる描画インターフェースに取り残される。 あくまでも入門者向けのおもちゃだ。
>>859 数えるほどしか使われていないだけで非常によく使われているわけではない
描画に関してはなぁ。下手にOOP持ち込んで抽象化目指すより、 いつでももっと目指すべきもんがあるからなぁ。速度な。 だって目標とする速度がでなきゃぁ製品としてリリースできないもの。全部ダメだもの。
>>862 ピクセルレベルで仮想関数つかってるならまだしも、大抵問題になる事はないぞ。
DirectXなんてそこらじゅう仮想関数だらけだ。
>>854 生成以降、vector自体のコピーはないです。
利用者(といっても、自分)にstd::shared_ptrと打たせるのがなんか嫌なだけなんですけど
スマポの有無ごときで普通格好がどうのとか気にせんから好きにしろとしか言えんな。 個人的には、どっかの名前空間でtypedefしたりする。 namespace SharedPointer { typedef boost::shared_ptr<::Product> Product; } using SharedPointer::Product; std::vector<Product> product;
>>865 そんな程度の理由でshared_ptr否定とか、どんだけ規模小さいコード書きしかしてないんだよw
キー入力が面倒くさいからって変数を全部1文字にするのと大差ない理由じゃねーかw
>>834 かっこ悪いかどうかを気にするんなら、
俺ならもっと単にシンプルにするな。
Hoge *HogeFactory::create();
こんだけ。もちろん、パラメータを取るオーバーロードメソッドも必要に応じてつくる。
XxxFactory::create()はXxx *を返す。これだけ。
vectorだの、shared_ptrなどは出てこない。
ファクトリ、というクラスの本懐を果たす。
それ一つあればレンジアルゴリズムと組み合わせられるからshared_ptrバージョンだろうが、vectorバージョンだろうがその組み合わせだろうが簡単に作れそう std::vector<Hoge*> hs = replicate([](){ return HogeFactory(); }) | copied;
↑に話題が出てるけど、図形を扱う際のクラスって構成するのがいいの? 直線、円、円弧、楕円、矩形、ペジェ 、、、 これらに存在する属性をすべて包括した、図形クラスをつくって派生させるの? クラス 図形 { 開始点,終了点、長辺半径、短辺半径、開始角度、終了角度、通過点、通過点数 仮想 描画する(描画先) }; クラス 直線 : 図形{ 上書 描画する(描画先)} クラス 円 : 図形{ 上書 描画する(描画先)} ・・・ 直線には関係ない、長辺半径等が含まれて無駄だと思うんですが・・・ どのような形がセオリーですか?
ちょっと図形に色々持たせ過ぎじゃね? 図形には本当に基本的なものだけで、あとは複数のサブクラスに共通的な属性を インターフェイスや中間的なクラスとしたり 纏めたものをひとつの属性として定義して保持じゃないのかな
>>870 そもそもなんのためにclass化したいんだよ。
普通classを利用する側の都合でclass化するんじゃないのか。
図形classを利用する側に開始点だの通過点だの派生でもたせりゃ十分で不要だろ。
×図形classを利用する側に開始点だの通過点だの派生でもたせりゃ十分で不要だろ。 ○開始点だの通過点だの派生でもたせりゃ十分で図形classには不要だろ。
クラス 図形 { 仮想 描画する(描画先) }; クラス 直線 : 図形 { 開始点,終了点 上書 描画する(描画先) }; クラス 円 : 図形 { 中心点,長辺半径、短辺半径 上書 描画する(描画先) }; クラス 円弧 : 図形 { 中心点,長辺半径、短辺半径、開始角度、終了角度 上書 描画する(描画先) }; こんな感じにして、図形の管理はベクタ<図形へのポインタ> 図形達で管理しています。 このベクタのある要素の開始点、終了点を変更しようとすると 直線へのポインタ あ = 動的キャスト<直線へのポインタ>(図形達[n]); あ が NULLじゃなかったら あ->開始点.X = 1; となりいちいち、キャストしなきゃいけない これってどうですか?
親classのpointerに子の所有権を持たせない。 子固有の操作がしたいなら、子の集合を別途管理しとけばいい。 std::list< Line > lines; std::list< Ellipse > ellipses; std::list< Paintable* > figures; lines.push_back( Line() ); figures.push_back( &lines.back() ); ellipses.push_back( Ellipses() ); figures.push_back( &ellipse.back() );
876 :
uy :2012/07/22(日) 23:53:31.26
相変わらずOOスレはかっわいそうなことになってんな
で、お前はソフトの1本でもリリースできたか? 早くこらのスレが黒歴史になってコテ付けて書き込んだことを絶対公言できないようになれよ
>>868 生ポインタをあつかう理由がまったくないのでそのファクトリー関数はshared_ptrを返すように書き換える
>>874 クラス 描画先
{
public:
描画する(直線);
描画する(円);
描画する(円弧);
描画する(図形)
{
assert(0);
}
};
クラス 直線 : 図形
{
上書 描画する(描画先)
{
描画先.描画する(this);
}
};
>>879 なんの解決にもなってないだろ
あとそういう描画にダブルディスパッチはやめたほうがいい
拡張性が下がる
要素と描画は完全に分離したほうがいいな。 数値はintとかdouble出あつかうとして、点のクラスが必要。 点の集合である基本線のクラス、それらを複数集合した図形クラス。 上記の操作や描画は、それらを利用して処理するようにしたほうがいい。
直線と円弧を考えると 直線には不要なメンバ(角度、中心点)がありますよね 直線と円弧の親クラスに角度、中心点もメンバとして入れるか否かを聞きたいです。
直接クラスを相互参照させたダブルディスパッチはやめれ せめて図形側を抽象化クラスにして単方向の参照にしたほうがいい あと、ダブルディスパッチするなら"描画する(図形)"は要らんだろ
>>880 LokiのCyclic Visitorのような物を使えば、拡張性は逆に上がるとおもうけど。
>>879 だと描画先だけど、オブジェクトに対する操作をストラテジパターン的に扱えるようになるし。
>>881 目的をBitmap限定にするならそれでもいいかもしれんが、
バックエンドをOpenGLやSVGみたいなベクターグラフィックにするならアウト。
SSEつかって描画したいってケースでも使えない。
単に描画指示情報と、レンダラーに分離したほうがまだ意味がある。
> クラス 直線 : 図形 横槍だがこの表現自体が気に入らん クラス ウィンドウ : 図形 とか作るのか? クラス ウィンドウ : 描画要素 クラス 直線 : 描画要素 でいいだろ。(実際にはPaintableみたいな名前) 図形は図形で境界管理とか位相管理とか別の継承ツリーになるはずだ。
位相管理?
>>886 struct line_mover : public visitor
{
void visit(直線)
{
直線.開始点.x = 1;
}
void visit(円){} // visitorで何もしないデフォルトの実装を用意してもよし
void visit(円弧){}
};
図形.accept(line_mover());
じゃ、だめなん?
+=か、Moveみたいな移動関数にベクターを与えられたら移動するとか 行列に合わせて拡大するとか。尤も厳密な位相調整はレンダラーの方でやるだろうから 相対的な大きさや位置の調整しかやる事ないだろうけど。
>>889 ダブルディスパッチ使ってるだけでさっきのと意味合いが全然変わってんじゃん
そもそも問題が具体的じゃないから解決策が定まらない。 まず、何と何に出力したいの?それから何と何から入力したいの? どういう加工をしたいの?そこをはっきりさせないと万能な解決策なんて無い。 だいたいOOをしたくてコードを書くんじゃなく、ある目的のソフトを書く上でOOを取り入れてるだけな筈だ。
派生クラスに存在する全ての属性を、親クラスに持たせますか? クラスAには属性aが存在するが、クラスBには不要な属性
俺の経験上、そういうのってクラス化が丸ごと間違ってた、 という場合が多々ある。 サブクラスのことを知っている親クラスなんて腐ってるし、 サブクラスのことを配慮した親クラスも結局足をひっぱる。 言ってる意味が分からないならそのままつっぱしればいい。 半年後に気付く。
Ruby ダックタイピング再考ですね わかります
Rubyは蛇足だろ ダックタイプできない言語のほうがむしろ少数派なんだから
>>885 なんでアウトかしらんが、全部分離しろ。
任意の方向のベクターに変換すれば。 描画に制限があるからって、データ側が描画側の都合にあわせてどうする。 点集合を描画に必要なデータに変換する機能を作ってそっちにまかせて抽象化しろ。
非現実的。妄想ならブログに書いてろ。
902 :
uy :2012/07/27(金) 02:29:56.69
まだクラスとか使ってるんだ
903 :
uy :2012/08/03(金) 12:55:23.92
ゲームでOO不要だなってやればやるほど実感する 結局ゲーム内オブジェクトって「物」じゃねーもん もっといえば「オブジェクト(種類付)」じゃないよ ゲーム内で使うオブジェクトっていうのは、 種類、区別のないオブジェクトだよ class Block ← はい、この時点で設計間違ってます class Node ← 正解 class Obj ← 正解 一は全で、全は一 の状態にさせないと、まともなゲームプログラムはかけない 確実にハードコーディングになる
uyちゃんゲーム語っちゃってるけど何本売れたの?
905 :
デフォルトの名無しさん :2012/08/04(土) 12:21:51.14
気持ち悪いから二度と話かけんな
ファイル、テクスチャ、フォント ゲームじゃ使わないのかもしれんが、これらはオブジェクトとして扱えたほうが良い。
907 :
uy :2012/08/05(日) 06:58:45.91
そういう根拠のないゴミ発言いらない ゲームで使わないものはない 使い方が違う
だから何本売れたんだよ
909 :
uy :2012/08/05(日) 19:55:37.38
コイツの中では 俺はいつの間にか商品としてのゲームを作っている話になっているらしい そもそもカテゴリー的にはゲームでも、ゲームとか作ってる気はない 作っているのは世界 俺が何のために、わざわざプログラミングで最強スキルを手にして ゲーム()ごときを作るには 勿体無いくらいの技術で開発しているかを分かっていない ああ、そうだな・・・ やっぱお前らはオブジェクト指向でいいよwwww
ドカタ
OO必要だろ。 オレはゲーム開発の仕事で15年以上食ってるけど必要。
ゲームどころかソフト1つ満足に作れない人間に付き合わなくてもいいのに
OOが必要といわれると引っ掛かる。 部分的には便利というレベルで 必ず必要というものでもない。
そいつぁ頭痛が痛いな。
915 :
uy :2012/08/06(月) 08:14:07.99
ゲームでOO不要論はそこら中にある ゲーム内で使うオブジェクトは本当は「物」ではないでFA チーム開発で足並みそろえる為にOOでやってるとかそんなのは知らない ただ本質的にはそうというだけ
まだ完成してねぇんだろ そろそろ自分の開発に戻れよw 480 : uy : 2012/05/07(月) 11:27:57.63 いやいい 俺はそろそろ自分の開発に入る 最近やけに初心者相手にソース2chにあげまくったりしていたのは少しプログラム離れていたから 感を取り戻す為にやっていた
917 :
uy :2012/08/07(火) 08:08:31.64
もうプログラムの作業は8割終わってる いまはプログラムから離れすぎて感覚を失わないようにム板を見ている
ノノノ ` 、 \ 俺が仕事も勉強も完成させないのは別にできないからじゃない。 ヾ, ;;) やりたくないわけでもない。もうプログラムの作業は8割終わってる。 ヾ,.;″ ;,;;) いまはプログラムから離れすぎて感覚を失わないようにム板を見ている ) こんなことって、 ー――-,, ,,,,-'" i) 世間のがさつで無神経な奴らには絶対に理解できないだろうし、 ____ ヾ / ___ i′ してほしくもない。 ヽ(;;;;)丿 '.(;;;)ノ i 人  ̄ i < > ─┼─ (.,,. .,,.) i ∨ ─┼─ ,i │ ,、____, i | | / .---‐ ,ノ _/ ヽ ヽ、 _ _ _ ,ノ
919 :
uy :2012/08/07(火) 14:34:53.08
うわキモ ていうかここ数日、全力でruby情報漁りまくってるが 情報追うのマジで疲れた こんな言語でも10年くらいの歴史はあるし、 そのログを漁っていくのは大変すぎ でも古参()に舐められるのウザいから覚えていく まだ実装側のソースコード解読にはほぼ着手してないし いくら俺様が1回見た情報は1度で記憶できるとは言っても、流石に厳しいものがある あ、ちゃんと2004年とか2008年ごろにruby-listを騒がしたカス共の情報もサルベージ出来てます
920 :
uy :2012/08/07(火) 14:40:44.80
つうかrubyって、上辺だけ知って扱うのが一番いいかもな かなりコアな部分になってくると、 そういうrubyの部分は積極的に使うべきではなく、 コアな部分に触れる事によって有益なものを作れたら コードを綺麗にまとめてアップするとかでいい気がしてきた 実装がゴミカスっていうんじゃないけれど 誰も戦わない場所で戦ってる感じ 完璧に扱いたい!→でも一生に一度使うか使わないかの機能ばっかりだ→rubyなんてやめてやる! 結局こうやってrubyアンチが増えていくのかもしれない 完璧主義者ほどrubyは扱えない
ようやく気が付いたか。モジュール化されたライブラリやDLL、クラスなんてのは中身を知らなくても 必要なことが出来るようになっていて、それを知ったり作ったりする手間を省くためのもの。 全部知る必要があるなら、CPUを作るためのシリコンの扱いから覚えろ。
922 :
uy :2012/08/07(火) 23:33:04.65
いってんのはそこじゃなく ライブラリではなくruby特有のノウハウについてだ rubyは奥が深いにも関わらず深部を解説してるサイトが個人ブログくらいしかないからルビリストに俺は正直rubyのコードで勝てないと思ってる 結局rubyコミュニティ入るか実装ソース読まないと2、3歩遅れたruby情報しか拾えない ruby情報ぐぐればぐぐるほど知らないことが未だにでてくる言語だよ 奥が深いってレベルじゃないバージョンアップしても何がどう変わったのかどこにも情報まとまってないからわかんねーしさ ちょっと各クラスのメソッド一覧を表示して一個一個ぐぐって使い方を調べていく作業は飽きたよ? 完全記憶能力は比喩的な表現であってその能力を維持するためにはそれなりのエネルギーを消費する
誰も必要としてないものの情報なんか数が少ないのは当然。 なくても困らないものは使わなくてもOK
uy年収いくら?
925 :
デフォルトの名無しさん :2012/08/08(水) 07:52:14.18
>>923 アスペか?
話通じなすぎて怖いわ
俺がいってんのはruby言語のマイナー構文やコア部分仕組みだよ
で、それを仕組み知っているルビリストと知らない一般ruby使いで
不思議rubyハックコードをかいた時に明らかに差がでる
アルゴリズム的な差というより
こんなクラスあったんだメソッドあったんだ構文あったんだみたいな知識的な差
そういう知識的な差を埋めるためにぐぐりまくってるけど
これからぐぐらなくちゃならない情報は4桁単位だよ?ルビリストはこれ全部覚えてるならマジでやばい
経験がそうさせるんだろうか
オンラインゲームを作りたいのでMVCに分けた設計をしたいのですがいいサンプルはないでしょうか
大雑把すぎるだろw
928 :
デフォルトの名無しさん :2012/08/08(水) 15:06:12.58
age
929 :
uy :2012/08/08(水) 19:36:14.12
rubyはよく出来た言語 感心するわ でもenumrable周りってまだなんかおかしいよね nextとnext_valuesってあるけど あれは結局 1種類のnilしかないからああなってんだよね 1種類のnilしかない弊害はハッシュ引数においても発生する 処理内部に外部からはみえないnilとrubyユーザーがみることができて扱えるnilが必要だと俺様はおもう キーワード引数でなんとかなるならいいんだけどな いまの仕様だとバグの元になるだけだからハッシュ引数にnilやfalseはやたらと渡せない
>>926 まずスタンドアロンでMVC試せよ
ネストしてるViewをどうやって操作するとか
考えにゃならんから最初から複雑なもん作ろうとしたら
後々大規模に直したくなって困るぞ
あまりおっきいモノのたいしてMVC当てはめようとするといびつになるかもな。 描画とイベントをくっつけて原始的にGUIつくろうってときはMVCで十分だけど。
932 :
デフォルトの名無しさん :2012/08/09(木) 08:32:17.14
言語はC#を考えていますが、Javaなどでも構いません。 数種類のエクセルシートを、数種類の帳票に変換して出力するというツールをどう組むか迷っています。 いずれのエクセルシートも、全ての種類の帳票に変換可能です。 仮にエクセルシートがA, B, Cと、帳票がD, E, Fとあるとしたら、 エクセルシート抽象クラス エクセルシートクラスA エクセルシートクラスB エクセルシートクラスC 帳票クラス抽象クラス 帳票クラスD 帳票クラスE 帳票クラスF という風にクラスをつくった後、 「.xlsファイルから値を読み取り、メンバ変数に格納していくメソッド」を抽象クラスに定義し、 エクセルシートクラスA, B, Cにオーバーライドして実装させる。 そして、帳票クラス抽象クラスに、 「エクセルシートクラスのインスタンスのメンバーを帳票クラスのインスタンスに代入していく」メソッドを定義し、 引数違い(エクセルシートクラスA, B, C)でオーバーロードさせておく。 そして、帳票クラスD, E, Fにその中身を実装させる。 という風なものを考えてみましたが、皆さんならどのように組まれますか?
ハッシュを使う
帳票って、Graphics2Dとか使って線引いたり文字列書いたりするのがメインでしょ? クラス階層不要と思うけどな。シートのほうも良く分からん。 読み込んだシートを数集類に判別した後、 それごとにデータをただ単に読んで、 データのラインナップを共有してんなら、 DataModelクラスでも使ってそいつを、 シート→モデル→帳票としてパラメータに使う。 帳票のほうは独自性がどうせ高くなるだろうから、 先に言ったように、クラス階層は意識させない。 データをチョコっと計算させたり、 独自のフォーマットに従わせたいような場合は、 データモデルの方をいじる。 帳票はそっからデータをもらって、あとは単に頑張って描画。 描画が複雑になるようならヘルパ用クラスを作って、 必要に応じて、各帳票クラスはそれをコンポジションとして使う。
>>935 Graphicsじゃなくて普通にテキストとして書き込むんじゃないの?
普通PDFじゃないの
>>935 GUIにはMVCアーキテクチャという発想があって、
今回のケースは対話(controler)がないからModel-Viewだけになる
で、
>>935 の話はModelとView(Graphics2Dなど)との関連を考察していて、
ModelとViewとの間にクラス継承関係は存在しないし、その内容も間違っていないと思う
ただし、
>>932 の相談はModel内部のクラス継承設計に関する事柄じゃないのかな?
で、それについては(
>>934 の言うように)
>>932 の考え方でいいと思う
両者は直交する視点からの考察であって、どちらも正しいし矛盾した議論ではない
>>932 自分ならVB-Reportを勧める。
自作で作るよりは結局安上がりになると思うから。
まっ設計のレスだから自作の話でいいとおもうけど。
OOの設計なら
>エクセルシート抽象クラス
>エクセルシートクラスA
教科書的な設計でいいと思う。
自分もこんな感じの抽象ー具象クラスで作っていた。
でも、最近は具象クラスのみで作っている。
OOらしくないけど、やっぱり処理やIFは一箇所に固めた方が理解しやすい。
その後に改修が入った時点で、継承をして機能変更するスタイルにしている。
940 :
932 :2012/08/09(木) 19:42:35.02
皆さんありがとうございました。
俺ならこの3種類の群に分けるな ・Excelクラス群 ・変換クラス群 ・帳票クラス群 抽象化クラスがExcelに一個、帳票に一個じゃ インターフェースとしての抽象化クラスが肥大しかねん。 帳票群のそれぞれに適した抽象化クラスを複数と Excelクラス群の抽象化クラスを複数定義し、 変換クラスによってそれぞれの抽象化クラスを つなぎ合わせる。 例えば、ある少数の帳票でしか使わないデータ書き込み手順があったとする。 その形式ためだけに、帳票の抽象化クラスにメンバーを追加したり Excel側に対応求めるってのは極力避けたい。 予め変換クラス群の抽象化クラスを経由してやりとりするようにしていれば 最低限の変換処理を記述した変換クラスを追加するだけで 新しい形式に対応できるようになる。
へぇー 頭のいい方は考えることが違うね
rubyのどうでもいい詳細仕様を知るのとOOPに何の関係があるんだ
945 :
uy :2012/08/10(金) 00:58:31.13
ooとか関係ないがしかしrubyの詳細仕様はどうでもよくない rubyはあらゆるものをインタプリタ上から拡張できる詳細をどれだけ知っているかで拡張できる範囲が変わる それによるとんでもないハック 知らない奴は知らない世界
Rubyって誰が使ってるの?
使わなくていいんじゃね おまえ等が効率悪くてもあまり俺に関係ないし
自分に関係ないものを排除出来るひとが仕事が出来るひと
ゴミグラマ乙
オブジェクト指向設計てどうやったらできるようになるんですかね
というのはユースケース図書いてもシーケンス図とかクラス図とか書くんですけど、実装になるとなんかつじつまというかそういうのが合わなくなって途中でダメになるんですよね
実装を先にやらないからだよ
953 :
uy :2012/08/10(金) 17:29:58.47
LLとかでさっと試作プログラムの作成→それみながら設計→本番プログラム
やべぇ uyに同意だ
955 :
uy :2012/08/15(水) 01:49:41.59
オブジェクト指向厨にききたいんだけど 本気でオブジェクト指向で書くとグローバル変数1個もなくなるよね? でも色んな場所で使う情報はグローバル変数に入れたほうがコーディング効率が良い オブジェクト指向的にグローバル変数って概念は有りなの?無しなの?特例なの?
Applicationなんちゃらというようなオブジェクトがグローバルに 参照可能になっていてset/get的なメソッドがあって、 メジャーなクラスライブラリのリファレンスを見て行くと グローバル変数的な何かを発見してしまうことしばしばw
可能な限り少ない方がいい ただしグローバル変数に直アクセス出来るならクソ Cであっても関数経由でのみアクセス出来るならいい
普通に書いてたらグローバル変数はでないような グローバル定数ならあるけど
OOのオブジェクトは構造化の関数と違い 機能にデータを渡すのではなく データに機能が付いている。 つまり、オブジェクトは変数と同等。 オブジェクトがどこからでも参照でき 更新に制約がなければ、そのオブジェクトはグローバル変数と変わらない。 オブジェクト=機能と取られる人が多いが OOの本質からするとオブジェクト=変数だと理解出来ている人が少ない。
960 :
uy :2012/08/15(水) 14:10:50.02
OOでグローバル変数はなしか またゲームの話になってしまうけど Player情報っていうか、 残機 、残ボム、 得点 、プレイヤー自身のオブジェクトのポインタ(Enemy_shotとかでプレイヤー座標が欲しい為) この4つくらいはどうしてもグローバル変数になっちゃうんだけど ここら辺だけが唯一ソースがまとまらない 一応ライブラリ内部のみでグローバル変数アクセスは行って、表面上は相対アクセスのように見せかけたりは出来るけど ゴミ箱に蓋をしたに過ぎないと思う
961 :
uy :2012/08/15(水) 14:11:49.32
>>959 データでも関数でもない単位を扱いたいから、
わざわざ抽象化してそれをオブジェクトと呼んだのでは?
しかも、インタフェースのデザインを考える場合、
実質的にはメソッド群とそれにつける名前を設計するわけで、
そう考えるとどっちかというとOOPでの設計の本質は、
「メソッド群+その命名」の設計だと思う。データというよりはね。
>>960 ゲーム管理クラスがそれぞれのオブジェクトを管理する。
シーンを木構造で考えるとどこに配置するのが良いか見えてくると思う。
システム-> メニュー
ゲーム -> プレイヤー情報
スコア
ステージ -> 自機
-> 背景
-> 敵
アーケードでSTG作ったときはCしか使えなかったのでCでツリー構造の処理系作ってこんな感じで処理してた。
まあ、いわゆるアレシステム。 弾とかアイテムは数が多いので1つのアレでまとめて管理
半角スペースだめだったっけかwww システム-> メニュー ゲーム -> プレイヤー情報 スコア ステージ -> 自機 -> 背景 -> 敵 C++ならそれぞれをオブジェクトにしてそれぞれの生成/破棄を管理する感じかね。
966 :
uy :2012/08/15(水) 15:14:00.17
>>965 一応、木構造だけど、
rubyの
class A
end
このclass Aの内部からアクセスできるのはグローバル変数だけなんだ
Cでいうところのグローバルstatic変数が欲しいけどそれは無い
システム-> メニュー
ゲーム ->
ステージ -> 自機( プレイヤー情報( スコア )
-> 背景
-> 敵
システム-> オブジェクトパターン ->
-> 自機
-> 自機ショット
-> 敵
-> 敵ショット( 誘導弾とかの作成の為に自機の情報へアクセスしたい )
-> エフェクト etc
設計はいまこんな感じで、いま自機のところに情報を詰め込んだ
この オブジェクトパターン 自体はライブラリにされていて
そこのパターンから選択してゲームを作る形
自機情報と、現在どのシーンを見ているか?っていう情報だけグローバル変数にポインタを持たせてる
967 :
959 :2012/08/15(水) 15:32:12.81
>>961 >そのグローバル変数をなくしたい
グローバル変数とローカル変数の違いは
・スコープ
・生存期間
これを管理すれば、ローカル変数と同等。
オブジェクトを指す”変数”のスコープや生存期間を制御すればいい。
>>962 >わざわざ抽象化してそれをオブジェクトと呼んだのでは?
抽象化はクラスレベルで定義。オブジェクトでは具象化されている。
>実質的にはメソッド群とそれにつける名前を設計するわけで、
メソッドは手段であって目的はフィールド(変数)の操作。
「○○○をXXXする」○○○の主語がフィールドで、XXXの動詞がメソッド。
メソッドの存在しないオブジェクトはありえるが
フィールドがないオブジェクトは関数ライブラリと同じ。
968 :
uy :2012/08/15(水) 16:02:40.83
>オブジェクトを指す”変数”のスコープや生存期間を制御すればいい。 シーン自体に初期化や、解放の為のコードは書きたくない 俺様のはOOとしてみたらクズ設計だと分かった オブジェクトの動作パターンはシーン以下の階層には置かないことは決定してて そこからステージ内の変数にアクセスって事は、アレか 初期化のための セッター & げったー か グローバル変数と大差ない もういいや
969 :
uy :2012/08/15(水) 16:03:45.96
あ、これセッターゲッターでいいわ いける
ぶっちゃけRubyはなにがどうなってるのかまったく知らないのでアドバイスはできんが C++ならファクトリー関数をクラスに持たせてやることでカプセル化が強固になる。 クラス内での生成はしたくないということだが、必要なときに必要なものだけ生成するようにしないと 全部のリソースオンメモリなゲームになる。STG程度ならまあいまのPCなら余裕ではあるが。
971 :
uy :2012/08/16(木) 04:12:01.50
>>970 グローバル変数が出来る事は別によかったんだ
rubyはモジュール、クラスのスコープが複雑だから、そこにさらにMix-inの関係も複雑になる場合だと
メンバ変数、クラス変数がどこまでスコープ聞いてるか俺でも分からなくなるので
思い切ってグローバル変数にした方が圧倒的にマシ
どこにその変数作るかとか、そのグローバル変数の初期化場所で悩んでただけかもしれない
クラスは使ってないけどカプセル化については、完璧すぎるくらいに出来てる
いやクラスは1個だけ使ってるんだけどね
シーンも含めゲーム中のオブジェクトの全てを生成するクラスが根にあって
そのクラスでオブジェクトを生成してから、lambdaで実装を書くような感じだから
メンバ変数やクラス変数もないし、基本的にローカル変数しか必要としないので最強
,:::-、 __ ,,r::::::::::::〈:::::::::) ィ::::::ヽ 〃::::::::::::;r‐''´:::::::::::::::::::::ヽ::ノ ,'::;'::::::::::::::/:::::::::::::::::::::::::::::::::::: l::::::::::::::::::l::::::::::●::::::::::::::●:::::ji |::::::::::::::::::、::::::::::::::( _●_)::::::,j:l クマー! }::::::::::::::::::::ゝ、::::::::::|∪|_ノ::;! . {::::::::::::::::::::::::::::`='=::ヽノ:::::/ ';::::::::::::ト、::::::::::::::i^i::::::::::::/ `ー--' ヽ:::::::::::l l;;;;::::ノ 【ラッキーレス】 このレスを見た人はコピペでもいいので 10分以内に3つのスレへ貼り付けてください。 そうすれば14日後好きな人から告白されるわ宝くじは当たるわ 出世しまくるわ体の悪い所全部治るわでえらい事です
973 :
uy :2012/08/17(金) 00:15:40.80
,:::-、 __ ,,r::::::::::::〈:::::::::) ィ::::::ヽ 〃::::::::::::;r‐''´:::::::::::::::::::::ヽ::ノ ,'::;'::::::::::::::/:::::::::::::::::::::::::::::::::::: l::::::::::::::::::l::::::::::●::::::::::::::●:::::ji |::::::::::::::::::、::::::::::::::( _●_)::::::,j:l クマー! }::::::::::::::::::::ゝ、::::::::::|∪|_ノ::;! . {::::::::::::::::::::::::::::`='=::ヽノ:::::/ ';::::::::::::ト、::::::::::::::i^i::::::::::::/ `ー--' ヽ:::::::::::l l;;;;::::ノ 【ラッキーレス】 このレスを見た人はコピペでもいいので 10分以内に3つのスレへ貼り付けてください。 そうすれば14日後好きな人から告白されるわ宝くじは当たるわ 出世しまくるわ体の悪い所全部治るわでえらい事です
974 :
uY :2012/08/18(土) 03:43:22.24
OO厨に意見もらったおかげで設計は完璧になった 最高の気分です
975 :
uY :2012/08/21(火) 20:43:54.16
無理だと思うけど質問してみる Windowsにあるようなウィンドウをプログラム内で作りたいんだけど 一応WinAPIにならってウィンドウオブジェクトにメッセージを飛ばす形で作ってる アクティブウィンドウと非アクティブウィンドウってあるけど、 非アクティブウィンドウをクリックした際のメッセージを送るタイミングってどうするべき? 非アクティブ状態ではメッセージをウィンドウは受け取らず、 "アクティブにする"というメッセージを送ってからアクティブにさせてから クリック判定されたとかのメッセージを送るか そもそも非アクティブ状態でもメッセージを送信するようにしておいて ウィンドウ側で、自身が非アクティブな場合は不必要なメッセージをスルーするようにするか Windowsのウィンドウのカスタマイズ性を考えると 後者の実装のような気がしなくもないけど、アクティブ非アクティブ関係なく全ウィンドウに常にメッセージ送信してるのってどうなんだろう
そんなもんOOP的にどうかじゃなくてお前がどう使いたいのかで決めることだろ >ウィンドウのカスタマイズ性を考えると とか >どうなんだろう とか そんなもんお前がどうカスタマイズしたいのか、メッセージをどんな風に扱いたいのかに依るだろう
977 :
uY :2012/08/21(火) 21:42:36.82
Windowsのウィンドウシステムのフルスクラッチをしたいんだよ 何でもいいから実装方法かいてよ 作ったことないプログラムは無理ですか? >アクティブ非アクティブ関係なく全ウィンドウに常にメッセージ送信 これは普通に作ったら、実行速度に影響する だから「非アクティブでもメッセージを受け取る or 受け取らない」 っていうようなフラグが必要になってしまうようなカス設計しか今は思いつかないから相談しにきたんだけど?
そんなもん速度に全く影響しないだろ ウィンドウ何個作る気だよ
979 :
uY :2012/08/21(火) 22:09:29.58
>>978 OS設計として考えて欲しい
ウィンドウ( ウィンドウオブジェクトとして扱うと楽になるオブジェクト ) は
OSの中ではめちゃめちゃ数が多い
軽く100,200は想定すべき
980 :
uY :2012/08/21(火) 22:14:11.82
そんでメッセージっていうのは マウスクリックだけじゃなくてマウスオーバーや マウスがクリックされていないというメッセージも必要なんだよ あるいは、キーマウスだけじゃなく、ウィンドウ制御用のメッセージもおそらく後から必要になる 俺はひとつ"W_WIN_CHANGE" みたいなメッセージ作った これはウィンドウのアクティブ、非アクティブが切り替わった時に発行するメッセージ 少なくとも、アクティブになった、非アクティブになった、ウィンドウが生成された、ウィンドウが重なった 今思いつくだけでもこれだけのメッセージは最低限必要になり、 キーマウスイベントなどが発生するたびに飛ばす事になる
どうせゲーム用のUIを独自で作ろうなんて考えてるんだろう。 そんなくらいでコストって言ってたら、WM_NCHITTESTの発行回数みて発狂しそうだな。
>>975 >そもそも非アクティブ状態でもメッセージを送信するようにしておいて
>ウィンドウ側で、自身が非アクティブな場合は不必要なメッセージをスルーするようにするか
MSのWindowsはこれだね。だから
>これは普通に作ったら、実行速度に影響する
一応この方式でも問題ないと思うけど。
OO的に考えると、アクティブか非アクティブかはメッセージ送信側が考えるじゃなく
受け取る側(オブジェクト)が考える方がOO的だけど
OSならある程度レスポンスを考慮してもいいと思う。
ゲーム程度なら、独自にアクティブ化、非アクティブ化をするのは自身か管理クラスだろうから アクティブリストに載せたりはずしたりすればいいだけだと思うが。 shared_ptrとweak_ptrを使えば容易にそのようなリストを無制限に作れる。
最近はOSはウィンドウ(便宜上そう扱うんじゃなくて本当の意味のウィンドウ)だけ管理して その中はゲームみたいにアプリケーションごとに箱庭でやるのが流行りだよね
そもそも既存のウィンドウアプリケーションにおいて ウィンドウシステムによってもアプリによっても非アクティブ時の挙動の標準が異なる 例えばWindowsは非アクティブ時、クリックを受け付けるのが標準で MacOSXは非アクティブ時、クリックはアクティブ化のみってのが標準だが どちらもそうでない実装をしてるアプリはあるしな
986 :
uy :2012/08/22(水) 05:36:18.57
>>981 ,983
ゲームで使う気はまだない
ただ仕組みをそのまま作りたいだけ
>>982 参考になるわ
Cでかけば問題ないんだろけど
rubyだから速度はかなり気にしながら書かないといけない
>>984 ほう
>>985 そこら辺が謎なんだよな
アプリによってウィンドウの挙動を変えられるようにしてるってことは
マジでソースがフラグや設定項目だらけになりそう
Spy++で実際にどんなメッセージがどんだけ流れてるか見て発狂したらいいと思うよ
15年前の段階でも多すぎてspy++のフィルタリングじゃどれがどれだかさっぱりなので 態々自前のより細かく条件指定できるメッセージロガー作るのを強いられるぐらい凄い
989 :
uy :2012/08/22(水) 11:09:35.63
そんなゴミカス設計にしたくないは
990 :
uy :2012/08/22(水) 11:16:07.76
Windowsをウィンドウメッセージを考えてたら自信が出てきた 余裕でこんなもの以上の作れるな
uyには無理
uyには無理っていいな 流行ってるの?
993 :
uY :2012/08/22(水) 14:26:45.78
趣味の中の趣味で作るだけ ゲームを作るのに飽きたら1日だけ脱線して作業する為のSubプロジェクト
Spy++で流れてるメッセージの量見て発狂するなんて どんだけ脳味噌小さいんだ
話の流れ読んでから書こうぜ 実行速度の話だぜ
作りたいと思ってるのに何で人に訊くんだ? 馬鹿なの?
997 :
デフォルトの名無しさん :2012/08/23(木) 01:49:50.64
日本語
998 :
デフォルトの名無しさん :2012/08/23(木) 05:18:25.10
999 :
デフォルトの名無しさん :2012/08/23(木) 05:19:13.55
1000 :
デフォルトの名無しさん :2012/08/23(木) 05:29:10.26
__ r:...、 /::::::} _{::-::> ´ ̄ ̄` 、 く::::/ \ . 〉′{ / ハ }∧ ヽ ハ きょろーん { i ∨ノ }-ノ \ノハi } | | | ● ● 〈从リ | | ⊂⊃ 、_,、_, ⊂} | } i⌒ヽ、 (_.ノ ノ八__/⌒) i ヽ ヽ>-´-r彡; | :::ヽ/. / /∧__,ヘ}:ヽ }::/l| |',:::ハ\ . / / ヾ_:::ッリ:ヘ_{::| .| |<''´i ヽ / / / 人 | ::::V:: .| ノ| } } } { { { | .|∨`冗´ノ |ノノ ノ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。