2015年11月30日月曜日

CoffeeScriptのススメ

CoffeeScript は、シンプルな記述でJavaScriptのコードを生成するための一種のコンパイラです。
これにより、冗長な記述や誤りが入り込みやすい部分を、よりシンプルに記述することが可能になります。
そのCoffeeScriptでクラスを記述してみたいと思いますが、その前にライブラリをインストールします。
ここでは、Node.jsを既にインストール済みであることを前提とします。

$ npm install -g coffee-script

グローバル・オプションでインストールしました。これでCoffeeScriptのインストールは完了です。
コンパイルのコマンドは以下のようになります。

$ coffee -c hoge.js.coffee

CoffeeScriptによって記述された hoge.js.coffee をコンパイルすることにより、hoge.js が生成されます。
この流れが基本です。

JavaScriptにはクラスという考え方が存在せず、prototypeというクラスに似た考え方を利用して、あたかもクラスを実装しているように見せかけていますが、CoffeeScriptでは、classキーワードを使用してクラス定義を記述できます。

# TVクラスを定義
class Television
  # チャンネルプロパティを定義します。
  ch: '7'

  # 引数としてnameを受け取り初期化をするコンストラクタを定義します。
  constructor: (@name) ->

  # メソッド watach を定義
  watach: ->
    alert "#{@name}で#{@ch}を視聴中 ..."
    return

# Usage;
tv = new Television 'television'
tv.watch()


var Television, tv;
Television = (function() {
  Television.prototype.ch = '7';

  function Television(name) {
    this.name = name;
  }
  Television.prototype.watch = function() {
    alert("" + this.name + "で、ch " + this.ch + "を視聴中 ...");
  };
  return Dog;
})();

tv = new Television('4Kテレビ');
tv.watch();

結果は ...
「4Kテレビで、ch 7を視聴中 ...」


CoffeeScriptの @は、thisとほぼ同じ意味でインスタンス・プロパティへの参照です。
また、()なども省略可能で、インデントにより表します。このあたりは、Rubyや、Python、または、Jadeに似た感覚です。

2015年11月14日土曜日

DockerでGUIアプリケーションを動かしてみる

高性能なIDEなどを構築するのはとても手間な作業だと思います。
この実験がひとつの発火点になれば、より合理的に仕事ができるようになるかもしれません。

まず、以下のような Dockerfile を用意します。

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y firefox
RUN export uid=1000 gid=1000 && \
    mkdir -p /home/developer && \
    echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
    echo "developer:x:${uid}:" >> /etc/group && \
    echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
    chmod 0440 /etc/sudoers.d/developer && \
    chown ${uid}:${gid} -R /home/developer

USER developer
ENV HOME /home/developer
CMD /usr/bin/firefox

そして、イメージを作成します。
ビルドにはしばらく時間がかかります。

$ docker build -t kenny/gui-docker .

次に run します。

$ docker run -ti --rm \
       -e DISPLAY=$DISPLAY \
       -v /tmp/.X11-unix:/tmp/.X11-unix \
       gui-docker

すると Firefox が起動します。























たったこれだけの実験なのですが、ひとつ可能性の地平が拡がりました。




2015年11月11日水曜日

Docker ver. 1.9 を発表

米Docker が現地時間(11月3日)にバージョン1.9を発表しました。
大きなポイントとして、マルチネットワーキングへの対応と永続的ストレージ関連の強化あたりでしょうか。

ひとつめは、コンテナの配備に関係なく仮想ネットワークと紐付けてコンテナの通信を完全に制御できるという点です。複数のホストにまたがって仮想ネットワークが構築できるようになります。
つまり、仮想ネットワークで抽象化され、どのホストでコンテナを実行するのか、という事実を隠蔽します。今回は安定板という位置づけなので本番環境での利用も可能です。

つづいて永続化ストレージに関して
1.9ではボリュームシステムが完全に再設計されたようです。データボリュームは複数コンテナで共有できるようになります。また、Swarmとの連携で、たとえばクラスタ全体での永続化を管理できるようになります。

その Docker Swarm ですが、今リリースから ver1.0 に到達し正式版になります。
コンテナで構成したクラスタのスケールが自動的に管理されるようになります。

オーケストレーションの Docker Compose は、ver. 1.5 になりました。
今回からWindowsのサポートも加わりました。
Swarm上でComposeのアプリケーションを複数のホストにまたがってデプロイすることが可能になります。

以上、Docker 1.9 のバージョンアップの要点をまとめました。

2015年11月9日月曜日

MongoDBをDokcerに隔離してマニュアル操作する

まずは、MongoDBのコンテナを作成します。

$ docker pull mongo

Latestは3.2です。
早いです。
11月5日に MongoDB Blog でアナウンスされたばかりです。3系の最新版ということになります。
軽く主な変更点に触れておこうと思います。

1)注目はストレージエンジンです。負荷状況に応じた最適化の選択肢の設定を行いやすくなった点です。これにより複数のストレージ稼働でのスケールがより柔軟になり運用の負担を軽減します。
2)ドキュメントバリデーションも強化されました。
3)インデックス作成時にフィルタをかけることによりメモリ容量を節約する。
4)BIコネクタ (BI Connector) が導入されました。

主なところをリストしてみました。
BIコネクタの導入は簡易なBI分析に向けて、ビッグデータ的な大がかりではないようなちょっとしたことがいろいろ可能になるような夢を感じますね。

では、pullしたmongoDBコンテナを起動します。

$ docker run --name mongo-sampler -d mongo:latest

さて、起動したら念のため ps で確認してみてください。
クライアントを起動してMongoDBを扱いたいわけですが、ホスト側のローカル環境にはMongoのコマンドは存在しません。
そのために、クライアントの役割を演じるコンテナをひとつ起動します。

$ docker run -it --link mongo-sampler:mongo --rm mongo sh -c 'exec mongo "$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/sample-db"'

MongoDBの操作が終わればクライアントのコンテナは必要なくなるので -rm でオプションを設定して、これからログインするコンテナを抜けると同時に終了するように設定します。
--link で既に起動してある MongoDB のコンテナに接続します。
sh -c でシェルスクリプト経由で、$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT のコマンドを実行します。内容は、Dockerで自動的に生成される環境変数でMongoDBのIPアドレスとポート番号を参照するようにします。
最後の sample-db は MongoDB に作成するデータベースです。

先のDockerコマンドを実行するとMongoDBのコンテナにログインするので、作成されたデータベースを使ってみます。

> use sample-db
switched to db sample-mongo

データを投入します。

> db.records.insert({_id:1,title:"MongoDBへテストレコードを投入する。",number:100})
WriteResult({ "nInserted" : 1 })
> db.record s.insert({_id:2,title:"続いてレコードをもう1件投入します。",number:101})
WriteResult({ "nInserted" : 1 })

検索します。

> db.record s.find()
{ "_id" : 1, "title" : "MongoDBへテストレコードを投入する。 ", "number" : 100 }
{ "_id" : 2, "title" : "続いてレコードをもう1件投入します。 ", "number" : 101 }

更新します。

> db.books.update({ _id:2 }, { $set : { title: "上書きします。" } })

確認します。

> db.record s.find()
{ "_id" : 1, "title" : "MongoDBへテストレコードを投入する。 ", "number" : 100 }
{ "_id" : 2, "title" : "上書きします。 ", "number" : 101 }

削除します。

> db.books.drop()
true
> db.record s.find()
>
> exit
bye

そしてプロセスを抜けたので、クライアントのコンテナは消滅しました。
NoSQLを実感してください。

2015年11月3日火曜日

Cloud9 で Rails を動作させてみる

ローカル環境でアプリケーションを構築して、gitにコミットしてクラウドにデプロイという流れとは別にクラウド上でアプリケーションを構築して、gitにpushしたり、任意のクラウドにデプロイという開発の流れもあります。
いちばんのメリットは個々の環境に開発環境を作らなくても済むという点です。
つまりブラウザさえあればモノが作れてしまうというわけです。

そういうわけで、今回は Cloud9 という開発用のクラウドサービスを試してみようと思います。

まずは、どんな機能を持っているのか? をまとめます。

1)開発に関連する環境がすでに揃っている(ruby, php, node.js, java C++ ...)
2)フレームワークもインストール済みなので、そのまま使用できる(Rails, httpd など)
3)Ubuntu環境なので、ターミナル操作をそのまま実行可能
4)データベースも用意されている(MySQL, Postgres, Redis, MongoDB など)
5)サンプルやデモとして簡単にアプリケーションをインターネットに公開できる
6)メンバーとのリアルタイム編集
7)エディタ環境は、Vim, Emacs, Sublime から好みのものを選択できる
8)Chrome, Firefox, safari など、クロスブラウザチェックが可能

次に、無料の範囲でどこまでスペックを活用できるのか? もついでにまとめます。

1)1GBのディスク容量
2)512Mのメモリ
3)ひとつまでのプライベート環境インスタンス

さて、Cloud9のアカウントを作成するか、GitHub、Bitbucketのアカウントがあれば、そのままログインできます。























ログインしたら、まずはワークスペースを作成しますが、Workspace name の入力欄に任意の名前をつけて入力します。この部分がのちほどURLのドメインの部分に付与されます。
Workspece Privacyは、公開したければ public で設定します。

今回は、Ruby on Rails のプラットホームでアプリケーションを構築してみようと思います。
プラットホームのアイコンから Ruby on Rails を選択して Createボタンを押して、しばらく待ちます。
すると IDEが起動します。
左のペインにワークスペースのディレクトリツリーが、右ペイン上部には選択したファイル、下部にターミナルが表示されています。Visual Studio や eclipse を使い慣れた方ならば直観的に操作できると思います。

まずは、左のペインのワークスペースのディレクトリツリーから Gemfile を開きます。
とくに今回は編集しませんが、gem 'sqlite3' という部分があります。データベースは、そのままsqlite3でいこうと思います。

さて、さっそくbashターミナルでコマンドを実行します。
右側のペイン下部です。

$ bundle update
$ bundle install

必要なgemパッケージをインストール完了しました。
つづいて、Scaffoldでテンプレートを作成します。

$ rails generate scaffold User name:string email:string
      invoke  active_record
      create    db/migrate/20151103062340_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      invoke  resource_route
       route    resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/show.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.html.erb
      invoke    test_unit
      create      test/controllers/users_controller_test.rb
      invoke    helper
      create      app/helpers/users_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/users/index.json.jbuilder
      create      app/views/users/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/users.coffee
      invoke    scss
      create      app/assets/stylesheets/users.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss

そしてマイグレーションです。

$ bundle exec rake db:migrate
== 20151103062340 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0023s
== 20151103062340 CreateUsers: migrated (0.0025s) =============================

これで完了です。
実行の Run ボタンを押すと、クラウド上でアプリケーションが構築されます。データベースは c9 インスタンスが生成されます。
ブラウザで、https://ワークスペース名-ユーザ名.c9.io/users にアクセスすると、おなじみのRailsのチュートリアル画面を生成します。



















個々のPCに開発環境を作るのは、意外と大変です。
たとえば、vagrantなどで合理化しても、それなりに学習コストがかかりますが、今回の Cloud9 であれば、直観的にプラットホームを作成して、コーディングに専念できるという点がアドバンテージだと思います。
興味のある方は、ぜひ試してみてください。

2015年10月28日水曜日

続・コメント

自身が以前、ある開発者組織の研修を経験したときに、おもしろい経験をしたので参考までに紹介したいと思う。
それはコメントに関する指針についてのレクチャだった。まず、例題としてごく簡単なクラスをひとつだけ実装して、その内容に応じたコメントを記述したもらった。
対象はヘッダからはじまって、コンストラクタ、フィールド、パブリックアクセサ、パブリックメソッド、プライベートメソッド、プロクテッドメソッド、そして デストラクタ。
奇妙なことに判を押したようにそれらのコメント群の記述、粒度、文言は一致していた。そのときの生徒数はおよそ15名。この程度の人数だと思うかもしれないが、この統制のとれたコメントのノーテーションには、非常にびっくりした記憶がある。驚いたというのは、とても優秀な成績だったということではなく、この奇妙な統制についてだ。
ある意味、これだけの人数のチームで、これだけの統一感があるというのは、とても望ましいことだと思う。しかし、自身が思ったのはまったく違った。
実際的なコメントを読むと、自身の水準に照らし合わせれば、悪くはないが合格点はあげられない出来だった。

何が問題なのか?

一般的にコメントは適度な粒度が必要だ。シンプルに、かつ、必要にして充分な情報を提供できなくてはならない。もちろんこれは本質ではあるが、一朝一夕で記述できるほど甘くはない。
まず、考えなくてはならないのは、文脈に即した情報を網羅できているのか? つまり、構造のコンテキストに応じた言葉の選択や論理で貫かれているだろうか? というのが第1のポイント。
2つ目に、よく考えてほしいのは、果たしてこのコメントを読んで3週間後の自分は理解できるだろうか? 半年後の自分は理解できるだろうか? そして未だ見ぬ未来の実装者は、ここから必要な情報を得られるだろうか?
読めばわかる、という考え方は実は閉ざされた地平でしか通用しないある種の文明なのだ。共通基盤と一定水準の知識があってはじめて成立する、いわば方言、地方言語でしかない。
コメントはローカルであってはならない。参考までに、プロプライエタリ系の言語世界では、よくローカルな方言に陥りがちだ。もちろん、これは経験的に感じた傾向ではある。

翻ってオープンソースの世界はまた違った側面を持っている。誰に強制されるわけでもなく、コメント文化は成熟しているのが常だ。もちろんすべてのソースコードがそういうわけではないが、傾向としてグローバルな文化が根付ているように見える。これは、コメントという小さな視点だけではなく、実装やプロジェクトの運営方針に対して極めて規範的な空気感が常に流れているからではないだろうか? と思うことが多い。
自らを律する。この地平で初めて他人のための仕事も成熟を遂げるのではないかと考えている。

2015年10月26日月曜日

ダメなコメント

「予約情報をチェックする」

というコメントがあったとする。

メソッドを見ると

CheckResavationData() : bool

とある。
メソッド名を見れば予約の情報をチェックしているのだろう、という察しがつくし、その結果を論理型で返すのだろうな・・・

という見当もつく。
それで? 結局、このメソッドは何をするのか? そしてどんな結果を返すのか? は不明だ。

予約情報の有無を調べているのか?
または、妥当性をチェックしているのか?
依然として不明だ。何より文脈がわからないのでどのように扱えばよいのかという点で理解はできない。

問題は、メソッド名の直訳的な説明しかコメントからは読み取れない。それ以上の情報は得られないのだ。
このメソッドを含むクラスはブラックボックス化されていて中の実装は気にしないでよい、ということを示唆しているわけだが、これでは上位の呼び出し側からはどんな論理を記述すればよいのかわからない。
世の中にはこういうコメントやメソッドが溢れている。

これは英語圏の表現からはかなり遠い(何しろ Far East なわけだし・・・)ところに本拠を置く我々の致命的な弱点なのかもしれない。では、仮に日本語でメソッド名を付けましょう、という運動でも展開すれば、この手の問題は解決するのだろうか?

2015年10月21日水曜日

expressでHTMLを直接扱う

今回も Node.js における expressフレームワーク の小ネタを。
一般的には、あるいは、モダンにHTMLを構築してレスポンスを返すという点では、既にこのフレームワーク は充分に洗練された機能を持っていると思います。
それは、たとえば、JadeのHTMLコンバータだったり ejsのテンプレートエンジンだったりするわけです。 しかし、これらの機能を使いこなすには従来のHTMLに関するパラダイムシフトがある程度は必要なわけです 。
この部分の考え方は、モダンであると同時にシンプルでもあるし効率的でもあるとも思います。
ただ、このシフトがいまひとつピンと来ない人や、これらのテンプレートの表現になじめない人もいると思 います。
そこで、今回はHTMLを直接扱う方法の紹介です。
ちなみに、Jadeやejsとは何か? ということに少し説明を加えようと思います。

Jadeは、HTMLからタグを取り払いインデントの階層でドキュメントを表現し、その構造をJadeテンプレートに投入してHTMLに変換する機能です。
コードとしては以下のような雰囲気になります。

extends layout

