かたちづくり

つれづれに、だらだらと、おきらくに

キツネと公務員

イソップ物語ずるい狐 という話がある。公務員批判の議論を見聞きしているうちに、このお話を連想するようになった。
2匹のネコがご馳走の取り合いをしているところにキツネがやってきて、こう提案する。僕がきっちり半分に分けてあげよう、と。しかし秤で計ってみると片方がわずかに重い。バランスをとるためにキツネが重い方を齧ると、今度はもう片方が重くなる。これを繰り返して、結局キツネが全部平らげてしまうという話である。

このお話の要諦は、平等にはコストが掛かる、ということだと思っている。

キツネは必要なのだ。キツネが居なければネコの喧嘩は避けられない。ネコにも喧嘩の強弱はあろう。百戦錬磨の野良猫を前にしたら飼い猫などひとたまりもない。あるいは、片方が徒党を組んでご馳走を奪おうとするかもしれない。これでは殺伐とした弱肉強食の世界ではないか。屈強なモヒカン男が闊歩するヒャッハーな世界を理想に掲げる人はいるまい。もちろん実力に応じて獲得する果実に多寡があってもよいのだが、行き過ぎた格差は社会を荒んだものにするだろう。富を再分配する安定化装置としてキツネはやはり必要である。

問題は、キツネはどの程度までネコのご馳走を食べてもいいのか、ということ。イソップ物語ではキツネは全部を平らげてしまっている。これはさすがにズルイ。ではキツネの取り分は50%としたらどうか。多い?では30%?それとも20%?どの程度が妥当なの?

公務員の問題とは、要するに私達の社会はキツネの取り分を何%に設定しますか、という問なのだろうか。うーん、難しい。キツネの取り分を減らしたら、そのぶんだけ社会は平等ではなくなるのだろうか。つまり格差社会になるのだろうか。キツネの取り分を減らすのならば、ある程度の格差の増大は許容しなくてはならないのだろうか。ではどの程度の格差までなら許容して良いのだろうか。

僕にはサッパリ分からないよ。

Yield の意味

C# で yield return に出会ったとき、まず最初に理解の妨げとなったのは yield という単語の意味だった。

当時の僕にとって、yield といえばそれは「降伏する」という意味だった。その理由は僕が工学部機械科出身で材料力学を習ってきたことと関係がある。材料力学には「降伏応力」という概念があって、これは英語で yield stress というのである。

そんなわけで、yield return を知ったときは大いに戸惑った。降伏する、ではサッパリ意味が通じないではないか。当然、辞書を引くことになる。

  1. 〔農産物や鉱物が〕産出する
  2. 〔努力や投資によって〕収益が出る、利益が挙がる
  3. 〔戦いなどで相手に〕降伏する、屈服する
http://eow.alc.co.jp/yield/UTF-8/?ref=sa

辞書を引いても、ストンと腑に落ちる訳は見つからない。強いて言えば「産出する」だろうか。yield return とは産出したものを return することだ、と考えられなくもない。しかしいくらなんでも、日本語の「産出する」という語感とどうしてもイメージが合わない。結局スッキリせぬまま「まあ yield とはそういうもんだ、プログラムが書ければそれでよし」と今まで過ごしてきた。

すると先日、会社の同僚が「yield の意味、英英辞書で調べてみたらスッキリですよ」などとのたまう。ほうほうなるほど、と思い調べてみたらこんな意味が見つかった。

  1. to produce a result, answer, or piece of information:
http://www.ldoceonline.com/dictionary/yield_1

直訳すれば「結果とか答えとか情報とかを生み出すこと」。なるほど、これぞまさに yield return にドンピシャの意味ではないか。やはり英単語の意味がスッキリと腑に落ちないときは英英辞書を引くことが大事なようだ。

不便のデザイン

ふと突然、「不便さ」こそデザインされるべきだ、などという思考に頭が支配される。そんな今日の昼下がり。

紙の本は不便だ。検索できない。ハイパーリンクもない。でも、だからこそ目の前の文章に集中できる。活字の世界に入り込むことが出来る。小説に没頭することが出来る。

心をシングルタスクにすることができる。

