東方算程譚

Oriental Code Talk ── επιστημηが与太をこく、弾幕とは無縁のシロモノ。

目次

Blog 利用状況

ニュース

著作とお薦めの品々は

著作とお薦めの品々は
東方熱帯林へ。

あわせて読みたい

わんくま

  1. 東京勉強会#2
    C++/CLI カクテル・レシピ
  2. 東京勉強会#3
    template vs. generics
  3. 大阪勉強会#6
    C++むかしばなし
  4. 東京勉強会#7
    C++むかしばなし
  5. 東京勉強会#8
    STL/CLRによるGeneric Programming
  6. TechEd 2007 @YOKOHAMA
    C++・C++/CLI・C# 適材適所
  7. 東京勉強会#14
    Making of BOF
  8. 東京勉強会#15
    状態遷移
  9. 名古屋勉強会#2
    WinUnit - お気楽お手軽UnitTest

CodeZine

  1. Cで実現する「ぷちオブジェクト指向」
  2. CUnitによるテスト駆動開発
  3. SQLiteで組み込みDB体験(2007年版)
  4. C++/CLIによるCライブラリの.NET化
  5. C# 1.1からC# 3.0まで~言語仕様の進化
  6. BoostでC++0xのライブラリ「TR1」を先取りしよう (1)
  7. BoostでC++0xのライブラリ「TR1」を先取りしよう (2)
  8. BoostでC++0xのライブラリ「TR1」を先取りしよう (3)
  9. BoostでC++0xのライブラリ「TR1」を先取りしよう (4)
  10. BoostでC++0xのライブラリ「TR1」を先取りしよう (5)
  11. C/C++に対応した、もうひとつのUnitTestFramework ─ WinUnit
  12. SQLiteで"おこづかいちょう"
  13. STL/CLRツアーガイド
  14. マージ・ソート : 巨大データのソート法
  15. ヒープソートのアルゴリズム
  16. C++0xの新機能「ラムダ式」を次期Visual Studioでいち早く試す
  17. .NETでマンデルブロ集合を描く
  18. .NETでマンデルブロ集合を描く(後日談)
  19. C++/CLI : とある文字列の相互変換(コンバージョン)
  20. インテルTBBによる選択ソートの高速化
  21. インテルTBB3.0 によるパイプライン処理
  22. Visual C++ 2010に追加されたSTLアルゴリズム
  23. Visual C++ 2010に追加されたSTLコンテナ「forward_list」
  24. shared_ptrによるObserverパターンの実装
  25. .NETでマンデルブロ集合を描く(番外編) ── OpenCLで超並列コンピューティング
  26. StateパターンでCSVを読む
  27. 状態遷移表からStateパターンを自動生成する
  28. 「ソートも、サーチも、あるんだよ」~標準C++ライブラリにみるアルゴリズムの面白さ
  29. インテルTBBの同期メカニズム
  30. なぜsetを使っちゃいけないの?
  31. WPFアプリケーションで腕試し ~C++でもWPFアプリを
  32. C++11 : スレッド・ライブラリひとめぐり
  33. Google製のC++ Unit Test Framework「Google Test」を使ってみる
  34. メールでデータベースを更新するココロミ
  35. Visitorパターンで遊んでみたよ
  36. Collection 2題:「WPFにバインドできる辞書」と「重複を許す検索set」
  37. Visual C++ 2012:stateless-lambdaとSQLiteのぷち拡張
  38. 「Visual C++ Compiler November 2012 CTP」で追加された6つの新機能

@IT

  1. Vista時代のVisual C++の流儀(前編)Vista到来。既存C/C++資産の.NET化を始めよう!
  2. Vista時代のVisual C++の流儀(中編)MFCから.NETへの実践的移行計画
  3. Vista時代のVisual C++の流儀(後編) STL/CLRによるDocument/Viewアーキテクチャ
  4. C++開発者のための単体テスト入門 第1回 C++開発者の皆さん。テスト、ちゃんとしていますか?
  5. C++開発者のための単体テスト入門 第2回 C++アプリケーションの効率的なテスト手法(CppUnit編)
  6. C++開発者のための単体テスト入門 第3回 C++アプリケーションの効率的なテスト手法(NUnit編)