block content
  h1= title
  p Welcome to #{title}

  h3 BootStrap3 Sampler
  ul
    li: a(href="./bootstrap-nav") ボタン・サンプル

リクエストで受け取ったパラメータから title という文字列を取り出して画面に表示します。加えて上記の例では Bootstrap3 を装飾として使用しています。
ejsは、もっとHTMLそのものに近く直感的にわかりやすいと思います。それは、たとえば NetFrameworkの ASP.NET MVC で採用されているスキャフォールディングや、Ruby on RailsのViewの構造に近いとも言えます。

さて、本題に戻ります。
目標はHTMLの表現でViewを作り、そのままレスポンスとして返す方針の解決法です。

package.json に ejs のモジュールを追加します。
"ejs": "latest"

続いて

$ npm install

これで ejsモジュールがプロジェクトに追加されます。

app.js に以下を記述します。

app.engine('htm', require('ejs').renderFile);
app.engine('html', require('ejs').renderFile);

後は、個別に js ファイルにRESTを作成します。例えば下記のようにです。

router.get('/', function (req, res) {
    res.render('index.html', { title: 'Express' });
});

ここで出現した index.html はHTMLのルールに基づいて作成したファイルです。
これで素のHTML構造を返すことが可能になります。

2015年10月16日金曜日

コンテナ・インジェクションのアンチパターン

以前 C#におけるインジェクションテクニックのうち、Bastard Injection の紹介をしましたが、今回は Late Binding の手法を使ってみようと思います。
2000年代半ばの Java のフィールドでは数多くのプラクティスが生み出されましたが、他ならないリフレクションの最も基本的な実装方法とも言えます。
Spring framework では、最も洗練されたDIコンテナ(依存性の注入)の運用が編みだれました。
その中心的な考え方は、実装とインスタンスの生成を完全に切り離してしまうものです。それを今回はC#で試してみようという寸法です。

まずは、プログラムのインタフェース規約を定義します。

namespace Sample.DISampler.Injection
{
    interface IMessageWriter
    {
        void Execute();
    }
}


続いて、規約に基づいた実装です。

namespace Sample.DISampler.Injection
{
    public class ConsoleMessageWriter : IMessageWriter
    {
        public void Execute()
        {
            Console.WriteLine("OK!");
        }
    }
}


さて、コンフィギュレーションでは、検索のkeyとなるキーワードに対して、valueにコンテナ実装をフルネームで記述します。

<appSettings>
    <add key="InjectMessage"
         value="Sample.DISampler.Injection.ConsoleMessageWriter"/>
</appSettings>

最後に呼び出し方法です。

var typeName = ConfigurationManager.AppSettings["InjectMessage"];
var type = Type.GetType(typeName, true);
IMessageWriter writer =
(IMessageWriter)Activator.CreateInstance(type);
writer.Execute();


つまり、設定ファイルに記述された文字列から対応するクラスをインスタンス化して実際に動かすという目論見です。
動くまでは、どんな型になるのかは決まりません。
クラスの依存を動的に解決するわけです。

2015年10月13日火曜日

Vagrantfile で仮想環境を生成しよう

先日、Vagrantを使いコマンドラインから仮想環境を生成する方法を紹介しましたが、今回は、Vagrantfileに仮想環境の作成手順書を記述することにより、仮想インスタンスを生成する方法を書いてみようと思います。
Vagrantfile というのは、作成したい仮想環境をテキストとして記述しておくことにより、生成状態が常に一定の結果が期待される、いわゆる Infrastructure as Code の中心的な考え方を実現する手法です。
当然、ターミナルを開いてコマンドラインで1ステップづつ実行する場合と同じ結果が得られることを目標とするわけですが、結果を得るまでの品質がまったく違います。
コマンドラインの実行は誤りを犯しやすいわけですが、コードとして実行手順を記述すると、結果は常に同じになるわけです。
加えて、最も大切なポイントとして、環境を構築するコードは、実際的な「手順書」になるわけです。ここは、ぜひとも押さえておいてください。

では、Vagrantfle をまず作成します。
そのまえに、VirtualBox と Vagrant が導入してある前提です。OSは何でもよいと思います。自分の環境で構いません。
任意のディレクトリで以下のコマンドを実行します。

> vagrant init

この結果、Vagrantfile が作成され、あらかじめ必要なひな形は既にできています。
そこで、内容を以下のように編集します。

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "centos65"
  config.vm.box_url = "https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box"

  config.vm.hostname = "vagranthost"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.network "public_network"

  config.vm.synced_folder "host", "/guest"
  config.vm.provision :shell, :inline => "echo hello world"
  config.vm.provision :shell, :path => "provision.sh"
  config.vm.provision "file", source: "test.html", destination: "/guest/test.html"
end

do ~ end までがひとつの括りです。
では、ひとつづつ見ていきます。

config.vm.box_url
ここには、仮想環境を生成するうえで基になるBoxの入手先のURLを記述します。
以前も書いたように Vagrantbox.es などから、使用するOSイメージの入手先をコピーするのが簡単です。
例では、CentOS 6.5 のイメージを使用します。
そして config.vm.box には、任意の名前をつけます。

つづいてネットワークの設定です。
ホスト名にしたい任意の文字列を設定します。ここでは”samplehost ”という名前にしています。
config.vm.hostname = "samplehost"

ポートのフォワード設定には、ホストOSとゲストOSのポートの転送を設定します。
たとえば、ゲストOSの80番ポートをホストOSの8080に転送する場合、次のように記述します。
この設定を行うと、ホストOSでlocalhost:8080にアクセスすると、ゲストOSの80番ポートにアクセスできます。
config.vm.network "forwarded_port", guest: 80, host: 8080

ゲストOSにプライベートネットワークを設定します。
この例の場合、ホストOSから192.168.33.10のプライベートアドレスで、ゲストOSにアクセスできます。
config.vm.network "private_network", ip: "192.168.33.10"

ゲストOSにパブリックネットワークを設定できます。
プライベートネットワークの設定と同じようにStatic IPを指定できますが、次の例のようにIPアドレスを指定しなかった場合は、ゲストOSにホストOSと同じネットワーク環境でDHCP用のIPアドレスが設定されます。
config.vm.network "public_network"

ホストとゲストでディレクトリを共有します。
通常、Vagrantfileを置いたディレクトリがゲストから見ると /vagrant になります。
下記の例では、Vagrantfileを配置したフォルダに”host”フォルダを作成しました。
次にVagrantfileに以下の設定を行います。これにより、ホストOSの”host”フォルダとゲストOSの” /guest”が共有されます。
config.vm.synced_folder "host", "/guest"

プロビジョニング設定では、仮想環境構築時にあらかじめ用意しておいたシェルスクリプトを実行したり、ファイルを配置したりできます。
また、Chefなどの他のプロビジョニングツールと連携して環境を構築できます。
下記の例はもっともシンプルなシェルスクリプトによるコマンド実行の例について説明します。
まず、Vagrantでシェルを実行するには、config.vm.provision :shellを設定します。
例では、シェルをinlineで実行し、コンソールに”hello world”を出力する例です。
config.vm.provision :shell, :inline => "echo hello world"

実行したいコマンドを別ファイルに書いて一括で実行することもできます。
次の例では、"provision.sh"というファイルに書かれたコマンドを実行するための設定です。
provision.shは、Vagrantfileを格納したのと同じ階層のディレクトリに配置します。
config.vm.provision :shell, :path => "provision.sh"

ちなみに、provision.sh の中には次のような記述をします。
sudo yum -y install httpd
sudo service httpd start
ln -fs /guest/ /var/www/html
そうです。apache httpdサーバをインストールして起動しています。

セットアップ時にあらかじめゲストOSに任意のファイルを配置することもできます。
次の例では、ホストOS上に用意したtest.htmlをゲストOS上の"/guest"フォルダに配置しています。
config.vm.provision "file", source: "test.html", destination: "/guest/test.html"

さて、では次のようなコマンドを入力してみてください。

> vagrant up

先日、ご紹介したコマンドと同じです。
ただし、今回は Vagrantfle を元に仮想環境を自動で構築して、さらにプロビジョニングまで実行します。その結果、Webサーバが起動して htmlファイルをホストするまでを確認できます。
確認してみてください。

2015年10月2日金曜日

Bower

今回は、HTML/JavaScriptのパッケージ管理ツールを紹介したいと思います。
ふだん、あまりこの分野に関わりのない方は、ちょうど Visual Studio での .NET系の開発に NuGetを活用したり、Rubyでいうところの RubyGems だと考えてもらえればイメージしやすいと思います。

そんなわけで、今回ターゲットにしたいのは Bower です。
Bowerは、HTML/JavaScriptを対象に、CSSなども含めて依存性を解決しつつ管理することができます。
ここで思うのは、同じ対象を管轄範囲とする npm とキャラクターが重なります。
確かにそうなのですが、きちんと住み分けができていますので、簡単に整理しておきます。

Bower: jQueryや、CSSなどフロントエンドに関わるものが中心
npm: サーバーサイドを軸に開発系のパッケージ管理なども含む

さて、早速 Bower を導入しようと思いますが、Node.jsとGitが必要です。
以下のコマンドでインストールしますが、グローバルオプションを指定します。

$ npm install -g bower

これでインストールは完了です。
任意のディレクトリに移動して、jQueryをダウンロードしてみます。

$ bower install jquery

バージョンを指定してダウンロードしたい場合は

$ bower install jquery#1.11.3

また、直接GitHubのURLを指定してダウンロードすることもできます。

$ bower install git://github.com/jquery/jquery.git

加えて、GitHubのユーザ/リポジトリを指定してもOKです。

$ bower install jquery/jquery

さらに、任意のURLを指定してダウンロードすることも可能です。

$ bower install http://xxxyyy.com/script.js


今度は Bootstrap を導入してみます。依存するjQueryも判断してダウンロードしてくれます。

$ bower install bootstrap


これらの結果は、bower.jsonに設定されます。
あるいは、bower.json に記述してから

$ bower init

でもOKです。
使い勝手は npm とほぼ同じです。

今度は逆のアプローチをとります。必要なパッケージをダウンロードして、bower.json にリストします。

$ bower install bootstrap --save

これも npm と同じコマンドオペレーションです。

では、最後に導入したパッケージをリストします。依存性がツリーの形式で表現されます。

$ bower list


このような管理系の問題は人手で解決するのは難しいものです。
ぜひとも、オートメーション化して、正しい手の抜きかたを実現したいものです。
さらに大きなメリットとして、このような解決が難しい問題の本質は、ドキュメントと実装が乖離していくという点で、そのような問題を防止できるということを指摘できます。
現代のシステム構築でこれをクリアするのははっきりいって困難だと思います。無駄な努力はさっさとあきらめて、jsonスキーマに管理をまかせてしまうのも一手だと思います。
つまり、源泉はただひとつ、という方針を貫くのです。jsonスキーマであれば、管理の属人性も排除できますし、いかようにも加工ができるという点で大きなアドバンテージになるのではないでしょうか。

2015年10月1日木曜日

Docker - 削除系のTips2題

Docker でいろいろ試行錯誤をしていると、さて。。となることがよくあります。
そんなときの軽いTips2題。

$ docker imgaes
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
<none>  <none>  c395172a74e5  8 hours ago  1.151 GB
<none>  <none>  05a17381460b  8 hours ago  1.151 GB
<none>  <none>  eb3ce0796961  8 hours ago

と、こんな状況に陥ることがまれにあります。
そんなときは、以下のコマンドで <none> のイメージをきれいに削除できます。

$ docker images | awk '/<none/{print $3}' | xargs docker rmi

では、すべてのイメージを一気に片付けたい場合は

$ docker images | awk '{print $3}' | xargs docker rmi

で、一気にきれいになくなります。
必ず使うコマンドなので、メモしておくとよいです。

2015年9月30日水曜日

最近のWebの潮流

さて、いまどきのフロントエンド開発は恐ろしいことになっていて、シーンから少し遠ざかっただけで、取り返すのが大変な状況に陥ってしまうことも少なくはない。
わかりやすい例でいえば、Webの要とも言っても過言ではないJavaScriptが実は、扱うのに大変な苦労を強いられる。細心の注意を払わないと、あるいは、ちょっと手を抜くとたちまちスパゲティコードになってしまうという致命傷的な特性を持っている。
これをいかに解決するか?という観点でさまざまなフレームワークなり、ツールなりが考えられて使われてきたわけだが、その中でもおもしろいのが、CoffeeScriptの立場だ。
これは言語ではなく、あくまでシンタックスシュガーという位置づけで、規定は実装者自身に委ねられる。

つまり、オブジェクト指向で書きなさいと。

当然ながら、JSではクラスの概念をサポートしているわけではないので、なんとか工夫をしながら書いてきた歴史がある。この部分を乗り越えたのが CoffeeScript の功績だとも言えるのかもしれない。

はっきりいって面倒なものです。

独自のシンタックス感で CoffeScript を記述し、gulpやGrantでコンパイルする。さらにCSSをSassから変換して、のちほど散らかったファイル群を統合する。
しかし、JSの世界にクラスの概念を持ち込み・・・ 正確に言うとJSで実装する部分にオブジェクトアプローチの世界観をもたらしたことのメリットは実は大きいのです。

そして、当然のように面倒な部分は自動化し、極力、人の手の介在を避け、設計にこそ頭を使おうとこんなところを目指すのです。

2015年9月29日火曜日

Dockerfile から Dockerコンテナを生成しよう

今回は、Dockerfileを記述して、Dockerコンテナを生成するプロセスを体験します。
目指すのは、Webサーバを起動して動作を確認する、です。

まず、任意のディレクトリに Dockerfile という名前のファイルを作成して、以下のような記述をします。

FROM ubuntu:14.04
MAINTAINER kenny <kenny@mail.com>
RUN apt-get install -y nginx
ADD index.html /usr/share/nginx/html/

FROM で コンテナを作るにあたりベースになる環境として、Ubuntu14.04を使います。
MAINTAINER は見てのとおり作成者です。
コンテナをビルドするときに、上から順番に命令が走るわけですが、RUN でコマンドを実行します。
上の例では、nginxをインストールしています。非対話モードで走らせなければならないため -y オプションを追加しておきます。
次の ADD コマンドで、/usr/share/nginx/html に index.html を配置します。

たったこれだけです。
もちろん、必要最小限のコードしか記述していませんが、基本はこんな感じです。
これだけで、index.html を表示するWebを起動することができるわけです。

さて、index.html の中は空なので、このままでは結果を確認できません。

$ echo 'Hello!' > index.html

これでOK!

では、コンテナをビルドしてイメージを作ります。
$ docker build -t kenny/nginx:0.5 .

名前は適当でも構いませんが、慣習として <username>/<imagename> のように付与するのが推奨されます。
-t オプションでタグをつけます。上の例では 0.5 です。
注意点をひとつ。
最後の .(ドット)は忘れやすいので、注意です。最後の引数は、Dockerfileの配置したパスを指定します。つまり、このコード例では、カレントディレクトリで作業していることになります。

結果をリストします。
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
kenny/nginx 0.5  f5468aac82bb  18 seconds ago  206.9 MB
ubuntu 14.04  91e54dfb1179  5 weeks ago  188.4 MB

ここまできたらあとは起動してコンテナを生成します。
docker run -d -p 80:80 --name nginx1 kenny/nginx:0.5 /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
18c2ceb92246540662d390550334b0c1f75e4437aa7fd66766ca2ffec25c6f8e

--name で nginx1 という名前をつけて、-d でバックグランドで動作します。
-p で80番ポートを常時リッスンして、ホスト側で80番でアクセスできます。

ためしに、curlコマンドで確認してみます。
$ curl localhost:80
Hello!

想定したとおり Hello! が得られました。
ブラウザで localhost:80 でアクセスしても、当然、同じ結果が得られます。

2015年9月28日月曜日

nodebrew で Node.js を管理する

先日は、Node.js を nvm で管理する方法を書きましたが、今回は、nodebrew を使ってみます。
特徴はこんな感じです。

1)perl で作られているため、Macなどに入っている可能性が高い
2)curl や wget で入れるため、git が入ってなくても構わない
3)パスを指定すれば、nodebrewコマンドが実行可能(.bashrc .zshrc に記述)
  つまり、sudo 指定がいらない
