Out of Memory

ごめん、忘れてた。

目次

Blog 利用状況

ニュース

2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

aetos

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

Microsoft MVP for Windows SDK July 2007 - February 2008, Microsoft MVP for Visual C++ February 2008 - June 2009
Microsoft MVP for Windows SDK
July 2007 - February 2008
Microsoft MVP for Visual C++
February 2008 - June 2009

アクセサリ

あわせて読みたい

e-Words

アフィリエイト

記事カテゴリ

書庫

日記カテゴリ

車なんて…っ!

思わずこんなタイトルをつけてしまったが、車ではなくてオブジェクト指向のお話。

車はガソリンがなければ動きません(ディーゼル他、非ガソリン車はとりあえず置いといて)。最近高いですね、ガソリン。
ご存知のように、ガソリンにはレギュラーと廃屋ハイオクがあります。
レギュラー用のエンジンにハイオクを入れても大丈夫ですが、ハイオク用のエンジンにレギュラーを入れると壊れてしまいます。

面倒なのでコードは載せません。各々補完してください。

車クラスとガソリンクラスがあります。
車クラスには、ガソリンのインスタンスを引数に取る給油メソッドがあります。
車クラスから、ハイオク専用車クラスを派生させます。
このハイオク専用車クラスの給油メソッドの引数は、多くの言語ではガソリンになりますが、実際にはガソリンから派生したハイオクガソリンを渡さないと壊れてしまいます。

I車インターフェイスではなく車クラスから派生させるのは、レギュラー用エンジンを積んでいる車には(悪質なものでない限り)どんなガソリンを入れても大丈夫だからです。この点において、レギュラー車はハイオク車より抽象的です。
ハイオク専用車も車の一種には違いなく、ハイオクガソリンもガソリンの一種には違いないのに、車とガソリンに結合が関係があるとき、これらを継承関係にするとうまく行きません。

よくある「ペンギンは鳥か?」論によれば、いくつかの結論のパターンがあります。
たとえば、

  1. 現実世界がどうであれ、このプログラム中では、どんなガソリンでも給油できるものを車と定義したのだから、ハイオク専用車はその意味では車ではなく、車クラスから派生させることは不適当である
  2. ハイオク専用車の給油メソッドでは、実際に給油されたガソリンの動的な型を判別して、ハイオクガソリンでなければ例外を投げればよい。

というような。

1は、「ペンギンは鳥か?」論でもそうですが、常識的に考えて「そんな馬鹿な」と言いたくなります。
まして、ペンギンと鳥は実際にも姿形も生態も大きく異なるのに対し、今回の例では、より違いが少ないだけになおさらです。
2は現実的な解かもしれません。しかし、極論を言ってしまえば、型のエラーをコンパイル時に検出できないなんて、静的型システムに何の意味があるというのでしょうか?
もちろん、完璧主義に走るべきではなく、完全に検出できないからと言って全く役に立たないわけではないという意見は一理あります。
しかし、完璧を求めてうまく行く方法があるとしたら、それを求めないのは罪というものです。

さて、お題です。
このような状況下でも、静的な型チェックを機能させる方法はあるのでしょうか?

  • こういう仕様の新しい言語を作ればうまく解決できる
  • 既存の言語にこういう拡張を施せばうまく解決できる
  • 実は拡張しなくても既存の言語でうまく解決できる
  • そもそも問題設定に無理があって、どうやっても解決は無理、または不要
  • だから動的言語を使えっつってんだろ

既成概念に囚われない答えを募集します。

投稿日時 : 2008年7月9日 13:56

Feedback

# re: 車なんて…っ! 2008/07/09 14:20 長月葵

 ハイオクガソリンクラスにしかないメソッドを呼べばコンパイルエラーじゃないかしら?
 と思ったけどそういうメソッドがないときどうしたものか。

# re: 車なんて…っ! 2008/07/09 14:38 2リットル

むずかしいから、分ける。
給油機能を車から分離してI給油インターフェースにする。

# re: 車なんて…っ! 2008/07/09 14:58 なにかと黒い龍

給油できたほうがいいですね。給油という行為で壊れるのではなくハイオクに最適化された箇所(添加時期、オクタン価、過給圧、その他クリアランス等々)で不具合が発生するので。

# re: 車なんて…っ! 2008/07/09 16:11 よねけん

給油メソッドをジェネリックメソッドにすればよくないですか?
ガソリンクラスを継承したクラスに制約した引数を取るようにすれば、ハイオク車はハイオクガソリンしか入れられません。

#でも、燃料補充メソッドと燃料クラスにして、
#軽油や電気にも対応せねば。

# re: 車なんて…っ! 2008/07/09 16:58 シャノン

> そういうメソッドがないときどうしたものか。

どうしようか。

> 給油機能を車から分離してI給油インターフェースにする。

そうすると、ハイオク車にレギュラーを入れようとしたことをコンパイル時に検出できる?

> 給油できたほうがいいですね。

間違いは早期に見つかった方がいいです。走り始めてから壊れるよりは、給油しようとした段階でエラーになって欲しい。