AWARDS


Microsoft MVP
for Visual Developer - Visual C++


Wankuma MVP
for いぢわる C++


Nyantora MVP
for こくまろ中国茶

Xbox

Links

記事カテゴリ

書庫

日記カテゴリ

interfaceに物申す

interfaceね。その名の通りインタフェイスのみを宣言したもの。
C++でいえば純粋仮想関数(pure-virtual-function)のみで構成されたクラス(みたいなの)。

たとえば:

interface I商品 {
  int 売値();
}

JavaにしろC#/VBにしろ、interfaceに記述するメソッド(あるいはプロパティ)は
すべてpublic扱いとなります。
interfaceなんだからそれに対して"何ができるか"は
公開すんのがアタリマエだろ常考ってリクツでしょう。

けどね、隠したいメソッド/プロパティもあるんじゃないかしら。
たとえば、商品の原価は売り手にとっては重要だけど
買い手や競合他社には見せたくないよね。
だから願わくはinterfaceに書くメソッド/プロパティには公開限定子を指定できて
ほしいのね。 ↓こんな具合に。

interface I商品 {
  public int 売値();
  private int 原価();
}

隠しておきたいけど必要なメソッド/プロパティをどうやって表現するんだろう。
# C++ならprivateなpure-virtual-functionが許されるのにのに

この疑問はその昔JavaでObservable/Observer使ったときに感じたものです。
Observer.update はObservable側で発した変更通知を受けたときに(のみ)反応すべきもの。
だからこいつは勝手に呼んでもらっちゃ困ります。隠しておきたいはずです。
なのにpublicにならざるを得ないのです。

投稿日時 : 2009年1月6日 12:10

コメントを追加

# re: interfaceに物申す 2009/01/06 12:35 読者

interfaceはあくまでサブタイプの階層を表すためのものですからね。
それがやりたかったらサブクラスの階層を表すabstract class使え、ということでしょうね。
あと、Observable/Observerはそういった意味では本来のinterfaceの使い方からは少しずれているのかもしれません(更に言うと、引数がObjectなので使い辛い)。
たしかEiffelという言語は公開先を限定できたはずなので、そういう言語の表現能力に頼るのもいいかもしれません。
例えばJavaで公開先を限定したい場合は、interface自体をpackage privateにするだとか、何かのclassのprivate/protected/package privateなstatic interfaceにしてしまうとかが現実的ですかね。

# re: interfaceに物申す 2009/01/06 12:42 よこけん

はじめまして。


interface が「原価を private で定義しろ」と命ずることに何か意味があるのでしょうか?
private ということは、結局、実装クラスの内部でしか扱えないわけですし、
売値を算出するのに原価が必要ならば、実装クラスでは自ずと原価を用意することになるはずです。


> この疑問はその昔JavaでObservable/Observer使ったときに感じたものです。
> Observer.update はObservable側で発した変更通知を受けたときに(のみ)反応べきもの。
> だからこいつは勝手に呼んでもらっちゃ困ります。隠しておきたいはずです。
> なのにpublicにならざるを得ないのです。

private にしたら Observable からも使えなくなりませんか?