4)ls-remote、clean など、機能はひととおり網羅

こんなところです。
では、インストールいきます。

$ wget git.io/nodebrew

$ perl nodebrew setup
fetching nodebrew...
install nodebrew in $HOME/.nodebrew

========================================
Add path:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================

こんな指示が出ると思うので、従う。

$ vi ~/.bashrc
で、オープンする。
vim のタイプが苦手だ! という方は
$ sudo gedit ~/.basrc
これで、WondowsライクにGUIエディタでOKです。

で、指示にあるとおり、下記の行を追加します。

export PATH=$HOME/.nodebrew/current/bin:$PATH

追加したら、設定ファイルをリロードします。

$ source .bashrc

この状態で nodebrew コマンドを実行すると

$ nodebrew
nodebrew 0.9.0

Usage:
    nodebrew help                         Show this message
    nodebrew install <version>            Download and install a <version> (compile from source)
    nodebrew install-binary <version>     Download and install a <version> (binary file)
    nodebrew uninstall <version>          Uninstall a version
    nodebrew use <version>                Use <version>
    nodebrew list                         List installed versions
    nodebrew ls                           Alias for `list`
    nodebrew ls-remote                    List remote versions
    nodebrew ls-all                       List remote and installed versions
    nodebrew alias <key> <version>        Set alias to version
    nodebrew unalias <key>                Remove alias
    nodebrew clean <version> | all        Remove source file
    nodebrew selfupdate                   Update nodebrew
    nodebrew migrate-package <version>    Install global NPM packages contained in <version> to current version
    nodebrew exec <version> -- <command>  Execute <command> specified <version>

Example:
    # install from binary
    nodebrew install-binary v0.10.22

    # use a specific version number
    nodebrew use v0.10.22

    # io.js
    nodebrew install-binary io@v1.0.0
    nodebrew use io@v1.0.0

これで、あとは察しがつくと思いますが…
利用可能な Node.js と io.js のバージョンをリストする
$ nodebrew ls-remote

使用する Node.js をインストールしてやる
$ nodebrew install-binary v0.11.13
もちろん、npm もいっしょに入ります。

使用する Node.js を確定する。これを忘れないように。
$ nodebrew use v0.11.13
use v0.11.13

最後に確認します。
$ node -v
v0.11.13
$ npm -v
1.4.9

いかがでしたか?
とても簡単です。そしてわかりやすいと思います。

2015年9月25日金曜日

Vagrantで仮想環境構築の自動化を目指す

今回は仮想環境を自動で構築する方法を試してみます。
あらかじめ VirtualBox がインストールされていることが前提になります。
なに? 自動構築と思えば、なんだそういうことか・・・ と言わずに、これには多大なメリットが得られます。
たとえば、何名かのメンバーでチーム開発を始めることを想像してみてください。それぞれのホストOSはバラバラなので、仮想環境を構築して開発環境を揃えるという方針をとります。
しかし、各々が、バラバラに開発環境を構築した場合のデメリットはあまりにも大きすぎます。非常にシビアな開発プラットホームをメンバー全員が共有できるでしょうか? とても難しい問題です。
今回は、その問題を簡単に、そして、シンプルに解決するソリューションのご紹介です。

では、VirtualBox がインストールされていない方は、早速導入します。
次に、今回の軸となるツール Vagrant をインストールします。
これは、各々の環境に応じたものをダウンロードすればよいでしょう。

インストール自体はとても簡単です。
終了したら次のコマンドでインストール結果を確認します。

$ vagrant -v
Vagrant 1.7.4

では、開発環境の構築をするための手続きを実施します。
まずは Box と呼ばれるものを追加します。Boxとは、仮想環境を構築するにあたりベースになるテンプレートと考えてよいと思います。
このテンプレートに対してさまざまなパッケージを導入するなりして、仮想環境を整備します。このベースになる部分はたとえば、
Vagrantbox.es などのようなサイトに集積されてるので、はじめはそれを利用するのがベストな選択だと言えるでしょう。
Boxを追加するコマンドは以下のとおりです。

$ vagrant box add [name] [url]

[name] はこれから作成する仮想環境の名前を付与します。どんな名前をつけても構いません。
[url] の部分には、テンプレートとなるboxイメージをダウンロードするURLを指定します。
たとえば、以下のようになります。

$ vagrant box add centos_6_3_32bit http://tom.davidson.me.uk/dev/vagrant/centos63-32.box

コマンドを実行します。

http://tom.davidson.me.uk/dev/vagrant/centos63-32.box
Downloading box from vagrant box add centOS63_32 http://tom.davidson.me.uk/dev/vagrant/centos63-32.box
Extracting box...ate: 642k/s, Estimated time remaining: --:--:--)
Successfully added box 'centOS63_32' with provider 'virtualbox'!

Successfully added box・・・ と表示されたら完了です。
では、結果をリストしてみます。

$ vagrant box list
centos_6_3_32bit (virtualbox)

次にたったいまダウンロードしたテンプレートを元に初期化します。
適当なディレクトリを作成して、その場所をカレントとします。

cd C:\Users\username\Cent_OS_6_3_32

では、さきほどのBoxを名前を指定して初期化します。

$ vagrant init centos_6_3_32bit

初期化が完了したら、SSHでアクセスできるように設定ファイルを書き換えます。
カレントディレクトリに Vagrantfile が生成されているはずなので、config.vm.network セクションを変更します。
IPアドレスの部分のコメントアウトを外します。

# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network :private_network, ip: "192.168.33.10"

これで、192.168.33.10 が仮想マシンに割り当てられました。
これで起動できる状態になったので、起動します。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.3.16
    default: VirtualBox Version: 5.0
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => C:/Users/username/Cent_OS_6_3_32
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.

起動しました。
終わりから3行目に共有フォルダの設定が表示されていますが、この内容はVirtualBoxからでも参照できます。

仮想マシンへの接続は TeraTerm などを使ってSSH接続します。Windows以外であれば vagrant ssh というコマンドを使えます。
SSH接続は

ホスト: 192.168.33.10
ポート: 22
ユーザ: vagrant
パスフレーズ: vagrant

でログインします。

さて、ベースになる仮想マシンができあがったので、あとは開発に必要なパッケージを適宜導入して、メンバ間でこの仮想環境をシェアすれば、環境の差異という問題を解決することが可能になります。
もうひとつ、大きなメリットは仮想環境をひとつ作成すれば、ほかのメンバーに共有することにより、それぞれが環境を構築するという煩わしさから開放されます。

ぜひ、試してみてください。

2015年9月24日木曜日

nvmでインストールされたNode.jsを管理する

nvm を使用すると、複数の Node.js を管理できるようになります。
ちょうど Ruby における RVM と同じ思想ですね。強い影響下にあることがわかります。

では、早速 nvm をインストールしますが、ソースパッケージをビルドするにあたり必要なパッケージを前もってインストールしておき ます。

$ sudo apt-get update
$ sudo apt-get install build-essential libssl-dev

次に GitHub からインストールスクリプトを取得して実行します。
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.26.1/install.sh | bash

profleのいずれかが更新されるので、ターミナルを開きなおします。
これで、nvmコマンドを発行することができるようになりました。
次のコマンドで、インストールが可能なNodeを確認することができます。

$ nvm ls-remote

上記のコマンドの結果、導出されたリストから適宜、選択したNodeをインストールします。
最新のv4.1.1をインストールします。

$ nvm install 4.1.1

~/.nvm 配下に指定したバージョンのNodeがインストールされます。
同時に、npmもインストールされます。

インストールされたバージョンのNodeを明示的に指定しなければなりません。
$ nvm use 4.1.1

結果を確認します。
$ node -v
v4.1.1
$ npm -v
2.14.4

管理下にあるバージョンをリストするには次のコマンドを実行します。

$ nvm ls

デフォルトで使用するバージョンを指定します。

$ nvm alias default x.x.x
default -> x.x.x (-> vx.x.x)

また、現在選択されているバージョンを明示的に設定するには、次のコマンドを実行します。

$ nvm use default Now using node vx.x.x (npm vx.x.x)

これで、適宜必要なNode.jsのバージョンを指定できるようになりました。

2015年9月19日土曜日

DockerでWordPressを起動してみる

ubuntu に Docker をインストールしてある前提で話を進めます。
Dockerイメージではなく、Dockerfileを使ってビルドする方法をとってみます。

$ docker build --rm -t (name)/wordpress git://github.com/jbfink/docker-wordpress.git

(name)の部分は適当な名前を付与して構いません。
これを実行することにより必要なイメージをダウンロードしてビルドします。

次に、以下のコマンドを実行します。
$ docker run --name wordpress1 -d -p 8080:80 -p 2022:22 (name)/wordpress

(name)は適当に付与した名前です。たとえば、sample という名前をつけたなら、sample/wordpress というDockerイメージができあがるわけです。
そして、wordpress1という名前をコンテナに付与しています。
加えて、80番(HTTP)と、22番(SSH)のポートをホストの 8080番に、2022番に、それぞれルーティングするように設定します。

これで完了です。
では、http://localhost:8080/ にアクセスしてみてください。



WordPress のインストール画面が表示されます。
簡単ですね。

では、WordPressをインストールしちゃいます。


サクッと完了です。

では、Dockerコンテナを終了してみます。
$ docker stop wordpress

これで、さきほどのURLにアクセスしてみてください。画面は表示できないはずです。
もう一度、再開するには
$ docker start wordpress

さて、ここからがポイントです。
コンテナは終了すると破棄されます。つまり、インスタンスを失い次に起動したときは新しいインスタンスで立ち上がります。
したがって、コンテナの中で設定された内容は永続化されません。
それでは困ってしまうので、現在の状況を別のコンテナとして記録します。

$ docker ps -a

上記のコマンドで現在のコンテナプロセス(起動しているもの、停止しているものも共に)がリストされます。その中から、さきほど停止したコンテナのIDに注目します。
そのうえで、以下のコマンドを実行します。

$ docker commit (CONTAINER ID) wordpress2:test

これで、さきほどのWordPressコンテナをコミットしました。
その上で、コンテナのイメージをリストします。

$ docker images

REPOSITPRYが wordpress2、TAGが test というイメージがリストされたでしょうか。
これで、さきほど停止、または 中断したときの状態からコンテナを起動することができるようになります。

2015年9月18日金曜日

スコープに注意しよう

スコープとは見える範囲を規定する表現だ。
スコープとは見えてはいけない領域を明確にする思想だ。

オブジェクト指向におけるスコープの規定はだいたい前者の理解が主流だと思う。
おそらく世の中に出回っている参考書やガイドブックの類はほとんどが前述のような説明をしていると思う。
もちろん間違ってはいない。 ただし、充分か? と言えば、必ずしも充分ではないように思われる。 スコープ定義のひとつの目的として不具合の囲い込みがあげられる。適切に見える範囲をコントロールすることにより、不用意に値を参照したり書き換えてしまったりしないようにすることだ。
アクセス可能な範囲を適切に縮小して狭めてやることで動作のメカニズムは安全なものとなる。正確にいうと、動作のしくみ自体が安全なのではなく、実装や検討をするにあたり考えなければならない範囲を少なくしている。つまり、ひとの頭の中の思考をなるべくシンプルにして、その結果、誤りを減らそうとする努力の表れだ。
この思考そのものは、見えるもの を制御することに軸がおかれるため、見える範囲から見えない範囲の方向に進みがちだ。したがって、観察対象の本質を見誤れば見える範囲として認識される可能性がある。
この誤りの方向は必ず見える範囲で起こる。
すなわち、ここで不用意にデータを書き換えてしまう危険性が生まれるわけだ。
実は、このスタイルの不具合というのが最も多いように思われる。と同時に、人々の仕事の最も苦しい部分を助長する要因でもあるように思われる。
見える範囲でモデリングをしている限りは必ず起こり得る問題だ。そして、この問題の本質はスコープ制御ではなく、観察対象の分類、整理に突き当たる。

では、逆のアプローチをとることが可能なのか?
可能であればその有用性は? ということについて考えてみたい。

今度は見えてはいけない範囲の考察が軸になる。
観察対象は、はじめは種々雑多なデータやコンテキストが散りばめられた状態だと思う。
ここから不要なものを取り除いてゆくわけだが、一気に分解して整理してゆくのは難しい。徐々に問題を解体しつつ段階を踏む必要がある。当然、このときに意識するスコープに不要なのか? 必要なのか? という観点で分析が進むはずだが、もうひとつ特殊な性格をもった観察対象の発見があるに違いない。
それは、ほかのスコープでも使用することが予想されるものの発見だ。
実はこの部分がキーポイントになる。さきほどあげたスコープの内側から、いわゆる共通データや共通コンテキストを、考察の対象としてスコープ内でどのように定義するべきか? という問題に答えを出すのは非常に難しい。
分類、整理におけるねじれ現象にあたるこの問題を正確に捉えるには、対象スコープの外側からしか、その合理性を考察できない。
このねじれ現象をスコープの内側からの解決手段を定義しようとすると、後程、ほかのスコープから考察した場合のことを想定するのは難しいし、また、ほかの機会に、現在のスコープの共通項目を正確に捉えるのは困難だ。

ここまでで新たな発見があったと思うが、観察対象のスコープの外側から考察した場合、たったいま考えた、ほかのスコープとの共通項目が存在した場合、あるいは、見つけた場合は、それ自体が独立したスコープを形成し得ることをここで確認しておきたい。

2015年9月16日水曜日

Node.js 4.0.0 へ

Node.js の開発チームは最新の安定版となる Node v4.0.0 をリリースしました。

主な変更点としては

・非同期のコールバックパラメータを扱えるchild_processの追加
・拡張モジュールのビルドツールnode-gypおよびパッケージ管理ツールnpmのアップデート
・timerのパフォーマンス向上 など。

なお、Node は LTSと定期サイクルのリリースを進めているが、最初の LTS を10月にリリースする模様。

2015年9月15日火曜日

Go kit

世の中のサービスが、マイクロサービスのベストプラクティスの標準化を画策する中、おもしろいムーブメントが起きるのではないか? という予感がします。

Goと「Go kit」によるマイクロサービス構築


このインタビュー記事の中で、組織の中での作業の標準化というキーワードが何度となく飛び出してきます。
これはまさに重要なことを示唆しています。
問題なのは、アーキテクチャの中にあるのではなく実装の標準化に達していない文化なのだと思います。

2015年9月14日月曜日

命名法

思いの外悩むものが、名前の付け方だ。
変数から始まってメソッド、関数、クラス、名前空間、プロジェクト名称…
名前を付けるべきものはたくさんある。
命名とはパッケージなのだ。命名に関して思い悩む、あるいは、なかなかつけられないのは想像力が欠如しているわけではない。
分析が足りないだけだ。もしくは、名前をつけるには不適当な粒度と内容を持っているかもしれないことを検討する余地が残っているだけかもしれない。
一意の名前をつけられない原因は、対象となる変数なりクラスが、いったいどういう役割を持っているのか?という点でしっかりと確定されていないだけかもしれない。

そこで帰納法を試してみよう。
帰納法とは、特化したものから観察結果を取り出し一般的なものを導き出す手法だ。
つまり概念化して、形態や方向性など、モデルとしての本質を探る。まず、この段階で余計なファクタが取り除かれ重要なポイントだけが残ると思う。ここまでは確認段階だ。いわゆるインタフェースの抽出に似ている。

次にまったく逆のアプローチをとる。
演繹法により前提条件から結論を導き出す。ちょうど数学の公理から系統を導き出すようなイメージだ。ここでは、一般から特殊へと逆の流れをとる。
ここで、概念モデルから特殊化されたモデルが形成され、その対象を表す、もしくは、要約するべき名前が見つかれば幸いだ。
もし、この時点で要約すべき表現が見つからなければ、対象が明らかに役割過多かもしれない。

と、理屈ばかり書いたように思えるが、これは私たちがふだん行ったり来たりしているモデリング手法そのものだ。

2015年9月10日木曜日

AIによる作曲は果たして可能なのか?