電子書籍のデザインはどうあるべきか。問題は紙のような物理的な制約がないことだ。どこまでも機能が追加できてしまう。どこまでも便利を追求できてしまう。しかし、それは良いデザインといえるのか。
検索機能をつければ、その検索機能は画面の面積を占めるだけではない。読者の心にも入り込む。「検索する」という選択肢が入り込む。もちろんそれは便利だ。だが時として、集中の邪魔となる。読書体験の質を下げる。

温泉が好きだ。都会の喧騒を離れ、お金を使ってわざわざ不便な田舎の温泉宿まで足を運ぶ。不便だからこそ、いいのだ。以前行った温泉宿はお二人様限定で、部屋にはテレビも時計もなかった。あの外界からシャットアウトされた感じは最高に贅沢だった。(また行きたいけど、もう子供がいるので無理・・・)

便利は安売りされている。便利は安く手に入る時代になった。でも多分「デザインされた不便」は安くならないんじゃないか。
コンセプトがないと「不便」は作れないんだと思う。コンセプトがないと、どんどん便利になっちゃうんだと思う。今はそうやって便利が世の中に溢れて、便利が供給過剰になって、便利が大安売りになっているんだと思う。

マクドナルドがWi-Fi接続を提供するのと反対に、高級レストランは電波をシャットアウトしたら面白いんじゃないか。どこでもメールが読めちゃう時代だからこそ、電波から隔絶された空間というのは希少価値を持ちうるような気がするのだけれど。

Freezable と Binding の関係がよく分からない

XAMLにうまく埋め込めるクラスを定義しようとしていて、Freezable が色々と謎。
例えば Hoge クラスとか Piyo クラスとか作って、下記のようなXAMLインスタンス生成が出来るようにしたいとする。

<Hoge>
  <Hoge.Piyo>
    <Piyo Buzz={Binding Path=...}/>
  </Hoge.Piyo>
</Hoge>

まず最初は {Binding Path=...} がうまく機能しなくて悩んだ。
とりあえず、Hoge や Piyo を FrameworkElement または FrameworkContentElement の派生クラスにすればうまく動くことが分かった。ああそりゃそうか、と腑に落ちるものがあった。ミソは、FrameworkElement や FrameworkContentElement には論理ツリーの親子関係を保持する機能が備わっていることだろう。Binding のためには親要素の DataContext プロパティが継承される必要があるわけで、プロパティを継承するためには親要素へのリンクを保持していなければいけない、というのは道理である。あるいは Binding.Source として ElementName を設定する場合なら、要素名で element が検索可能な論理ツリーに組み込まれていなければいけない、これも道理である。上記XAMLの場合は、Hoge オブジェクトに Piyo オブジェクトを AddLogicalChild() すれば論理ツリーに組み込むことが出来る。ふむふむ、なるほどね。
しかしだ、場合によっちゃ FrameworkElement やら FrameworkContentElement を継承するのはあんまり好ましくない。これらにはマウスやキーボードのイベントなども定義されているけど、コントロールとしてウィンドウに表示するものでなければこれらのイベントは不要だからだ。
そこで調べてみると、どうやら代わりに Freezable クラスを継承すれば良いらしいと分かった。例えば Brush クラスなどは Freezable の派生として定義されているようだ。試してみると確かに Binding が動作している。結果には満足だが、しかし理屈が分からない。Freezable は論理ツリーに組み込まれるわけでもないのに、何故 Binding が出来るのだろう?XAMLパーサーが何かやっているの?そもそも「フリーズ可能」であることと Binding 可能であることは何か関係があるの?

更に一歩進んで、次のように Piyo がコレクションになっている場合も実現したいとする。

<Hoge>
  <Hoge.PiyoCollection>
    <Piyo Buzz={Binding Path=...}/>
    <Piyo Buzz={Binding Path=...}/>
    <Piyo Buzz={Binding Path=...}/>
    ...
  </Hoge.PiyoCollection>
</Hoge>

試行錯誤してみて分かったこと。

  • PiyoCollection は FreezableCollection でなければいけない。
  • PiyoCollection は(read-onlyの)DependencyProperty でなければいけない。

この2点を守れば Binding は正しく動くことを確かめた。結果には満足だが、やはり道理が分からない。道理が分からぬものは何処かに落とし穴がありそうで怖い。