> 給油メソッドをジェネリックメソッドにすればよくないですか?

その場合、車クラスの給油メソッドの宣言はどうなりますか?

# re: 車なんて…っ! 2008/07/09 17:35 なかむら

メソッドではなく、車クラスをジェネリックにするのはどうですか?

public class 車<T> : where T : Iガソリン
{
public void 給油(T 燃料)
{
// いろいろやる
}
}

ハイオク車なら T にハイオクを指定すればいいかと。




# re: 車なんて…っ! 2008/07/09 17:55 biac

> 給油しようとした段階でエラーになって欲しい。

ノズル径が違うので、エラーになります (w
# え? 現実はお呼びでない? f(^^;;;


現実は、ハイオク車にレギュラーを入れたら必ず壊れる …というもんではありません。 壊れるやつもいるでしょうけど、 ノッキング検出してリタードするようにマジメにプログラミングしてあるやつもいます。
壊れるやつにしても、ハイオク:レギュラー比が 50:50 くらいまでは大丈夫、 だとかあったりして。

なので。
Class ガソリン{
  オクタン価 _オクタン価;
  分量 _分量;
}
みたいなのをタンクに入れて、 残ってたガソリンと足し合わせて、 でもって、 実際に走らせてみないと、 壊れるかどうかは判定できません。

ということで、 ビジネスロジックの中でロジックとしてエラー判定すべき問題で、 コンパイル時エラーにしてはいけないと思います。

サービス (商品) A があって、 その派生サービス A' があって。
A は大人でも子供でも申し込み可能だけど、 A' は大人だけが OK。
んじゃ、 子供オブジェクトが A' に渡されるのは、 コンパイル時エラーにすべきか?
…同様な問題のつもりで書いてみました。 f(^^;

コンパイルエラーにしてると、 営業から 「子供が申し込んできたら、親に連絡して契約を取りに行くようにしたい」 とか言われた瞬間に、 破綻しませんか?

# re: 車なんて…っ! 2008/07/09 18:44 長月葵

 あれ? 車とかガソリンとかはたとえであってお題は

 クラスAがクラスBを受けとる関数を持っていて、クラスAの派生クラスA'ではクラスBではなくクラスBの派生クラスB'を受け取りたい。しかし言語仕様上オーバーライドで引数が変更できないときいかにして静的型チェックするか?

 なのですよね?

# re: 車なんて…っ! 2008/07/10 1:22 よねけん

> > 給油メソッドをジェネリックメソッドにすればよくないですか?
>
> その場合、車クラスの給油メソッドの宣言はどうなりますか?

#なんか私、言葉の選択を間違えたような
私の言いたかった方法は、まさになかむらさんのコードです(^^;

# re: 車なんて…っ! 2008/07/10 1:27 yayadon

給油メソッドは,
ガソリンスタンドオブジェクトが実装するので,
車オブジェクトが実装する地点で間違え。

# re: 車なんて…っ! 2008/07/10 9:55 シャノン

> メソッドではなく、車クラスをジェネリックにするのはどうですか?

設問では、「レギュラー車」と「車」を分けて定義していません。
この場合ですと、車ジェネリッククラスとレギュラー車クラスを分けることになってしまうかと。

> # え? 現実はお呼びでない? f(^^;;;

うん、ごめんねw

> クラスAがクラスBを受けとる関数を持っていて、クラスAの派生クラスA'ではクラスBではなくクラスBの派生クラスB'を受け取りたい。しかし言語仕様上オーバーライドで引数が変更できないときいかにして静的型チェックするか?

ですです。

> 車オブジェクトが実装する地点で間違え。

だとして、どうやって車の中にある残油量プロパティを増やすのでしょう?

# 8月には190円台?出光、ガソリン4・4円値上げ 2008/07/11 19:20 Newsブログ検索結果BLOG

 出光興産は11日、7月後半出荷分のガソリンなど石油製品の卸値を同月前半に比べ1リットルあたり4・4円値上げすると発表した。原油価格高騰に伴い調達コストが増加したためで、7月全体の上げ幅は11・7円となる。月単位で卸値を見直す新日本石油やジャパンエナジーも、現状の原油価格が続けば8月卸値を前月比7?8円値上げする方針。卸値の引き上げで、ガソリン価格の上昇圧力が一段と強まりそうだ。 ニューヨーク原油...

# re: 車なんて…っ! 2008/07/11 23:50 あるふ

この場合、どのガソリンをいれるかを"選んだ"人、もしくはその責任のある人が
エラーを出すべきと思いますよ。
給油自体は成功しないとまずいと思います

クラスは状態を持ち、クラスの正当性は状態に依存し、状態は動的に変化するので、
静的チェックだけでは基本うまくいかないです

# re: 車なんて…っ! 2008/07/24 15:54 長月葵

 亀レスですが。
 type_traitsとstatic_asertでコンパイル時型チェックとかどうかと。
 思ったんですがtype_traitsもstatic_asertもまだ標準じゃないとか固有のメソッド~と同じでガソリン側に用意がないとどうにもならない問題が解決できず。しょぼーん

タイトル  
名前  
Url
コメント