この記事によると、Hello World というタイトルが付けられた実験音楽ではあるが、拍子は4/4拍子。
ただし、冒頭からピアノが4拍3連の連符を弾き、トップのバイオリンが3拍に感じられるであろうゆるやかなパッセージを奏でる。と思ったら、クラリネットがこのコンビネーションの中で旋律を前に引っ張っていくようなリズムをギミックのように表現している。なおかつ、このクラリネットのカウンターパートにバイオリンのトップノートは1小節目の最終拍で減5度で音をぶつけている。そうぶつけているのだ。
これは聞く人によっては強烈な不協感とインパクトを与えるだろう。加えてリズムのギミックはポリリズムの展開を見せ、果たしてこの音楽はどういうビート感を伴っているのか? とまどうに違いない。唯一、聞き分けが容易なのがピアノの3連符の強烈なインパクトだ。

これは、いわゆるアルゴリズムにより作られた音楽だそうだ。
作られたというより、ほぼインプロビゼーションの雰囲気に近いもののようにも思える。 音楽は、基本的に数学であり時間芸術だ。つまり、時間と周波数の高さを数理的に定義してはじめて成り立つものだ。このあたりが絵画や文学とは違った性質を持つ。そういう意味では、音楽は次元の設計に他ならず論理には極めてマッチする。
この試みは決して目新しいものではなく、かつて、ピエール・ブーレーズの音楽や、もしかしたらジョン・ケージも、そして、あのイゴール・ストラビンスキーの「春の祭典」で対数の分析から導き出された音楽たちで、その効果を追体験することが可能である。
そして、件の記事を追っていくと生活の音楽を提案している。これはまぎれもないエリック・サティの環境音楽の思想そのものだろう。 おもしろいことに音楽は一定の周期で、まるで波のように解釈や焼きなおしというムーブメントが必ず起こるが、このようなアルゴリズムが自立して紡ぎだす音楽が、今後のトレンドになるのかもしれない。

果たして、このアルゴリズムの音楽はどのような展開を見せるのか?

2015年9月9日水曜日

Prototype宣言

オブジェクトというものを考えてみます。

とはいっても、所謂オブジェクト指向言語のオブジェクトではなく、プロトタイプベースのオブジェクトを考えてみます。
その前に従来のオブジェクト指向言語のオブジェクトを簡単に振り返ってみます。
まず、システムやソフトウェアはあるシナリオによって動作します。このシナリオをできるだけ細かく分解して汎用的な部分を共通化して合理的な実装に備えます。
しかし、これではまだ不充分で、特性や性質、あるいは、本質的に何を表現するのか? という観点でさらに分解されます。
つまり、ある事象の根本的な動作の表現、それを色づけるための特性や性質に分解されることに結実するのがオブジェクトに対するアプローチだと思います。
たとえば、前者がコンテキストだったり、後者がデータだったりします。
合理的な単位で分解されたものがオブジェクトになり得る候補になります。私たちがやることは、その分析結果をクラスという概念でモデル化して、電気信号に変えられインスタンスに変化します。 これがオブジェクトです。
ここで注意したいのは、このオブジェクトは既に特性や性質を兼ね備えているということです。それらはメンバという形で自然に存在します。
なぜなら、オブジェクトとして実体になるクラスがそのように定義されているからです。

さて、ECMAScriptの世界はどうでしょうか?
プロトタイプベースのオブジェクトは、実はそのように考えません。
オブジェクト自身は別のオブジェクトを追加することにより、新たな性質が加わります。
これがプロトタイプの考え方です。
では、そのプロトタイプベースの考え方に則りオブジェクトを生成してみます。

function Object() {}
var onj = new Object();

上のオブジェクト定義では retun がありませんが、下のステートメントで new されたときにオブジェクトインスタンスが得られます。

さらに初期化してみます。

function Object() {
    this.param = “done.”;
}
var obj = new Object();
Console.log( obj.param );
>Done. と表示されます。

今度は、このようなコードを書いてみます。
function Object() {}
Object.prototype.param = function() {
    console.log('Done.');
};
var obj = new Object ();
obj .param(); // Done. と表示される。

これでは、どうでしょう。
function Object () {
    this.param = function() {
        console.log('Done.');
   };
}
var obj = new Object ();
obj .param(); // Done.

ほぼ、同じです。
しかも同じように動作します。
しかし、大きな違いがあることがわかると思います。
後者のコードでは毎回インスタンス化されてしまうという違いがあります。 すべてのオブジェクトは prototype オブジェクトの参照を持っています。 この prototype オブジェクトに新たな特性や性質を付与することにより、細かなニュアンスの違いを表すことができます。
オブジェクト指向言語の継承に近い雰囲気を持っているように見えますが、性質が違います。
prototype に特性や性質を加えて、かつ、削除することも可能です。

ここでポイントです。
new により生成されたオブジェクトは、Object の prototype と同じ参照を持っています。
これによりオブジェクトは合理化されるわけです。

2015年9月8日火曜日

ASP.NETの吐き出すマークアップの矯正

知っている人も多いと思いますが、ASP.NET Web Forms の出力するHTMLコードがいかんともしがたい。
CheckBoxやRadioButtonListなどで顕著。
つまり、素直なHTMLツリーが出力されないのだ。

たとえば、以下のマークアップは
<asp:CheckBox ID="check" runat="server" class="myClass" />

このようなHTMLとしてレンダリングされる。
<span class="myClass"><input id="check" type="checkbox" name="check" /></span>

そう、<span></span>タグで括られてしまう。 これでは、フロントエンドでDOM解析をしたいときに非常に不便だ。と同時に input に属性を付与できないという最も大きな問題を引き 起こす。
そこでレンダリング方法をカスタマイズしてみたいと思う。

WebControlAdapterクラスを継承したクラスを作る。
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Adapters;

public class CheckBoxAdapter : WebControlAdapter
{
    protected override void Render(HtmlTextWriter writer)
    {
        CheckBox targetControl = this.Control as CheckBox;
        if (targetControl == null)
        {
            base.Render(writer); return;
        }
        writer.WriteBeginTag("input");
        writer.WriteAttribute("type", "checkbox");
        writer.WriteAttribute("id", targetControl.ClientID);
        if (targetControl.CssClass.Length > 0)
        {
            writer.WriteAttribute("class", targetControl.CssClass);
        }
        writer.Write(" />");
    }
}

でもって ブラウザ定義ファイルに以下のコードを追加する。
<browser refID="Default">
<controlAdapters>
                        <adapter controlType="System.Web.UI.WebControls.CheckBox" adapterType="CheckBoxAdapter" />
        </controlAdapters>
</browser>

さて、この状態で以下のようなマークアップがどのように変化するのか・・・ というと
<div> <asp:CheckBox ID="check" runat="server" CssClass="myClass" /> </div>

きれいなHTMLコードをレンダリングするようになりました。
<div> <input type="checkbox" id="check" class="myClass" /> </div>

まぁ、いまさら ASP.NET Web Forms もないだろ・・ という声も聞こえてきそうですが、画面の初期化を Web Forms で画面の更新を Web API で実行するハイブリット方針も、これはこれでなかなか生産性が高い方法でもあるのです。

コミット・メッセージには気をつかっていますか?

コミット・メッセージには気をつかっていますか?
1か月も経てば、いや、1週間程度でほとんど記憶も吹っ飛び、自分が書いたメッセージさえ意味がわからないなんてことになっていませんか?
たとえば、Git界隈では、このあたりも積極的に議論が成され一定の規範に則って運用しようという文化が醸成されつつあります。
調べてわかればよい、という意見も多く聞かれますが、果たしてこの感覚は正しいものでしょうか?
いえ、正しい誤りという二律背反的な捉え方は無意味でしょう。 第一、時間の無駄です。調べるという行為には追跡という要素があります。この追跡という行為には推測という要素がつきものです。つまり、推測に誤りがあれば間違った情報や解釈に到達してしまう危険性があります。
たかが、コミットメッセージだけで大げさな… という見方もできるかもしれません。事はコミットメッセージだけに留まらずドキュメントやコードにまで影響するのです。

どういうことか?
コミットメッセージさえ気を使えなければ、ドキュメントもまたしかりだと思います。
これは作業品質の問題です。 あるいは、余計なことに頭を使う必要がなければ、もっと本質的な部分に注力することが可能になります。

2015年9月5日土曜日

boot2dockerを試す

WindowsやOSXな方は、boot2docker を導入することで、手軽に Docker のソリューションを試してみることができます。
とは言え、それなりにハマりどころが存在するのも、この手の技術の常です。

まずはインストールしてみましょう。
公式サイトに行って自身の環境にあった boot2docker のインストーラをゲットします。
インストール自体は非常にシンプルで、指示に従うのみです。
その際、VirtualBoxとcygwinもいっしょにインストールされますが、既に導入済みのかたはチェックを外せばいいでしょう。

さて、VirtualBox で 32 bit の仮想サーバーしか作れない、というトラブルに見舞われたなら、BIOSをチェックしてみてください。
VT-x が BIOS で OFF になっているケースが考えられます。

ということで、boot2docker のインストールが完了しました。デスクトップにあるアイコンをダブルクリックすると Dockerコンソールが起動します。このとき、コマンドプロンプトで入力待ち状態になります。これで boot2docker が起動しました。

バージョンを確認してみます。
docker -v

Docker Version 1.8.0. build 0d03096

と表示されれば正常です。

では、早速 Docker を作成します。
たとえば、
docker pull centos:latest

CentOSの最新イメージを取ろうと思います。

と、Pulling repository docker.io...
となったところで、connection refused.

ん。。。

DNSの指定をチェックします。

$ boot2docker ssh
docker@boot2docker:~$ vi /etc/resolv.conf

## そして、以下を追加して
## nameserver 8.8.8.8

docker@boot2docker:~$ cat /etc/resolv.conf
nameserver 8.8.8.8
docker@boot2docker:~$ exit
$ boot2docker restart

そして再び Docker pull

超えるべき壁は多い予感です。

2015年9月3日木曜日

急がば回れ

落ち着きのない仕事をたまに見かけます。というよりかなりの高確率で見かけます。
先を急いでもよいことはありません。

たとえば、ひとつのクラスの実装を終えました。
これから動作させてデバッグをしようと思いますが、果たして、そこで確認をするでしょうか? 再確認です。
クラスを生成してオブジェクト化するにあたり、事前条件は揃っていますか?
実際に動作させた後の事後条件と期待値は頭の中で整理できていますか?
そもそもコードのセルフレビューは実施しましたか?

こういった単純な準備作業は案外重要です。ここで一歩引いて俯瞰するゆとりが、あるのか?ないのか? で時間の節約の仕方がだいぶ変わります。それどころか、この段階でつまらないバグはつぶせるはずです。

昔から言い古されている言葉ですが、ゆっくり、落ち着いて、ひとつひとつ確実にこなすのが結局はいちばん早いのです。

2015年9月2日水曜日

ASP.NETのレガシー・マークアップ

ASP.NET4.5 Web APIで構築されたHTMLに対して Angular.JS でバリデーションをレンダリングしようと企てたのだが、form要素のname属性が捨てられていることに、いまさらながらに気づいた。
下記は MSDN の ASP.NET と XHTML というドキュメントからの抜粋。

---

XHTML に準拠するための ASP.NET 機能 
ASP.NET は、form 要素に action 属性を動的に追加します。既定では、form 要素には XHTML 1.0 Transitional 仕様で許可されている name 属性が含まれています。これ により、フォーム名を使用して form 要素を解決するクライアント スクリプトに依存する既存のアプリケーションとの下位互換性が保持されています。 
メモ : 
form 要素の name 属性は XHTML 1.1 ガイドラインでは許可されていません。name 属性をレンダリングしないようにアプリケーションを構成できます。 

ASP.NET ページとコントロールの XHTML レンダリングの制御 
ASP.NET コントロールで XHTML 1.1 仕様のより厳密な形式でマークアップをレンダリングすることが必要な場合があります。既定のレンダリングには、XHTML 1.1 仕様に 準拠していないマークアップも含まれています。たとえば、XHTML 1.1 標準では、HTML form 要素の name 属性の使用は禁止されています。 
メモ : 
レガシ マークアップをレンダリングするオプションは、主に既存のページを ASP.NET の最新バージョンに移行するために提供されているので、ASP.NET の将来のバージョ ンではサポートされなくなる可能性があります。 

レガシ レンダリング 
レンダリングをレガシに設定すると、ASP.NET のページとコントロールは、レンダリング機能を ASP.NET の以前のバージョンの動作に変更します。次のような変更が行われます。 
form 要素は、name 属性を使用してレンダリングされます。

---

以上を踏まえてASP.NETのマークアップを利用してレンダリングするには、次の3つの方法がある。

・Legacy (以前のバージョンの ASP.NET でのマークアップのレンダリング方法とほぼ同じ、典型的な例は、form タグの name 属性をレンダリングする場合)
・Transitional (XHTML 1.0 Transitional)
・Strict (XHTML 1.0 Strict)

どの方法を使ってレンダリングするかは、以下の方法で指定する。
Web.config ファイルの system.web 要素に xhtmlConformance 要素を追加する。次に、mode 属性を Legacy、Transitional、または Strict に設定する。

xhtmlConformance 要素が Web.config ファイルに定義されていない場合、既定の設定モードは transitional となる。

以下は、XHTML のレンダリングを無効にするコード例

<system.web>
<!-- other elements here -->
    <xhtmlConformance
        mode="Legacy" />
</system.web>

以下は、XHTML 1.0 Strict のレンダリングを指定するコード例

<system.web>
<!-- other elements here -->
    <xhtmlConformance
        mode="Strict" />
</system.web>

では、Legacyレンダリングに設定した場合の副作用は・・・
1)form 要素の内部の div 要素はコントロールのコンテナとして自動的にレンダリングされない
2)検証コントロールは、controltovalidate などのカスタム属性を使用して span 要素としてレンダリングされる
3)img 要素では、alt 属性と src 属性はそれらを明示的に含めない限りレンダリングされない
4)Autoポストバック機能をサポートする必要がある場合、コントロールは language="javascript" などの language 属性をレンダリングする。
5)コントロールの Wrap プロパティが false に設定されている場合、div 要素をレンダリングする Panel などのコントロールに nowrap 属性が追加される
6)ImageButton コントロールは、border 属性をレンダリングする
7)br 要素は、すべて <br> としてページにレンダリングさる。ただし、明示的に <br /> タグを記述すると、そのままレンダリングされる。
8)BackColor プロパティが設定されている場合、DataGrid コントロールと Calendar コントロールには、レンダリングされた table 要素に bordercolor 属性が含まれる

以上は押さえておくべきポイントです。

2015年9月1日火曜日

gulpモジュールで簡単なタスク自動化

gulp は Node.js 上で動作するタスク自動化のためのビルドツールです。
ソースファイルの圧縮、lessファイルのコンパイルやCSSのベンダープレフィックスの付与、CoffeeScriptのコンパイルなどを実行できます。
タスク定義をシンプルな JavaScript で記述して動作させるのが特徴です。このあたりが Grunt のJSONで宣言的に定義する方法より細かい制御がシンプルに記述できる理由です。

では gulp をインストールしてみます。今回はWindowsで試してみます。
まずは npm で gulpモジュール をグローバルオプションでインストールします。
npm install -g gulp

C:\Users\username\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js
gulp@3.9.0 C:\Users\username\AppData\Roaming\npm\node_modules\gulp
├── pretty-hrtime@1.0.0
├── interpret@0.6.5
├── deprecated@0.0.1
├── archy@1.0.0
├── tildify@1.1.0 (os-homedir@1.0.1)
├── minimist@1.2.0
├── v8flags@2.0.10 (user-home@1.1.1)
├── chalk@1.1.1 (supports-color@2.0.0, escape-string-regexp@1.0.3, ansi-styles@2.1.0, strip-ansi@3.0.0, has-ansi@2.0.0)
├── semver@4.3.6
├── orchestrator@0.3.7 (sequencify@0.0.7, stream-consume@0.1.0, end-of-stream@0.1.5)
├── liftoff@2.1.0 (extend@2.0.1, rechoir@0.6.2, flagged-respawn@0.3.1, resolve@1.1.6, findup-sync@0.2.1)
├── gulp-util@3.0.6 (array-differ@1.0.0, array-uniq@1.0.2, lodash._reevaluate@3.0.0, lodash._reescape@3.0.0, beeper@1.1.0, object-assign@3.0.0,  lodash._reinterpolate@3.0.0, replace-ext@0.0.1, vinyl@0.5.1,lodash.template@3.6.2, through2@2.0.0, multipipe@0.1.2, dateformat@1.0.11)
└── vinyl-fs@0.3.13 (graceful-fs@3.0.8, strip-bom@1.0.0, defaults@1.0.2, vinyl@0.4.6, mkdirp@0.5.1, through2@0.6.5, glob-stream@3.1.18, glob-watcher@0.0.6)