どーなってんの?

多品種小ロットな世界

世の中は多品種小ロットに進んでいく傾向らしい。仮に究極的に多品種小ロットに突き進んだ世界を想像してみると、そこはどんな世界になるんだろう。
多品種小ロットということは、市場は小さく分断されるんだろう。市場の粒度が小さくなるんだろう。国や世界の経済を入れ物だとすると、その入れ物からは大きくゴツゴツした岩が減って、代わりに小さな小石や砂粒で埋め尽くされることになるんだろう。経済はサラサラと砂のように流動的になって大きな屋台骨のような構造が見えにくくなるんだろう。構造力学では経済が見えなくなって、流体力学で経済を見なくてはならなくなるんだろう。
グローバル化する一方で、逆に個々の市場は小さくなるんだろう。「ローカル」の概念が物理的・地理的制約から解放されて、生活スタイルや趣味や嗜好で区切られたセグメントに市場が局所化するんだろう。「内輪(うちわ)」という言葉が指す概念は物理的・地理的な制約から独立し、また血縁関係や組織からも独立するのだろう。
多品種小ロットの製品やサービスは、少人数の組織によって生み出されることになるんだろう。一つの製品やサービスに今までのような巨額な投資が行われることは少なくなるのだろう。高度で細分化された専門家による分業体制よりも、上流工程から下流工程まで幅広い能力を備えた人が活躍するようになるのだろう。
つまり人々は会社にコミットするのではなく、職能や専門分野にコミットするのでもなく、携わっている製品やサービスにコミットする働き方になるのだろう。名刺の肩書きには製品名やサービス名を書くようになるだろう。仕事は何かと問われたときに、会社名を答えるのではなく、専門を答えるのでもなく、製品やサービスを説明することになるのだろう。
こういった社会では、従来とは異なる「効率化」が求められるだろう。従来のような生産ラインで分業するような効率化ではなく、セル生産方式のように一人で多くのことをこなせるようにするための効率化が求められるだろう。そこではプラットフォームの概念が大きな役割を果たすだろう。
プラットフォームの構築には大きな投資が必要だろう。経済は幾つかの大きなプラットフォームと、その上で生み出される無数の製品やサービスで構成されることになるだろう。製品開発と違って、プラットフォームの構築には高度で細分化された専門家による分業・協業が必要不可欠となるだろう。


・・・ここまで書いてきたことは、かなり極端な世界。現実はここまで極端ではないと思う。けれど、色々と聞きかじった偉い人のビジョンを自分なりにつなぎ合わせてみると、傾向としてはこういう方向に向かっているような気がする。あってる?

[WPF/MVVM] INotifyPropertyChanged の実装がメンドイので

みなさん、あけましておめでとうございます。

WPFとMVVMに向きあう今日この頃。表題の件、ちょっと考えて次のように書けるようにしてみた。

class MyViewModel : ViewModelBase // 事前に用意したベースクラスを継承
{
  public int Hoge
  {
    get { return base.Properties.Get<int>(); }
    set { base.Properties.Set( value ); }  // PropertyChanged イベントが発行される
  }
}

既に多くの偉大なる先人たちが取り組んでいる古典的な問題っぽいので今更感はありそうだけど、ともかく恥を偲んで紹介してみよう。晒してこそ勉強になるはず。

良いと思うところ。

  • get も set も実装は1行で済んでいる。
  • プロパティ用のフィールド(int _hoge; とか)の宣言が不要。
  • プロパティ名の文字列を使用していない。

イマイチなところ、気になるところ。

  • ベースクラスの継承を強要する方式はやっぱりイマイチかな・・・。
  • プロパティ名の文字列が省略できるカラクリは、StackTrace で呼び出し元を取得することで実現している。とりあえず動いたけど、ギミックがトリッキー過ぎる気がするし、なんか落とし穴はないのかな、この方式。ちょっと不安。
  • パフォーマンスは悪いかも・・・。

では順に説明してみる。ViewModelBase は次のように定義した。

public class ViewModelBase : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  protected void RaisePropertyChanged( string name ) { ... }

  protected readonly PropertyContainer Properties;

  public ViewModelBase()
  {
    this.Properties = new PropertyContainer(
      name => this.RaisePropertyChanged( name ) );
  }
}