コンパイラで防ぐことはできませんが、
(C# の場合) 明示的なインターフェイス実装をすれば、
"Observer の" Update メソッドという意味を強めることができますね。

# re: interfaceに物申す 2009/01/06 12:44 επιστημη

> サブクラスの階層を表すabstract class使え、ということでしょうね。

真っ先にそれ考えたです。
とたんに単一継承の呪縛に絡めとられますた orz

# re: interfaceに物申す 2009/01/06 12:46 επιστημη

> private にしたら Observable からも使えなくなりませんか?

C++ならfriendで特定のクラス/メソッドに限定公開できますもん。

privateを許す"だけ"では使いものにならんでしょう。
だから 「作るヒトには公開/使うヒトには隠蔽」 ってゆー
カラクリもコミでサポートしてホスイってことです。

# re: interfaceに物申す 2009/01/06 13:06 επιστημη

あー...

interface I商品 {
 int 売値();
}

interface I売りもん : I商品 {
 int 原価();
}

とかやっといて、商店は I売りもん をもってるけど、
お客さんには I商品 として見せろ。

ってーことかしら。
なんか直接的じゃないんだよなー...

八百屋さんはりんごを I売りもん として扱います。

class りんご : I売りもん {
 Color 色() { ... }
}

お客さんには値段しか書かれていない真っ黒な袋に入った
I商品として見せろって?
じょーだんじゃない、お客は りんご が欲しいんだ。

# re: interfaceに物申す 2009/01/06 13:17 よこけん

C++ は (ほぼ) 未経験なのですが、僕も friend はたまに欲しくなります。
一応、C# ならこんな感じで Update を隠蔽することもできますね
# 割に合わない気がしますが…w

public class Hoge
{
 public Hoge()
 {
   // Observable に ObserverImpl のインスタンスを登録
 };

 private void Update(Observable o, object arg)
 {
   // 処理
 }

 private class ObserverImpl : IObserver
 {
   public ObserverImpl(Hoge parent)
   {
     this._parent = parent;
   }

   private Hoge _parent;

   public void Update(Observable o, object arg)
   {
     this._parent.Update(o, arg);
   }
 }
}

# re: interfaceに物申す 2009/01/06 13:22 επιστημη

↑んー...割に合わない感バリバリ ^^;

オブジェクト指向ってばアタマん中にあるアイデア
を素直に表現できるって利点がある思うの。
それが台無しになっちゃうよねぇ...

# re: interfaceに物申す 2009/01/06 13:49 菊池

>だからこいつは勝手に呼んでもらっちゃ困ります。隠しておきたいはずです。
>なのにpublicにならざるを得ないのです。

メソッド単位では無理ですけど、interface全体についてはinternalに規制する事は出来ますよね。

internal interface IHoge_internal
{
アセンブリ内に限定公開
}

public interface IHoge
{
アセンブリ外まで公開
}


部分的にしか使えないインターフェースは悪い設計の予兆なので「interface内ではメソッドに個別設定できません」は言語設計としては好きな感じです。

同一アセンブリに信用ならざるプログラマのコードが入るってなると弱いかもですけど、それは信用ならざるプログラマを何とかしていただきたいと思ったりして。

# re: interfaceに物申す 2009/01/06 13:55 επιστημη

> internalに規制する事は出来ますよね。

んー...これが使えるシチュエーションも少なくないけど
アセンブリ内限定だとライブラリとして提供できんくなるですぅ。

# re: interfaceに物申す 2009/01/06 15:41 凪瀬

private int 原価();
っていうメソッドがあったとして、それを呼ぶ人は誰?ってのが根底にはありますよね。
privateがアクセスできるのはそのinterface自身だけで、interfaceには実装がないのだから呼べる人が誰もいないのでナンセンス。

このあたり既存のアクセス修飾子による制御では限界が来ているというのが共通認識で、
Java7ではJSR 294のSuperpackageという概念で対応しようとしています。
http://journal.mycom.co.jp/articles/2007/05/13/superpackage/

# re: interfaceに物申す 2009/01/06 15:59 επιστημη

> それを呼ぶ人は誰?

うん、それを指定する手立てがない限りナンセンスです。
C++では friend class 売り手; とか指定できるんだけども。

> Superpackage

ほほー。

# re: interfaceに物申す 2009/01/06 16:56 まさる

たまたま今さっき見つけたんですが、
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?AccessModifier
ここの「published」みたいな感じでしょうか?

# re: interfaceに物申す 2009/01/06 17:12 επιστημη

> published

たぶん僕の言わんとするところのものかとは思う。
いかんせん肝心のリンク先:
「IEEEソフトウェアのコラム(PDF)」
が辿れない...あ、コレ↓か。読んでみよ。
http://martinfowler.com/ieeeSoftware/published.pdf

# re: interfaceに物申す 2009/01/06 20:04 akiramei

>C++ならfriendで特定のクラス/メソッドに限定公開できますもん。

interfaceをinternalにして
[assembly : InternalsVisibleTo("公開相手(DLL)")]
のようにInternalsVisibleTo属性を使うのは駄目ですか?

公開相手にしたアセンブリからはinternalへのアクセスを許可出来ます。

http://d.hatena.ne.jp/akiramei/20061105/p1
↑その昔書いた記事。

# re: interfaceに物申す 2009/01/06 20:06 yama

C++ですが、私はここ数年はinterface的なものを書くときはもっぱらNVI(non-virtual interface,ユーザーに対するインターフェースはpublic非仮想・仮想関数は非publicにする)なんですが、C#だとNVIにできないんですよね。

# re: interfaceに物申す 2009/01/06 21:47 まつあに

お久しぶりです。

面白いお話ですねえ。まったく仰るとおりです。

「C++の進化」(D&Eでなくてね)に、
多重継承を導入する・しないが議論された時、
C++にinterfaceを導入してはどうかという論文が掲載されていたと思いますが、
あれはアクセス修飾子についてはどういう提案だったかなあ・・・。

明日にでも久々に(10年ぶり以上?)読み返してみよっと。

# re: interfaceに物申す 2009/01/07 9:01 επιστημη

そかそか、NVIのイメージはかなり近いす。
「interfaceが"使い方"と"作り方"の二つを同じく扱うのが気に入らん」てのが僕の主張。

"使い方"は当然公開するんだけども
"作り方"は隠すのが吉ぢゃねぇかと。

interfaceではなんもかんもpublicなのがヤです。

# re: interfaceに物申す 2009/01/07 13:29 aetos

> オブジェクト指向ってばアタマん中にあるアイデア
> を素直に表現できるって利点がある思うの。
> それが台無しになっちゃうよねぇ...

プログラムを組む際に、分析、設計、実装みたいな段階を踏むとして。
分析段階で出てくるクラス、設計段階で出てくるクラス、実装段階で出てくるクラスというのがあるんじゃないかと思います。
そういうのが出てくるべきでない、クラスの粒度は上から下まで一貫しているべきだということでしょうか?

# re: interfaceに物申す 2009/01/07 13:50 επιστημη

んなつもりはありませんです。

言語のもつ縛りのために
アイデア(what)とコード(how)間のギャップが拡がる
のは好ましくないよねーってことで。

# ホントにアクセス修飾子? 2009/01/09 1:54 C#と諸々

途中までしか追ってないけどinterfaceに物申すinterfaceに物申す(2)売値やら原価なんてのは青果店や問屋が勝手にりんごに貼った値札のようなもの。...

# re: interfaceに物申す 2009/01/09 13:21 επιστημη

↑あらら、fc2にコメントできねぇ...なのでここで。

例えとして適切ではなかったかもです。
とはいえ同様のシチュエーションはままあるこっちゃないでしょか。

# re: interfaceに物申す 2009/01/10 2:00 よこけん

あれ、コメントできませんでしたか。なんでだろ…失礼しました。

> 例えとして適切ではなかったかもです。
はい、「客に原価を見せたくない」というのは、
「原価がいくらなのか (値) を知られたくない」(インスタンスの話)であって
「原価という概念が存在する事実を知られたくない」(型の話)ではないんですよね。
なので Observer / Observable の話の方がしっくりきました。

タイトル  
名前  
URL
コメント