任意のディレクトリに再度gulpモジュールをインストールします。
これは、グローバルでインストールした gulp がローカルインストールの gulp を実行する役割に使われるためです。
プロジェクトによって gulp のバージョンを合わせることなくタスクを実行できます。
npm install gulp

また、以下のようなオプションでインストールすると package.json で管理できるようになります。
これは、プロジェクトメンバ間でパッケージモジュールそのものを管理するのではなく、package.json を基にして、その都度インストールするときに便利です。
npm install --save-dev gulp

バージョンを確認します。
gulp -v
[23:05:23] CLI version 3.9.0
[23:05:23] Local version 3.9.0

次に gulpfile.js というファイル名で gulp の設定ファイルを作成します。

'use strict'
var gulp = require('gulp');
 
// 監視タスク
gulp.task('watch', function () {
    gulp.watch('*', function (event) {
        console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
    });
});
 
// デフォルトタスクとしてwatch
gulp.task('default', function () {
    gulp.run('watch');
});

では、gulpを動作させます。コマンドは次のようにシンプルです。
gulp

[23:15:09] Using gulpfile C:\xxx\Gulp_Test\gulpfile.js
[23:15:09] Starting 'default'...
gulp.run() has been deprecated. Use task dependencies or gulp.watch task triggering instead.
[23:15:09] Starting 'watch'...
[23:15:10] Finished 'watch' after 12 ms
[23:15:10] Finished 'default' after 21 ms
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント.txt was added, running tasks...
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント (2).txt was added, running tasks...
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント (2).txt was deleted, running tasks...
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント (3).txt was renamed, running tasks...
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント (3).txt was deleted, running tasks...
^Cバッチ ジョブを終了しますか (Y/N)? y

任意のディレクトリ配下のファイル変更を監視し、変化があればコンソールにメッセージを表示します。
gulpコマンド実行後、いろいろなファイルを作成して試してみてください。

以上のような特性を利用して、テストランナーを走らせたり、ビルドタスクを実行したりするわけです。

2015年8月31日月曜日

Dockerのデータのポータブル化

Dockerコンテナの永続化についてです。
本来、ポータビリティの高い、あるいは、ポータブル化が主目的であるはずのコンテナでいかに永続化するのか、ある種のパターン化したソリューションの紹介です。

たとえば、MySQLをコンテナとして起動します。コンテナを stop させれば、当然ながら蓄積されたレコードは跡形もなく消えてしまいます。
そこで、よく用いられる手法が、データをホストのディレクトリにマウントする方法。

sudo docker run --name=mysql-data -d -v /opt/data/mysql:/var/lib/mysql foobar/mysql:latest

ボリュームオプションにより、ホストの /opt/data/mysql/ に記録しようと企てています。
しかし、この方法だとコンテナ自体のポータビリティが損なわれ、ほかのホストへの移植に際して考えなければならないことが増えてしまいます。
当然ながら、開発環境とテスト、本番などの差異を吸収するのが困難になります。

そこで、MySQLコンテナとは別にデータを永続化するコンテナを作成する方法をとってみます。
Dockerfileを作成します。
今回は最小限の構成で作成されている公式のイメージ busybox を使用します。

FROM busybox
VOLUME /opt
CMD /bin/sh

このDockerfileをビルドします。
$ sudo docker build -t foobar/mysql-storage:1.0 /opt/data/mysql

完了したら sudo docker images で確認します。

次に永続化用データコンテナを起動します。
$ sudo docker run -i -t -v /opt --name mysql-data busybox /bin/sh

ボリュームオプションで /opt以下を格納するコンテナになります。

では、このコンテナを使う側から見ます。
$ sudo docker run -t -i --volumes-from mysql-data mysql /bin/bash
--volumes-fromで件のコンテナのディレクトリを参照して起動します。これで件のコンテナとつながりました。

/opt 以下が接続されたのか確認します。
/# ls -al /opt/

本来のマイクロサービス、あるいは、一定の粒度をもったSOAアーキテクチャの設計パターンでは、このような Dockerソリューションの隔離されたうま味を十分に生かせるような発想が重要になってくるはずです。

2015年8月29日土曜日

Expressであえて静的なファイルを生成してみる

たとえば、以下の2種類のJade定義を用意します。

1) base.jade:

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

2) extend.jade:

extends base

block content
  h1= title
  p Welcome to #{title}

これは、2)のHTML出力用に定義した extend.jade をテンプレートとして、これから HTML を生成しようと思います。
しかし、上記には構造上のちょっとした工夫があって、extend.jade は、1)の base.jade を継承しています。
具体的には、おおまかなレイアウトは base.jade が担い、body の部分を extend.jade に差し替えています。
それが、block content という記述です。

さらに、Nodeのほうでは、HTML をレンダリングするのではなく静的な HTML ファイルを物理的に生成しようと思います。
それが次のコードです。

まずは、ルーティングの部分にRESTのPostリクエストを、app.js に記述します。
var output = require('./routes/output')
app.use('/output/:param', output);

次に処理の部分を output.js に記述します。
var express = require('express');
var router = express.Router();

var jade = require('jade'),
    fs = require('fs');

/* POST listing. */
router.post('/', function (req, res) {

  // 事前条件は省略 ・・・

    fs.readFile('./views/extend.jade', 'utf8', function (err, source) {
        if (err) throw err;
        console.log(source);
        var opts = {
            pretty: true, filename: './views/base.jade'
        };
        var template = jade.compile(source, opts);
        html = template(body);
        fs.writeFile('./public/test_file.html', html);
    });

  // レスポンス処理は省略 ・・・
});

module.exports = router;


通常、このようなコードを書くことはないと思いますが、実験です。あえて静的なHTMLをレンダリングするのではなく実体を出力します。
ポイントは、jade.compile() の第2引数として与える opts のパラメータに jadeの継承元のファイルを指定してあります。

では、POSTでリクエストします。URLはこんな感じです。当然 JSONプロトコルです。
http://XXX.XXX.XXX.XXX:YYYY/output/param

そして body はこんな感じ。
{
  "title": "test_parameter"
}

生成された HTML ファイルは以下のようになります。
<!DOCTYPE html>
<html>
  <head>
    <title>test_parameter</title>
    <link rel="stylesheet" href="/stylesheets/style.css">
  </head>
  <body>
    <h1>test_parameter</h1>
    <p>Welcome to test_parameter</p>
  </body>
</html>

という検証結果でした。
今回はノンブロッキングIOに関する考察は省略しましたが、この部分は注意してください。

2015年8月27日木曜日

Buzz

BuzzFeedが今冬にも、いよいよ日本にも上陸します。
政治経済からサイエンス、芸能まで幅広く、そして名前のとおりBuzzっているニュースが日本のユーザにはかなりアピールするのでは?と予想しています。
Googleの検索系とは違うバイラルメディアに中毒状態になる人も続出するかもしれません。

ここでバイラルメディアに関して簡単に書いておくと、Web流入を目指したSEO対策などの検索コントロールとは違う、いわゆるソーシャル系の拡散情報が集約されるメディアです。
簡単に言ってしまえば、いわゆるまとめ記事的なものです。
もちろん、有益なものも多いと思いますが、そのほとんどがBuzzったゴシップ記事かもしれません。
ニュースの形式もどんどん新しくなっていきます。そしてカバーする枠組みもどんどん拡大していくのかもしれません。
私たちは、その情報の洪水の真っ只中で、溺れていくのでしょうか。

2015年8月26日水曜日

積極的に「できない」と言う感性

「XXXなはず。」
「XXXXは、ここでは有り得ないこと。」

上記のセンテンスは、一日に何度も聞く言葉です。
これらは、常に根拠なき推測に基づいた表現手段です。
メカニズムというのは感情や理性を持っていませんから、このような判断をすべきではありません。
言ってしまえば、これらは性善説に基づいた単なる願望に過ぎません。
私たちの仕事はいかなる状況においても常にロジックで判断をして、裏付けをとり、根拠を明確にしないとならないのです。

「できないこともないけど…」
これも何度となく耳にする発言です。
バリエーションとして
「できないこともないけど、工数が足りない。」
「できないこともないけど、人が足りない。」 などがあります。

これらも似たような構造で、きっとできるはずという願望が見え隠れしていて、根拠が示されていません。
根拠には次の2つの特性が含まれます。
ひとつには、過去の経験から得た知見に照らし合わせて、どのくらいで解決できるだろううか? あるいは、解決が可能であるか? という視点。
ふたつめは、自分の経験に参照することができずに一定の調査や学習が必要だと判断できる視点です。

とくにふたつめの視点は大切です。
常に一定の解決手段でものごとを進められるほど、仕事は単純ではありませんし、安定稼働や合理性という観点を損なうわけにもいかないからです。
したがって、エンジニアとして純粋無垢である姿勢が問われるのです。言ってみれば、これは伸びしろでもあります。

「できない」と「やるべきでない」がクロスオーバーしたときに、きっと重要なポリシーを発見できるのではないかと思うのです。

2015年8月25日火曜日

サンプル実装

プロトタイプを作る。と読み替えてもらってもよいです。
よく機能の検証や、画面の動きや連携などでサンプルを作成する機会があると思います。
このときに、どのように作るでしょうか?
どうせサンプルなのでという考えで、ざっくりと画面直下やビハインドコードに押し込めてしまったりしていませんか?
この方法だと結局作り直すことになってしまいます。その作り直し方も切り貼りが中心になり、データのハンドリングで苦労して、結局時間を浪費することになってしまう可能性が高いです。もっと悪いことに偶然動いてしまい、深刻なバグの表出の発見が遅れてしまうことにもなりかねません。

サンプル実装とは言え、手を抜くべきではないです。
したがってあえてプロトタイプと読み替えても構わないということを書きました。
実はサンプルだからこそ、しっかりと検証すべきなのです。ここでいう検証はアーキテクチャや設計、パターン、抽象化、データの表現、通信などが含まれます。
つまりシステムに関するほとんどの現象がこのときに確認されるべきなのです。
しっかり作りこんでしまったら本番と変わりなくなってしまうではないか? という意見も当然ながら出てくると思います。
ここで検証すべき本質はデータのハンドリングの妥当性、アーキテクチャのバランス、また、とくに通信系は本当に接続が可能なのか?という点について入念に検証すべきです。

ここまできて気がついた方は多いかもしれませんが、サンプル実装(プロトタイプ)は、ほとんど本番です。プロトタイプで幾十にも検証されて本番に発展してゆくのです。ここで検証の状態や意図した設計がよくなければほかの手段を検討することになります。
このプロセスの段階で再検討は許容範囲です。この段階でしっかり根拠をつかむことなく、いい加減な状態で本番実装に入ると、ある程度実装が進んだ段階で問題が発露します。
これは、いわゆる手遅れの状態です。
ここで本来の姿に戻すには、結局ごまかすか、作り直すか、の選択になると思います。

結局、プロトタイプの考え方が生産性や安定性に大きな影響を与えるのです。

よく、こんなことを聞きませんか?
「これで、きっと出来るはず。」
これは根拠のない、ただの願望です。

2015年8月24日月曜日

Bootstrap 4 alpha リリース

オープンソースのCSSフレームワークである Bootstrap の最新版 Bootstrap 4 alpha がリリースされました。
JavaScriptプラグインを全てECMAScript 6仕様でリライトする変更が加えられています。

Bootstrap 公式ブログ

メタ言語の採用は、LESSからSassに移行しました。
グリッドシステムは、12列のレイアウトに基づいて、複数の層、各メディアクエリ範囲のいずれかを有していますが、従来の4種類の表示調整(xs、sm、 md、lg)に加えて、480px以下のスクリーンに対応する xl が追加されました。

また、クロスブラウザのレンダリングのCSSリセットとして、Normalize.css を拡張し Reboot.scss に統合されました。

そして最も大きなトピックであろうと思われるのはIE8へのサポートを終了したことです。
つまり、レスポンシブデザインを実装するために重要なCSSメディアクエリをサポートしないIE8を切り捨てたことになります。
<meta> タグには可能な限り
<meta http-equiv="X-UA-Compatible" content="IE=edge">
と記述するか、あるいは、検討が必要です。

モバイルファーストのレスポンシブWebな方は要チェックです。


2015年8月22日土曜日

週休三日

ユニクロなどを展開するファーストリテイリングが10月から希望者を対象に週休三日を導入する、というニュースが、昨晩の深夜帯のNHKのニュースでも取り上げられていました。
週の労働時間は変えずに、5日の出勤を4日に圧縮する合理化策です。
個人的には歓迎すべきニュースで、この流れが加速してひとつのムーブメントにまで醸成されれば、日本も少しは幸せになるのでは、と淡い期待を寄せています。
実は、スポーツ用品などを扱うアルペンは1989年に既に週休三日を導入してます。ずいぶんと早い時期から労働時間の圧縮を実施していたのですね。
もう少し後になるとEPSONが製造現場での裁量制的な製造活動を実現しています。
一部ではありますが、日本もこのような流れの努力をしているのです。

とはいえ、基本的に我々日本人は働き過ぎだと思います。単なる働き過ぎではなく、働き過ぎに感覚が麻痺しているとさえ思います。とくに私たちの業界がその最たるものではないでしょうか。ここに改善の余地はないのでしょうか。
インターネット黎明期、私たちのような職種はやはり働きすぎでした。しかし、いまほど働いていなかったように思います。あれから、約20年。モノづくりの手法も考え方もツールもずいぶん合理的になったのにもかかわらず、いまのほうがずっと働き過ぎなのは不思議ではないですか?

どこに問題があるのでしょうか。

ひとつには、システムが複雑になり過ぎたというのはあると思います。工学的なシステムだけの話ではなく、社会も、サービスも、人も、複雑になり過ぎました。
それは加速度的な速さで拡大しているとさえ思います。
しかしながら、高効率な生産性を目指すプロジェクトもなかには存在します。反面、前時代的な大仰なモノ作りをするプロジェクトも存在します。
どちらが正しいか?という話ではありません。
ただ、幸福を追求する権利と、幸せを感じようとする感性を忘れないで欲しいと思うだけなのです。

2015年8月20日木曜日

Jadeを試す

今回はJadeを試してみます。
Jadeは、HTML を書くための軽量マークアップ言語であり、JavaScript テンプレートエンジンでもあります。
JadeはnodeのMVCスタックのViewの標準レンダラとして採用されている知名度の高いエンジンです。
その最大の特徴は記法にあります。

なんといっても、タグを閉じない。
class と id 属性の記法が CSS セレクタの記法と同じです。
ただし、注意点として インデントが必須 です。これは厳密です。4spaceでもTabでも構いません。必ず統一性を確保します。

では、nodeがインストールされている前提で、npmでjadeをインストールします。
今回は Windows でやってみます。

$ npm install -g jade
C:\Users\xxx\AppData\Roaming\npm\jade -> C:\Users\xxx\AppData\Roaming\npm\node_modules\jade\bin\jade.js
jade@1.11.0 C:\Users\xxx\AppData\Roaming\npm\node_modules\jade
├── character-parser@1.2.1
├── void-elements@2.0.1
├── commander@2.6.0
├── jstransformer@0.0.2 (is-promise@2.0.0, promise@6.1.0)
├── mkdirp@0.5.1 (minimist@0.0.8)
├── constantinople@3.0.2 (acorn@2.3.0)
├── with@4.0.3 (acorn@1.2.2, acorn-globals@1.0.5)
├── clean-css@3.3.9 (commander@2.8.1, source-map@0.4.4)
├── transformers@2.1.0 (promise@2.0.0, css@1.0.8, uglify-js@2.2.5)
└── uglify-js@2.4.24 (uglify-to-browserify@1.0.2, async@0.2.10, source-map@0.1.34, yargs@3.5.4)