見ての通り INotifyPropertyChanged の実装部分に新しいところはなく、後半で宣言している PropertyContainer というクラスがキモとなる。このクラスは、コンストラクタ引数で PropertyChanged イベントを発行する Action を受け取るように定義している。

public class PropertyContainer
{
  readonly Action<string> _notifyPropertyChanged;

  public PropertyContainer( Action<string> notifyPropertyChanged )
  {
    _notifyPropertyChanged = notifyPropertyChanged;
  }
  ...
}

次が PropertyContainer の核心部分となる。

public class PropertyContainer
{
  ...

  // プロパティの名前と値を Dictionary で管理
  readonly Dictionary<string, object> _properties = new Dictionary<string, object>();

  // ディクショナリから値を検索して返す  
  public T Get<T>( string name )
  {
    object x = null;
    return _properties.TryGetValue( name, out x ) ? (T)x : default( T );
  }

  // ディクショナリに値をセットしてイベントを発行
  public bool Set<T>( string name, T value )
  {
    T curr = this.Get<T>( name );
    if ( !object.Equals( curr, value ) ) {
      _properties[name] = value;
      _notifyPropertyChanged( name );
      return true;
    }
    return false;
  }

  ...
}

さらに Get/Set をラップして、プロパティ名を StackTrace から取得するようにする。これによりプロパティ名を文字列で明示的に指定する必要がなくなる。

using System.Diagnostics;

public class PropertyContainer
{
  ...

  public T Get<T>()
  {
    try {
      var name = new StackTrace().GetFrame( 1 ).GetMethod().Name;
      return name.StartsWith( "get_" ) ?
        this.Get<T>( name.Substring( 4 ) ) : default( T );
    }
    catch { return default( T ); }
  }

  public bool Set<T>( T value )
  {
    try {
      var name = new StackTrace().GetFrame( 1 ).GetMethod().Name;
      return name.StartsWith( "set_" ) ?
        this.Set<T>( name.Substring( 4 ), value ) : false;
    }
    catch { return false; }
  }
}

ここがヤバイよーとか、もっといい方法あるよーとか、あったら教えて~。

ソースコードとピーターの法則

世の中にはスパゲッティなソースコードが多い。これも一種のピーターの法則かもしれない。

ピーターの法則とは何故世の中には無能な奴が多いのかを説明する法則だ。ある人がある職能で優秀と認められたとする。その人はきっと昇進するだろう。昇進後の職能でも優秀と認められれば、きっとその次の階層に昇進するだろう。こうして昇進を続け、あるときその人に向いていない職能にぶつかり、そこで無能と判定され、昇進が止まる。つまりその人は自分に向いていない職能に留まり続けることになる。こうして世の中は無能な人材で埋め尽くされるというわけだ。

これをソースコードに当てはめてみよう。ソースコードが綺麗に書かれていれば、機能追加においてベネフィットがコストを上回る可能性が高い。従ってソースコードが綺麗であるかぎり機能追加は続くだろう。しかしいつかはソースコードが乱れ、機能追加に限界が来て、進化が止まる。逆にいえばソースコードが汚くなるまで、メンテナンスが限界に達するまで、機能は追加され続けるということ。こうして世の中はスパゲッティなコードで埋め尽くされる、という仮説。

この仮説に従えば、ソフトウェア技術の進化はスパゲッティコードの減少に寄与しないことになる。オブジェクト指向言語が開発され、関数型言語が台頭し、優れたフレームワークが登場しても、その技術の範囲で限界に達するまで機能は追加され続け、スパゲッティになって開発が止まる。新技術は問題を先送りするだけで、世の中からスパゲッティコードを無くしたり減らしたりすることが出来るわけではない。

もちろんこの仮説は決して、他社との競争に勝つためにより先進的な言語や技術を採用しようという選択を否定するものではない。スパゲッティ化の問題を他社より先送りできれば、それだけ競争に勝つ可能性も高まる。ただ、その先進的な技術を元に開発されたシステムもいつかはスパゲッティ状態に達するだろうという仮説にすぎない。

・・・あくまで仮説ですよ?与太話ですよ?一つの思考実験として面白いかな、という程度です。

ではでは、皆さん良いお年を。