以下のようなファイルを作ります。
index.jade

doctype html
html
  head
    meta(http-equiv="content-type",content="text/html; chaeset=utf-8")
    meta(name="description",content= "コンテンツ")
    meta(name="keywords",content= "キーワード群")
    meta(http-equiv="imagetoolbar",content="no")
    title Jadeのサンプル
  body
    h1 大見出しです
    h2 中見出しです
    p Jadeを試してみます。

htmlにコンパイルします。
$ jade index.jade

次のようなhtmlファイルが生成されます。

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; chaeset=utf-8">
    <meta name="description" content="コンテンツ">
    <meta name="keywords" content="キーワード群">
    <meta http-equiv="imagetoolbar" content="no">
    <title>Jadeのサンプル</title>
  </head>
  <body>
    <h1>大見出しです</h1>
    <h2>中見出しです</h2>
    <p>Jadeを試してみます。</p>
  </body>
</html>

どうでしょうか。
案外、簡単だったと思います。
ちょっとしたサンプルを作ろうとか、大量に静的なページを作るといったようなシーンに活躍すると思います。
nodeでMVC + RESTfulを達成するExpressionを使用するには必須です。

興味を持たれた方は、調べて深みにはまるのもいいでしょう。

2015年8月19日水曜日

仕事力

優れたエンジニアとはどのような人のことを言うのでしょうか?

スキルが高い人!

と一般的には思われている、あるいは、望まれているかもしれませんが、自身はこのような意見に積極的には賛成できません。
なぜなら、スキルだけではモノは作れないと思うからです。
誤解のないように書いておくと、ここで言うスキルとは教科書的な模範的スキルのことです。
次にでてくるのは

人間力?

人によっては政治力?

このあたりは要求は高いと思いますが、ちょっと視点がずれてくるような気もします。
では、スキル = 技術力 とひとまず仮定義して考えてみたいと思います。技術力は一朝一夕で当然身につくわけでもなく、まずいかなる分野においても準備が必要です。準備にもいろいろな種類があり、基礎的な範疇にまつわる技術素養がまず必要です。これは地道な努力の積み重ねにより堆積してゆく養分みたいなもので、この部分がしっかりしていれば、いろいろな展開に対して柔軟なアプローチが取れます。
当然、この部分に安住してしまうとどんどん考え方が古くなり、技術の進歩についていくのが難しくなってしまうというリスクはあります。このような現象に対する有効な手段が次のステップです。新しい技術や考え方の摂取です。もちろん、世の中の流れにのる、いわゆる時流や流行に敏感であるべきという種類のことではなく、日々、個々が課題として抱えている問題の半年先や1年後を、あるいは、もう少し先を見据える技術です。こちらのほうが準備と捉えるとわかりやすいと思います。
乗り越えどころというのは急にやってくるわけではなく予兆なり流れが必ずあります、これは個人個人で性格の異なる流れだと思います。この流れ、つまり ビジョンを持ち続けてどのように進んでいくか? という展望を思い描けることが重要なポイントでもあり、また 重要な技術力でもあるわけです。
このステップにまで突き進んでいくには、旺盛な知的好奇心とチャレンジ力が必要不可欠になります。とくに前者は感性に属する初動で柔軟に、かつ、いかに物ごとに感動し得るか? というような繊細さも必要ではないかと思います。

これらのことを、自身は 「仕事力」 と呼んでいます。

実は、仕事力を語るには、もうひとつ大事な視点があると考えているのですが、それはまた別の機会に書こうと思います。

2015年8月18日火曜日

喜びの瞬間を捉えよう

Googleを語った書籍の広告が、JRの車内にありました。
ここではあえてその内容には触れませんが、購買力をあげるなかなか興味深いコピーがならんでいます。
昨日のニュースでは、Googleの共同創業者でもありCEOのラリー・ペイジが新しい会社を起業し、その傘下にGoogleを置くという話題がありました。
Googleは巨大になり過ぎたのです。

さて、仕事は楽しいですか?
もしかしたら、大半の人が冗談じゃないと声を荒げるかもしれません。

では、コードを書くのは楽しいですか?
またもや、もうへとへとだよ。深夜帯も休日も返上してコードを書いていて楽しいわけがない。という声をあるかもしれません。
仮にある刹那を切り取ってみましょう。きっと生き生きとコードを書いている瞬間が必ずあるはずです。食事を摂るのもわずらわしいほどにタイピングの指の動きが止まらない瞬間があるかもしれません。もし、そのような瞬間に幸運にも出会えたら、あるいは、心当たりがあるならば、そのボルテージの高まりへのストーリーを想像してみてください。

また、このように捉えることも出来ます。
私たちは日々コードを書き続け、クラスを定義し、組み合わせ、そして走らせるわけです。もっとも緊張する瞬間ですが、想定どおりの動きを目の前で展開された瞬間は、きっと喜びに満ちているはずです。

2015年8月17日月曜日

MBA教材としての清掃サービス

新幹線の車内清掃サービスをご覧になったことがある方は、もしかすると案外多いのかもしれません。
いまや世界的にも注目されているこの仕事は、ハーバード大の経営大学院の教材としても取り扱われるほどです。
以前は、3K職場などと揶揄された時代もありました。
清掃の現場はカーテンで閉ざされ、クローズされた車内空間で戦闘が繰り広げられていました。これが、以前のメンタリティなのです。ところが、現在ではひとつの パフォーマンス として捉えることが可能なほどに、メカニカルで想像力溢れる作業効率を実現、かつ、追及して7分間の Show としてまとめられています。 この変化はどこから来たのでしょう?
米流に考えるならば、成果を上げれば報酬で評価し、あるいはその逆であれば罰則を強化する。ところが我が国の文化はまったく違ったようです。新幹線の車掌も、あるいはグリーンアテンダントも清掃スタッフも、お客様に見られることを意識したマインドセットを重視したそうです。これは、オープンであることの重要性だと思います。
しかしながら、ここまでの技術に昇華するには様々な紆余曲折があったことは容易に想像できます。ここにポイントが隠されてると思います。経営サイドや運営陣ではなく、現場から能動的に発信される改善案には必ず明確な根拠があることの重要性を、しっかりと受け止めるまでに成熟した文化が根付いたことの証だと思います。私たちもそこから学ぶべきことは少なくないはずです。

2015年8月6日木曜日

抽象的な工場の提案

ファクトリ(Abstract Factory)は極めて応用力の高い実装パターンです。
昨日にも書いたように、もし、if文の入れ子構造があまりにも深いのであればリファクタリングの兆候です。
同様にif文のコンビネーションの中で階層表現として扱われる問題は、結局は同じシリーズであるわけです。ただ、ほんの少しだけ条件が変わるだけなので、そういう場合は頭を冷やすなり、もう一歩引いた視点で俯瞰する必要があります。

これは決して難しい問題ではありません。
たとえば、ある車を生産する工場があったとします。その工場ではたったひとつの車種を生産します。しかしながらオプションの種類が多彩で、その都度生産条件を変更してやる必要があります。まさに if文で判定するわけです。
しかし、その方法ではおそらくすぐに限界がやってきて作業ミスが多発する問題は避けがたくなるだろうと思われます。
この問題をどのように回避したらよいでしょうか。

先にも書いたように、もし○○○であれば、XXXのオプションを追加するという考え方をやめてしまうのです。そして、そのパラダイムをXXXのオプションで○○○を実施するという方向にシフトします。

工場はいろいろな条件でモノを生産します。
条件が違うだけで、ベースになるものは同じです。つまり、生産物はシリーズであるわけです。であるならば、ベースになる部分をごく抽象的なインタフェースでルールのみを定義してやることにより、オプションで肉付けをすることが可能になります。
これがアブストラクト・ファクトリの基本的な考え方です。

2015年8月5日水曜日

実務に即したファクトリ実装

もし、○○○ならば、XXXをする。

これは極めてソフトウェア工学の中ではポピュラーなモノの考え方です。
常に通奏低音のように鳴り響き、まるで呪縛のように私たちを取り巻いている、ひとつの習慣として醸成されています。

今回はここを取り崩そうと考えています。

上の if文 の中でさらに条件を想定して、もし、△△△ならば、□□□をする。というような構造を考えてみます。いわゆる入れ子構造です。

ここまでを整理します。
すると以下のような構造が見えてくると思います。

if ○○○ {
     if  △△△ {
          □□□
     }
     else {
          XXX
     }
}
else {
     // 何もしない。
}

ここでは、3つの処理系が存在することがわかります。
さらに、もし、△△△ならば… という条件下でさらに入れ子になる構造… と考えたところで、うんざりしますね。そしてバグの不安に駆られます。このような構造が(そう、構造そのものなのです!)ソースコードの平面的な世界観の中で表現された場合、人間の頭の中ではどのくらいの階層まで把握、管理ができるでしょうか?

いいえ、このような発想は、おそらくナンセンスなのでしょう。
もっと、シンプルに整理、管理できないのか? ということに頭を使ったほうが、余程世のためなのだと思います。

皆さんであれば、どのような工夫をするでしょうか。

このように整理してみます。

if ○○○ {
     if  △△△ {
          □□□ Aの処理系
     }
     else {
          XXX  Bの処理系
     }
}
else {
     // 何もしない。Cの処理系
}

この構造を階層で表現せずに、バラバラにしてまずはコンテキストで表します。
(表現が冗長になるのためコンストラクタの記述は割愛します)

まずは、AとBの処置系
class ABClass implements IFactory {
     public void Execute() {
          if △△△ {
               // Aの処理をする。
          }
          else {
               // Bの処理をする。
          }
     }
}

次にCの処理系
class CClass implements IFactory {
     public void Execute() {
          // Cの処理をする。
     }
}

この段階でAとBの処理系をドライブする表現を記述します。

IFactory target = null;
if ○○○ {
     target = new ABClass();
     target.Execute():
}
else {
     target = new CClass();
     target.Execute():
}

if文の入れ子構造をひとつ減らすことができました。
ポイントは、もし、○○○ならば、XXXをする という考え方から脱却して、XXXという条件で○○○をする というように捉え直します。
いわゆるポリモフィズムの実務に即した応用です。

2015年7月28日火曜日

Test First ?

以前、テストに基づいて仕様を考えることを試してみた結果という観点での内容の文章を書きましたが、これはそれほど難しい考え方ではないということを皆さんも薄々気がついていることだと思います。
ただ、重厚長大な形式主義や単なる習慣が、こういった逆転の発想を打ち消してしまうのは少々もったいないようにも思います。

依然として、要件をまとめて、機能仕様を作成し、さらに詳細設計書まで落とし込んでやっと楽しい実装に入れるという流れも、そろそろ限界を迎えてるのではないかと、いや、とっくに限界なんだろうと考えるわけです。
なぜなら、プロジェクト後半にもなるとせっかく作成した先の成果物は、だんだんと現実から乖離してメンテナンスもままならず、役に立たなくなることがあまりにも多い。
最終的にはどうなるのか?というと、実装者の裁量にまかされるわけです。
本末転倒な話です。

さて、では、視点を変えてテスト項目から洗い出してゆくとどうなるのか?
結局は同じことなのです。
ユーザ視点になるとテストの項目で表され、開発者の視点で見ると仕様書になるわけです。
つまり、これは表裏一体。結局、同一、同じものを言っているわけです。
両者ともにウォーターフォールのV字型機構で対応して表され、インプットとアウトプットで対になるわけですから、ごく自然なことだと思います。

そのことのひとつの証明として何日間かかけてドメインを中心軸として、左右対称の形を描くユニットテスト、モックアップなどを取り上げてきたわけです。
いずれの思想も根底にあるのは、通常の習慣とは逆にモノゴトを観察する知恵なのです。

2015年7月27日月曜日

オニオンスライスのオートメーション

ふだん単体テストのオートメーションにあまりなじみのない方のために、少し具体的な話をしてみようと思います。
そして例によって具体例は先週の続きです。
以下のレコードをデータベースから取得して画面に表示するためのコンテキストをテストします。

<朝食>
     <食べたものリスト>
          <食べたもの>トースト</食べたもの>
          <食べたもの>ハムエッグ</食べたもの>
          <食べたもの>ひよこ豆とレタスとトマトのサラダ</食べたもの>
     </食べたものリスト>
     <飲み物>コーヒー</飲み物>
</朝食>

1)まずは、期待値を構成します。
listと飲み物はprivateスコープです。
var expected = new 朝食();

このオブジェクトはコンストラクタの中で次のように初期化されます。
this.list = new 食べたものリスト()
list.Add( new 食べたもの("トースト") );
list.Add( new 食べたもの("ハムエッグ") );
list.Add( new 食べたもの("ひよこ豆とレタスとトマトのサラダ") );
this.Set飲み物 ( "コーヒー" );

2) 次に被検クラスを起動して、返される値をキャッチします。
var target = ある朝に食べた朝食() ;
朝食 actual = target.Find();

3)最後に期待値と実測値が同じであるか判定します。
for ( 朝食 a : actual ) {
     for ( 朝食 e : expected ) {
          assertEquals( e.Get食べたもの, a.Get食べたもの );
          assertEquals( e.Get食べたもの, a.Get食べたもの );
          assertEquals( e.Get食べたもの, a.Get食べたもの );
     }
}
assertEquals( expected.Get飲み物, actual.Get飲み物 );

ここではじめてに期待したオブジェクトとデータベースから返却された実測値が同一であること、つまり、期待に沿ったものであるかを判定しています。
assertでかかれた比較がイコールで結ばれればテストは成功なので、グリーンシグナルとなるわけです。
ただし、正確に言うと、Listは投入された要素の順番が保証されないので、ここはもっと別の記述になるはずですが、テストの流れをシンプルにご紹介するために、あえてこのように書きましたことを注意してください。

こうやって見てみると意外と簡単ですね。
とは言え、このテストではデータベースに直接接続していますから、本来はもっと工夫が必要ですし、これでは不充分です。
加えて仕様が変化したときに、当然、このテストコードでは整合しなくなるわけですから、もっと柔軟な展開も頭の中に入れておかなければなりません。
と、いろいろ考えることは多々ありますが、それでも、この方法には価値あることが少なからずあると思います。
それを知るには実際的な体験が必要です。

よくテストコードのメンテナンスが大変だ、という意見も聞かれますが、それはテストとしての構造設計がうまくできていないことに原因があることが大半です。
変化に強い実装コードのノウハウは、そのままテストコードの柔軟性にも同じように展開できるはずです。平面的な構造設計だけでは、そもそも実装コードのメンテナンスもままなりません。ぜひ、このような視点に注意を払って挑戦してみてください。
そこではじめて単体テストのオートメーションの価値に気がつくと思います。

2015年7月24日金曜日

オニオンスライスの単体テスト

昨日はヘキサゴナル・アーキテクチャの紹介でした。
この実装パターンは実はモックアップの導入だけではなく、ほかの部分でも効果を発揮します。今回はそのことについて少し書こうと思いますが。

しかしながら、賛否両論の多いアイディアでもあります。

昨日、モックアップは本番実装の鏡影だということを書きましたが、ということは、ほぼ同じような特性を持ったエンティティクラスにも展開が可能だということが容易に推測できます。

それは、つまり、ユニットテストにおいてです。
たとえば、本番に使用するエンティティとして、昨日使用した 朝食クラス を使います。
このクラスはデータベースの検索結果を格納して、データベースのアクセスレイヤーを構成するモデル -> 上位のパーシステンス -> そして、画面直下のプレゼンテーション層までハンドリングされる、データの保持という役割をもったオブジェクトです。

それでは、プレゼンテーションの下層を位置づけるメソッドをテストすることを考えてみます。画面の背後で動作するこのコンテキストは、任意の朝食データを検索して返す というように動作するはずです。
このコンテキストの期待動作を確かめるにあたって、その正当性を判定するには、返されるはずの朝食オブジェクトの内容と同一のデータを保持するオブジェクトを期待値クラスとして定義すると思います。
これは、つまりユニットテストの期待値に相当します。データベースから返される実測値は、本番実装の朝食エンティティクラスのオブジェクトです。
この2つのオブジェクトが同一であれば… 同じ内容のデータを保持していて、AssertEqualで結ばれれば被検対象のコンテキストは正しく動作し、グリーンシグナルが点るはずです。

ここで気がついた方はするどいです。
被検対象のコンテキストを軸に(つまり、ここはドメインとなります)expected と actual はまったく同様のデータになる、という特性が得られます。
これがオニオンスライス、または ヘキサゴナル・アーキテクチャの特性でもあります。
ドメインは常に中心軸として捉えられ、その左右の線対称の部分に、expected のインプット(期待するデータ)と actual(実測結果)が配置され、同一の重量配分の元にバランスします。したがって、テストが成功したことを表します。
これがユニットテストにおける、ひとつの合理性とその実践アイディアです。

おそらく、なんて面倒な! と感じる方もいらっしゃるかもしれません。
そのために賛否両論が巻き起こるテーマとなり得るわけです。

このテクニックが現場の実装で成り立つのか? という議論は、少々本質を逸脱すると思いますので、それはまたの機会に。

2015年7月23日木曜日

朝食はオニオンスライス

今日は昨日の題材を使ってオニオンスライス・パターンを考えてみたいと思います。
オニオンスライスは後ほど説明するとして、目指すのはモックアップの作成です。
こんなことを想定してみます。

・明日までに任意の日に食べた朝食の内容を画面に表示するようなプレゼンが見たい。
・ただし、データベースがまだ構築されていない。
・しかしながらサンプル画面を作るのではなく、そのまま本番に流用できる精度が欲しい。
・なぜなら時間がないし、手戻りを生み出したくないから。

本当に勝手なものです。
この程度のことであれば、サクッと画面を作ってボタンか何かを押したタイミングで画面に情報が表示されるような「サンプル画面」の実装を作ってしまえるでしょう。
そこを、ほぼ同じような手軽さで、ある程度の構造を持ち、すぐに本番に流用できるようなメカニズムを考えてみましょう。
パラメータやデータベースのアクセスレイヤーは、今回の本質ではないので割愛します。
それでは、思い出す意味で、ボタンを押して画面に展開するデータは昨日提示したオブジェクトを使用します。

<朝食>
     <食べたものリスト>
          <食べたもの>トースト</食べたもの>
          <食べたもの>ハムエッグ</食べたもの>
          <食べたもの>ひよこ豆とレタスとトマトのサラダ</食べたもの>
     </食べたものリスト>
     <飲み物>コーヒー</飲み物>
</朝食>

こんな感じです。
このオブジェクトは本番用に使うとしてモックアップのデータオブジェクトのクラスを考えます。

class 朝食モックアップ extends 朝食 { … }
こんな感じです。
ついでに、朝食クラスはこんな風に定義します。

class 朝食 implements I朝食

モックアップは、本番用の朝食クラスを継承して同じ構成の朝食モックアップを定義します。
当然ながらコンストラクタはこのようになります。

public 朝食モックアップ() { super() }
つまり、実態は本番と同じということになります。
これを返却用のオブジェクトとして使用することにします。

次にビヘイビア(ふるまい)を表す検索用オブジェクトを考えてみます。
まず、本番用はこのようになります。

class ある朝に食べた朝食()  implements I食事 { … }

そして、こんな検索メソッドを持ちます。

public virtual I朝食 Find() { return 本来はデータベースから取り出すのだ! }

次にモックアップ用のビヘイビアを定義します。

class ある朝に食べた朝食モックアップ() extends ある朝に食べた朝食() { … }

本番用のビヘイビアを継承するわけです。
したがって、検索メソッドはオーバーライドされ、朝食を表すモックアップエンティティを返すように定義します。

public overrides I朝食 Find() {
     return new 朝食モックアップ()
}

この部分で、つまり、朝食モックアップのコンストラクタの中で、画面にプレゼン用として表示すべきデータを与えて初期化します。
ここまでで本番用とモックアップ用の2種類の検索メカニズムを定義しました。
2種類とはいえ、構造的にはまったく同様のことを表現しています。
これを比喩的なメタファーとして、オニオンスライスと言います。
または、ちょうど鏡を挟んで線対称として捉えることができることから、ヘキサゴナル・アーキテクチャと呼ばれたりもします。
本質は、モックアップは本番の鏡影として表します。

さて、最終段階として画面に結果として表示するコンテキスト(文脈)の部分を定義します。

class I朝食 朝食Repository(I食事 behavior) { … }

このコンテキストはこんな風に使います。
まずは、モックアップを使う場合。

var context = new 朝食Repository( new ある朝に食べた朝食モックアップ() );
var 結果 = context.Find();

これで、モックアップの朝食を表すエンティティが返されるので、それを使って画面に描きます。これで明日のプレゼンは乗り切ることができますね。
本番に切り替えるときは、以下のようになります。

var context = new 朝食Repository( new ある朝に食べた朝食() );
var 結果 = context.Find();

パラメータとして渡すビヘイビアを変更するだけです。
画面の中も変更する必要もないし、ビジネスロジックも変更する必要はありません。
そもそも本番とモックアップを分岐させる If DEBUG のようなロジックさえ存在しません。
コンテキスト、ビヘイビア、エンティティの構造に置き換えられてしまったのです。
このように大局的な視点でロジックを構造に置き換える作業は、データベースシステムだけではなく、制御などの分野でも有効です。
ぜひ、試してみてください。

2015年7月22日水曜日

朝食は頭の体操

いきなりですが、あなたの今朝の朝食を教えてください。

冒頭から不躾な質問で申し訳ありませんが、これをオブジェクトとして表してみましょう。
参考までに自身の今朝の朝食はこんなふうに表現してみます。

<朝食>
     <食べたものリスト>
          <食べたもの>トースト</食べたもの>
          <食べたもの>ハムエッグ</食べたもの>
          <食べたもの>ひよこ豆とレタスとトマトのサラダ</食べたもの>
     </食べたものリスト>
     <飲み物>コーヒー</飲み物>
</朝食>

簡単ですね。
当然ながら、個々のセンスや捉え方によって表現はいろいろあると思います。
もちろん、それでよいわけです。
ここで示した表現は、食べたもの という視点を集合で捉えて、すなわち、コレクションとして表してします。あえて何か特記するならそれだけです。

では、今度は、これをクラスに置き換えてみます。

class 朝食 { … }
これだけです。最小の構成です。

少し工夫を加えて汎用的にしてみます。

class 朝食 extends 食事 { … }

superクラスはこんな風に表してみます。

class 食事 implements I食事 { … }

こうすることによって昼食と夕食を表すことができますね。
もちろん、人によっては、上に提示した概念モデルに <時刻></時刻> のようなタイムスタンプを付与したり、<いつ></いつ> のような更なるオブジェクトの汎用表現を加えるかもしれません。もちろん、それもOKです。

今度は、もう少し視点を拡げてコンテキストを表現します。つまり、ふるまいの部分を与えます。たとえば、食べる、摂取する、という行為を概念モデルとして考えます。
こんな感じはどうでしょう?

class 食べるコンテキスト { … }

上記のクラスのコンストラクタで、さきほどの朝食クラスを生成してインジェクトします。

食べるコンテキスト c = new 食べるコンテキスト( new 朝食() );
c.Execute();

これにより、コンテキストに食事インタフェースの規約を実装したクラスを与えることにより、表現が汎用的になりました。

言ってみれば、これは頭の体操です。
いろいろなものをモデルに置き換えてみましょう。

毎朝の通勤ルート
今週末に観に行く予定の映画
今夏の長期的気象予想
などなど…

なんでもよいです。
ほんの少しの時間が出来たときにでも、頭の体操をしつつ柔軟な思考を持つべく練習をしましょう。

ポートフォリオマネージメント

システムやソフトウェアを作成するにあたり、最初にやるべきこととして要求の聞き取りがあると思います。お客様が目指したまだ形のないモノを作成するにあたり、この作業の実施はとても重要な期間でもあります。
この要求は、具体性と実現性を検証されて、やがて要件定義へと結実します。
この過程で私たちはいったいどんなことに注意をはらうでしょうか?
お客様の声に耳を傾け最大限聞き漏らすまいと努力をするでしょうか?
あるいは、なんとか抜けのない資料を作成するべく力を注ぐでしょうか?

どれも重要なことではありますが、固執すべきではありません。
ここで注意しなければならないのは形式ではなく「何か」を掬い上げるのにどのような仕事が効果を上げるのか? というざまざまな改善ポイントが隠されていることを積極的に察知することだと思います。

果たして、ビジネスがどこに向かおうとしているのか?

これは極めて重要な命題です。もちろん、これはプロダクト・オーナーの目的であるわけですが、私たちモノ作りに従事する立場からも大きな関心ごとであるはずです。なぜなら 「見通し」 が重要だからです。見通しとは、つまり、計画であり、もっと正確に言うならばライフサイクルを大きく決定づける動機でもあります。
これらの材料から、私たちは優先順位の提案をし、開発を段階的に進めていくことに一定の価値を見つけることが出来るかもしれません。
これは、きっと方向性のミクロな視点なのだと思います。

では、もっと大きな視点で、パースペクティブを示すことができる点があるとすれば
それは、きっと 何を作るか? ではく、何を解決するのか? もっと言ってしまえばどんな悩みを解決するのか? という観点に行き着くのだろうと思います。

2015年7月17日金曜日

エクセルの概念モデル

X軸とY軸の表現の集積は、誰にも直観的でわかりやすいものだと思います。
たまに、表現の枠組みを打開すべくセルを連結して、ひとつ下の階層を表してやることは誰にでも経験があることだろうと思います。
これは、つまり表の限界です。当然ながら表は二次元配列が基本なので、それよりも下の階層や、あるいは「Z軸」の要素を表そうと思えば、これは最早、表の限界を超えることになるでしょう。
しかし、我々エンジニアはエクセルを単なる表として捉えるのは少々乱暴すぎると思います。
もう少し本質に迫る必要がありそうに思えます。
では、表を分解して行の視点で捉えるとします。すると、行は1行のコレクションを表すことになります。

List<Row>
こんな感じです。

次に、行が保持する要素は? というと…

同じように List<Column> という表現になると思います。
これでセルの集合を表すことができました。

セルまで行き着いたところで、このセルがどのようにして表になり得るのか? を表します。

<Rows>
     <Row>
          <Columns>
               <Column>セルに格納するデータ</Column>
          </Columns>
     </Row>
</Rows>

ここまで到達すればオブジェクトに簡単にマッピングできますね。
つまり、これはノードとエレメント、親と子の関係でもあるわけです。
ここで思慮深く観察したいのは、あくまでも二次元配列のベクトルで捉えるのではなく、入れ子のイテレーションです。こうすることにより、より抽象度が高まることが実感できると思います。
良いデータ表現というのは、ノードの再帰的表現に他ならないのです。
もし、データの関連をオブジェクトで表そうと思えば、ルートノードは必ずひとつになるはずです。もし、そうならなかったならスコープを逸脱した設計になることがすぐにわかると思います。と、同時に人が頭脳で捉えられる臨界点を超えてしまうことにもなるでしょう。


2015年7月16日木曜日

テストエンジニア

残念なことに、我が国においてはテスト実施に従事する人は総じて地位が低く、エンジニアとして認識されない風潮さえ存在します。本来テストエンジニアとして高い能力を発揮する局面で、向上心や知識といった何ものにも代えがたい価値が削がれてしまっているのが現実だと言えます。
視点を変えて組織という単位で見てみると、こちらも同じような現象が起きていると言えます。評価や品質を考察するしくみが整備されていないために、必要な技術や経験知が整理されずに場当たり的に処理されているのが、また同じような現実だと言えます。
これらは、品質保証という観点から非常にかけ離れた遠い世界です。

ただ、この状況はあくまで私たちの所属する分野という世界での極端な例かもしれません。
では、産業という観点まで視座を拡げてみましょう。家電業界、自動車、重工業、交通、医療といった分野は、品質評価や信頼性評価、耐久試験などの知見がきちんと整備されています。おそらく、当たり前ではないかという感想が聞こえてくると思いますが、こと、ITの分野となるとやはりこの界隈での弱さを感じてしまう印象がぬぐえません。
これは、いったいどうしたことでしょうか?

ひとつには、私たちの分野はまだ歴史が浅いため、信頼性という高みにまでまだ熟成していないのかもしれません。
モノづくりは完成をもって完了というわけにはいきません。もっと言ってしまえば、世の中に出始めて、そこがスタート地点となるわけです。初期不良や使い勝手などが改善され、製品が熟成されていきます。
ここに重要なポイントが隠されています。
製品が熟成されるということは、つまり、生産ラインが改善され、作業手順が改善されます。常に振り返りながら、生産品質や作業品質を見直すのです。こうした地道な努力が安定した品質の製品を世の中に送り出す原動力となるのです。

ふたつめに文化の熟成があげられます。
見える化やQC、あるいはルールの強化、そして 作業者の自主的な改善活動。これらはすべて文化という地平に存在する事象だと思います。

こういった技術の裏側の部分(とは言え、これらもまぎれもない技術である)に目を向けてみるのも興味深いことだと思います。

2015年7月15日水曜日

問題意識とイノベーション

問題を解決するより、問題を察知するほうが遥かに難しい。
とはよく言われる言葉だが、
もっと正確に言ってしまえば、「問題を解決するより、問題を察知するほうが高い能力が必要だ。」と表すこともできると思う。
しかしながら、人は問題を察知する能力を潜在的に持っているようにも思う。このことをいかに表面に導出してやるか、あるいは、顕在化するように促すか? というのは個々やチームの特性に左右される部分が大きいようにも思う。

我が国は儒学の文化がしっかりと根付いているので、それはそれで素晴らしいことではあるけれど、上に示したナイーブな類の取り扱いがことさらに難しい。
人は誰でもいやな話は聞きたくないし、いやなことが起こりうることさえ目を背けてしまいがちだ。
もっと悪いことに、このような問題の発露は人間関係にも影響を及ぼす。

問題意識という言葉がある。
簡単な言葉だ。しかし、常にこのことを意識しながら仕事に取り組むには、かなりの集中力が必要だ。と同時に強い信念が必要だ。

少し視点を移動してみる。
イノベーションと言えば、誰でも耳を傾ける気にもなるし、画期的なことのようにも思えてくる。しかしこれは錯覚ではない。おろらくは正しい認識なのだと思う。
では、再び問題意識という言葉を持ち出してみる。とたんに気持ちが沈み重々しい雰囲気になってくるだろう。そして、これもおそらくは正しい認識なのだろう。
さて、両者を比較してみると実は目指している方向には大差がないことが見えてこないだろうか?
気持ちの持ちようなのだろうか?

自身はそれほど単純なものではないと考えている。

プロジェクトが死ぬとき

「とりあえず…」
この言葉が使われたときは、注意信号である。
とりあえず、仮の実装でもしておけばよいとでも言うのだろうか?
明確な方針が存在しないときに、この表現が使用される頻度が高くなる。マネージャクラスがこのような言い回しを多用する場合、十中八九、全体を把握するのが困難な状況に陥っている証拠である。それならまだしも、口癖にまで「昇華」している場合があるので、そうなったら改善するのは非常に困難だ。注意されたし。

ルールが明確でない。
ドキュメントの体裁から、保管場所、変更管理、エビデンス。
これらはビジネスの問題だ。軽く考えてはいけない。
にわか体質のチームは、まずこの問題を克服しなければ何も始まらないと考えてもよい。
わかればよいと言う人が少なからず存在するが、課題に直面しているであろう刹那だからわかることであり、半年後、一年後、あるいはまだ見ぬ人々がメンテナンスにあたることを想像したときに、今と同じように理解し得るだろうか?

誰が何をしているのかわからない。
誰が何を担当しているか?を把握していればよいのは管理者だけの「特権」ではない。
コードの競合は事前に察知したいと誰でも考えるし、実際に手がけた人に確認したいこともあるだろう。進捗管理と言いながらも言い値で見積もったグラフを描いているだけで、実際の状況を何ら反映していない不正確な代物だ。

コミュニケーション不足
ここまで来ると最早末期的症状を呈し始める。あちらこちらに問題が山積し、深く結びつき、絡みついた糸をほぐすのは困難だ。まして、実際に手を動かすメンバーが口を閉ざし始めると、どこにどんな問題があるのかさえ見えなくなる。
かなりの高確率で休日がつぶされるようになる段階だろう。

逆の見方をすれば、これらの事柄は貴重な経験になる。
経験した人でしかわからない重要な問題の息吹と戦いの歴史だ。
それにめげずに改善を続けよう。

2015年7月14日火曜日

MDD

マニュアル駆動開発。
もちろん造語である。そしてまだどこにも存在していないものと思われる。
以前から結合テストとシステムテストの中間的なドキュメント(もちろんテスト仕様になるわけだ)を先に作成して、その後に実装に入るということを何度か試している。
これは、案外 良好なスタイルだと思っていて、かなりの精度で見えない部分をあぶりだすことにも効果があるし、設計のブレを抑制することに一定の効果を上げることを確認している。

しかしながら、万全というわけにもいかないということも体験的にわかっている。
システムやソフトウェアの特性に左右される部分が大きいからだ。特性とは性格を表す内部特性ではなくビジネスゴールにおける特性だ。
リリースされる成果物はきまぐれで、時として根幹を揺るがすような強力な反乱部隊を送り込んでくることがある。つまり、外観的な視覚特性が明らかになったところで、夢を語りだす悪魔が身を潜めていることに注意しなければならないということだ。
「この機能は、ここをチェックしてこっちのボタンをクリックしたときのほうがいいなぁ。」
現代の実装はできるだけスコープを狭く、シナリオでクローズすることが望ましいとされる。そのような工夫が、この時点で仇となり一気に反乱を起こすということだ。
この時点で実装を見直さなければならないことが高確率で予想できるし、テストで確認した点がすべて無効となるわけだ。
このような問題に関する有効な回答を探していたところで、ふと思いついたのが冒頭の言葉である。

マニュアル、つまり「取扱説明書」をまず先に作る。

ふざけているだろうか?
もちろん効果も確認していないし、精度も測定していない。第一試してみたこともない。
しかし、目の前に取扱説明書が提示されたなら、具体的なイメージを余すところなく掴めるはずだ。これはエンドユーザのみならず我々作る側の人間も同じだと思う。
作るものの明確なゴールが見えたところで、もっと突っ込んだ話ができるのも大きな利点だと思う。

それは、セキュリティ、ポテンシャル、スケール、耐久性、拡張性 といった非機能要件である。

この部分を具体的に詰めるのはとても難しい。
プロジェクトによってはざっくり切り捨てなんてことも珍しくないだろう。
そのような中で最も効果が上がるのを期待しているのは

見積もりである。

2015年7月11日土曜日

ニューウェーブ

技術を習得すること自体、実はそれほど難しいことではありません。
ほんの少しのやる気と、根気があれば、年齢を問わず学び続けていくことは可能です。それに加えて体系立てた技術として習得することすら困難ではありません。
しかし、その技術を使って仕事をする以上、これは本質ではありません。

習得した技術をどのように生かしたらよいでしょう。
いろいろな技術には、向き不向きがあるのは当然で、どのようなバックグランドのもとにそのような技術が生まれてきたのか、を知ることは重要なことです。
ここを見誤ると、新しい技術を試してみたいがために大きな失敗を起こしてしまうことにもなりかねません。
しかし、だからと言って新しい技術の習得に及び腰になるのも、とても残念なことです。
技術の本質をつかみとるのは難しいことではありますが、ぜひとも、そういう視点を持ち続けて学んでほしいと思います。

このような背景の中で新しい技術に目を向けていくのは、技術者にとってとても刺激になる体験となると思います。

2015年7月10日金曜日

発行者と購読者

現代の実装は確実にスコープを狭めるという方向に向かっています。

この言葉に、ピンと来ない方は少し視点をずらして構造を観察してみることをお薦めします。コードの観察ではなく、構造の観察です。
pub-sub実装は、もしかしたら、おそろく気がつかないところでその恩恵を受けていると言ってもいいと思います。

たとえば、XAMLで画面を作成する場合、この種の作り方としては最も鋭角的なスタイルの実装になるかもしれません。ここではデータの流れをラッピングする形で覆い隠してしまいます。まるで細かいことに固執するなよと言わんばかりです。

たとえば、JavaScriptのMVVM系の一連のスタックは非常にしなやかにデータの流れを隠しています。ここにはアウトプットの「視点」は存在しません。と言ったら言い過ぎかもしれませんが、非常にうまくラッピングされてると言えます。

これらの構造は、GoFのカタログにある古典的なオブザーバー・パターンの思想がベースになっています。まさに先人たちの知恵の賜物です。
現代の要求は非常に複雑になっています。従来のような命令を発行してパラメータを渡す。命令の中はブラックボックスでやがて返却値として回答が返る。受け取った回答をたとえば画面に反映する。と言ったような一連の流れでは難しくなり過ぎています。
この難題を確実に解決するにはどのような工夫が効果を上げるでしょうか?

冒頭に示したようにスコープの分断が有効な手段であることを確認してみてください。
つまり、画面からの入力はパラメータとして処理のブラックボックスに渡します。ここで気を使うべきは、いかに正しい入力をブラックボックスに渡すか?という一点です。
何が返されるか? といったシナリオの終着点は最早存在しません。なぜならスコープの外だからです。
そしてもうひとつの視点が返却されたデータです。ここでは回答が取り出される部分がインプットにあたるという立場をとります。画面には、たとえば DataSource のようなインスタンスの参照を持ち、取り出された回答は DataSource にインプットします。考え方としては入力という視点です。画面にどのように反映されるのかは、ここでは注意を払いません。

画面の制御は極めて難しいものと言っていいと思います。その複雑さにおいて人が注意を払える限界点を超えたところでバグに汚染されてゆくのです。
したがって、私たちはその複雑さを軽減すべく、スコープを分断して注意を払うべき対象を狭めていくのが現代の工夫なのです。

2015年7月8日水曜日

恣意的なロギングの価値とは?

よく恣意的なログを見かけることがあります。
まるで粒度が揃っていなくて何に主眼を置いているのか理解に苦しむ類です。
さらに悪いことに、巷では通称エラーログと呼ばれたりもします。
果たしてこのようなログが役に立つのでしょうか。
エラーを抑え込んでログとして担保されているのであれば、論理的に障害など起こるはずがないと考えるのは、実は自然なことです。
システムやソフトウェアに何か予期しない障害が起きて、ログを調べることが多くあると思いますが、「なんでこんなにも役に立たない情報ばかり出力しているんだ!」と憤然とした経験を持っている方も多いと思います。

このような事象の原因は多くの場合ロギングポリシーを策定していないことが大半だと思われます。そのような状況で各実装の担当者に頼りきってしまえば、属人的なロギングコードが記述されるのは明らかです。チームプレーの場合は悲惨です。

そもそもログにはどんな情報を出力するのが有益でしょうか。
エラー時の内容を示す文言でしょうか。
果たして、エラーとは何を示すものなのでしょうか。
想定した値を得られず処理を中断してユーザにメッセージを導出するプロセスを考えてみた場合、概ねこのような現象をエラーとして取り扱うことが多いと思います。
ユーザ視点で立てばこのような考え方は間違いないと思います。では、ロギングの観点で考えてみた場合、これは果たして適切なのでしょうか。
たとえば、上記の想定で処理は中断されエラー・パスを通り、想定通りユーザにメッセージを通知しました。そして、ログにはそのような手続きの結果を文言として具体的な内容を出力しました。
このような充分想定されたパスを踏んだ手続きをログから読み取ったところで、どのような意味があるのでしょう。確かに、ユーザ向けにエラーとして処理されました。という証拠にはなるでしょう。
しかし、ログの重要性や有益性はもっと別なところにあるはずです。
想定しない制御が起こり、調べる段階でこのようなわかりきった記録を読んだところで、実際はほとんど役に立つことがありません。
なぜならば、客観性に乏しい記録に他ならないからです。
そうです。ロギングのポイントはシステム内のデータを客観的な視点で淡々と出力することが望ましいのです。
おそらくここが難しいポイントでもあるのだろうと思います。
開発者の視点でロギングコードを記述すると、つい当たり前のポイントに目がいかなくなります。障害というのは当たり前のデータの流れの中で起こるものなのです。その当たり前だろうと思っている材料を失うと、それは大きな損失に繋がります。

ぜひ、皆さんも自身のチームのロギングポリシーをいまいちど考察してみてください。

テストの終わりとは?

よくこんな相談を持ち掛けられます。
「どこでテストを終えればよいのか?」
「品質の可否はどこで見極めればよいのか?」

実は、これは見当違いな質問に思えます。
なぜならば、テストは極めて能動的な行為であるからです。
正確に言うならばテストに終わりはありません。理論的には、いつかは、どこかのポイントで終わりを迎えることになると思いますが、そこまでに到達するには天文学的なテストケースを導き出さないとならないでしょう。
もちろん、これは現実的ではありません。

では、最初の質問にあえて答えるとするならば、テストの終わりはどこにあるのでしょうか。
テストの終わりははじめに決めておくべきことなのです。
別の表現を借りるならば、この答えはテストの方針です。品質のスコープと着地点を明確にしておかなければ可否の判断などできないのです。

しかし、ある人は 「それでは、本当に品質をクリアしているのか判断できないではないか。」 と言うかもしれません。
合理的な根拠をもった指標を決めないと、こういう意見がでるのも当然だと思います。さらに言うならば、テストのモニターを怠っているからこその感覚だとも言えます。

もう一度言います。テストは極めて能動的な行為なので、テストをこなしさえすれば品質を稼げるという発想は止めるべきです。
システムやソフトウェアに完璧な状態などあり得ないのです。そのためにポイントを明確にした品質の観点や領域で少しでも指標に近づく努力に力を注ぐべきなのです。

2015年7月7日火曜日

あせるべからず…

仮に  Result オブジェクトで任意の情報(もちろん結果)をプレゼンテーションに返却することを仮定してみます。
Result オブジェクトにはフィールドとして ResultType を保持しているとします。その ResultType が取り得る値は、
Unknown: 初期値
Success: 成功
Failure: 失敗
と定義するとします。
さらに Result オブジェクトは、Results<IEntity> というパブリックアクセサを通じて、内部に保持する「結果」のコレクションにアクセスすることを定義します。
つまり、これらの情報によりプレゼンテーションでは、問い合わせの成功/失敗、そして得られた結果の集合を取得できるようになりました。

一見、理路整然とした構造のように見えます。
では、Aさんにプレゼンテーション層の実装をお願いして、Bさんにモデル層の実装をお願いすることにします。
例題として、蔵書管理の中から任意の作家に関する書籍のレコードの集合を取り出すことを考えてみます。
正常系として、想定した書籍のレコード群が取り出されるわけですが、当然ながら 0件以上  n件 というレコードの集合が取り出されることが考えられます。

では、まずプレゼンテーション担当のAさんの視点で捉えてみます。
たとえば、10件のレコードを取得することができました。ResultType = Success で結果は成功です。同様に1件のレコードのみを取得できました。これも成功です。ここまでは何も問題はありません。
次に0件のレコード、すなわち、検索の結果がマッチせずに結果が返されることを想定します。レコードが返されないので処理は失敗とみなし、ResultType = Failure と考えました。
同じシナリオを、今度はモデル層を担当するBさんの視点で捉えてみます。Bさんは何件のレコードを取得できようが結果は Success で定義できる、という考えをポリシーとして持っていました。つまり、結果0件であろうと、処理そのものを失敗しているわけではないので、ResultType には Success をセットしたのです。
ここに1件のバグが入り込みました。

この場合、どちらの実装が正しいのでしょうか?

答えは、どちらも正しいです。
そして、どちらも間違っています。

両者には、大局的な視点での実装方針を確認しあう 「ゆとり」 が、ほんの少しだけ欠けていたのです。

2015年7月4日土曜日

失敗の経験値

経験を積むとはいったいどういうことなのでしょうか。
たとえば、何かのプロジェクトに参画をしたことにより、それは経験につながるのでしょうか。
正確に言うと、経験を積むとは失敗を重ねるということに他なりません。
ただし、注意しなければならないのは、失敗を重ねることの字面をそのまま受け取ってはいけないということです。失敗は単なる失敗でしかないからです。
重要なのは、失敗の背後にはたくさんのヒントが隠れていることを認識することだと思います。
わかりやすく言えば、失敗の経験を基に成功が導き出されるのです。逆の言い方をすれば、つまり、失敗は成功の根拠になるのです。
成功を表すには根拠が必要です。その根拠とは失敗の裏返しです。
何かの仕事で成功を勝ち取ったとしましょう。しかし、その根拠を言い表すことが出来なければ単なる「まぐれ」です。失敗の理由すらそこから導き出すことはできません。
言い換えると、それは経験には至っていないと考えなければなりません。

もし、皆さんが現在従事しているプロジェクトがあるならば、その仕事を終えたときに、チームのメンバーとともに、ぜひとも反省会を開いてみてください。
そして出来るだけたくさんの失敗談を列挙してみてください。
その失敗はなぜ起こったのか? どこに原因があるのか? 必ず分析をしてみてください。
そこではじめて経験を積んだことになるのです。

2015年6月13日土曜日

1/1の配慮

たとえば、
あなたがずっと欲しかったものをやっと手に入れたことを想像してみましょう。
何でも構いません。出来れば幾分高額なものがよいでしょう。イメージしてみます。
喜び勇んでわくわくしながら帰宅したあなたは、その欲しかったものの使い心地を早速試してみます。
なるほど、あなたの見識眼は見事にその欲しかったものをぴたりと当てました。まるで、あなたの人生に光を照らす光明のような商品でした。
その使い心地をさらに確認すべくあなたは、いろいろと試してみることに余念がないことでしょう。
ところが、どうしたことか、そのものは暴走を始めてしまいました。思慮深いあなたはもう一度同じことを試してみます。するとどうでしょう。再び同じ現象が起こりました。確信を得るためにもう一度使い心地をゆっくりと振り返りながら試してみます。確実に再現することを、あなたは認識しました。
ここまでで、あなたの心は打ちひしがれてしまうことでしょう。長いこと欲しかった製品の不具合を発見してしまったのです。

さて、初期不良かもしれません。いずれにしてもあなたの想定を深く裏切られてしまったことに変わりはありません。まさに絶望を味わうことでしょう。
あなたは、この商品を作ったメーカーを許せるでしょうか。返品や交換には応じてくれることとは思いますが、あなたの期待は裏切られてしまったのです。

こういった現象は常に起きうることです。しかし、あなたは、このことを許せますか?
ユーザーは商品に対して常に希望を抱き、ときには夢を持つものです。しかし、この期待感はまれに裏切られる結果となることがあります。

今度は逆の立場をイメージしてみます。
あなたは、ソフトウェアのエンジニアです。
ユーザーの希望や夢を実現すべく、工夫に工夫を重ねて素晴らしいパフォーマンスを発揮する便利なソフトウェアを作り上げました。
そのソフトウェアをお客様に届けることを、出来るだけ具体的にイメージしてみてください。
お客様は使い心地をひとつひとつゆっくりと確認していきます。ひとつのイメージを想定しつつ、その結果を確認しながら、自分の希望が実現されている便利なソフトウェアに心躍る気持ちです。
ところが、ひとつのタイミングで結果が得られないという現象が起きました。お客様は疑問を持ちながらも、まだ消えていない希望の気持ちを維持しつつ、もう一度同じことを試してみます。今度は結果が得られないばかりか、反応さえ失われました。いわゆるフリーズ状態です。ここまできてお客様は不具合の確信を得ました。

あなたの作ったソフトウェアに不具合が存在したのです。
ただの不具合ではありません。さきほどあなたが経験した幻滅や絶望を、楽しみにしていたお客様に与えてしまったのです。

このようなことは比較的簡単に起こり得ることです。
あなたは、このようなイメージを常に持ち続けているでしょうか。

このようなイメージ、想像力、配慮を持ち続けることはとても重要なことです。
モノづくりの分野でよく言われることは、大量生産の世界で歩留り95%を叩き出せればかなり効率が良いと言えます。しかし、お客様のもとに届く製品は常に1/1の100%であるはずです。
これはどういう意味を持つことなのか? ここに想像力たくましく配慮をすることは、実はとても重要なことなのです。