・各人がそれぞれ箱をもっている
・その箱は所有者しか覗き込めない
・その箱の中身を(空であっても構わない)、《カブトムシ》と呼ぶ
これは、ウィトゲンシュタインの有名な思考実験「Beatle in the box」です。
他人が《カブトムシ》と呼ぶものが何なのかは分かりませんし、そもそも存在しないかもしれません。互いに《カブトムシ》と呼び合うことで会話が成立しますが、具体的には何も共有されていません。
私的な体験の表現は、「覗けない箱の中の《カブトムシ》」と同じで、伝えること(あるいは、同一の感覚的体験をすること)の不可能性を示しているという解釈がなされています。
この思考実験の解釈は、もう少し“実社会”の側に引き寄せられるように思います。
実社会では、哲学の世界ほど用語の定義を厳密にしているわけではありませんので、私的体験のみが《カブトムシ》になるわけではありません。共通言語レベルでも《カブトムシ》が存在するのが現実です。
****************************************************************************************
《カブトムシ》の存在を認めることは、プロジェクトマネジメント上で大きなアドバンテージを得ます。
そこで、ロゴスウェアのシステム開発部のプロジェクトマネジメント手法の一部をご紹介しましょう。
1.身近な《カブトムシ》
例えば「ユーザ管理機能はありますか?」と尋ねられた時に、この思考実験を思い出す必要があります。
確かに私が開発したシステムには【ユーザ管理機能】があります。しかし、これがあなたの要求する『ユーザ管理機能』と同じである保証はどこにあるのでしょうか?
「“ユーザ”を“管理”するんだから、大して違いはないだろう」という判断が悲惨な事態を引き起こす事例は山ほど見つかるでしょう。“破綻プロジェクトとデスマーチの2択”に自ら邁進するようなものです。
もっと小さな例を挙げましょう。
「メールの返事はいつまでにしますか?」「急ぎじゃないからゆっくりでいいよ」「では、ちょっと後にします」という会話では、“メールの返信タイミング”という《カブトムシ》が同じものである可能性は限りなく低いでしょう。
“あなたと私の《カブトムシ》が同じ”であることをどの程度保証する必要があるのかは、『《カブトムシ》の誤差と損害の分析』に依存します。なんでもかんでも厳密にすればいいというものではありません。
しかし重要なのは、《カブトムシ》であるという認識を持っているということです。
例えば「1週間くらい後でいいよ」という合意には、“くらい”という《カブトムシ》がいます。
この《カブトムシ》は、今日は無視してもよいレベルですが、おそらく5日後にはもう1回連絡を取り合って期限を確認する必要があるでしょう。
《カブトムシ》であることを認識するということは、この事例のようにビジネスの基本でもあります。
2.《カブトムシ》は、どこまでいっても《カブトムシ》
一時期、手にしているプロジェクトで、上記のことばかり考えていたことがあります。
「あなたが考えている《カブトムシ》は、私の《カブトムシ》と同じでしょうか?」という質問は、互いに《カブトムシ》を往復させるだけの構造でしかありません。
いくつもの“特徴”を抜き出しても、その“特徴”のすべてが新しい《カブトムシ》になるというカオス構造そのものです。
そこで、私は「《カブトムシ》は永遠に《カブトムシ》」を受け入れて、マネジメントをしています。
チームのメンバーに「顧客に再確認してください」「いえ、すでに合意しています」「それでも“今”このタイミングで、再確認してください」を繰り返すのは、このマネジメント手法です。
3.《カブトムシ》に紐をつけておく
私たちは、PM(プロジェクト・マネジメント)の知識とツールとテクニックを習得します。PMの能力は、ある一定レベルのプロジェクト進行を確実に繰り返し実行できるもので、非常に有効です。
PMが利用するツールとテクニックは、顧客の要求を正しく把握し実行するためのものです。
“顧客の要望を把握することなどできない”を前提にしたら、それこそ話になりません。PMの勉強をしている間は“顧客を理解する”ことを学ぶべきです。
しかし、PMの能力を習得した後は、もう一度《カブトムシ》に思いを巡らす必要があります。
つまり「ここまでヒアリングしたこと・合意したことが、根本的には《カブトムシ》である」ことを忘れないということです。これは、上の例で“適切な時期に再確認する”という行動を導いたように、“適切なタイミングでステークホルダーと再確認する”という行動を導くということです。
「以前合意しましたよね」「そのような認識で合意したのではありません」という食い違いのケーススタディは、それこそ山のように存在します。多くの場合は、“最初の合意が甘かった”ので、“○○というツールを使いましょう”という結論になりがちです。
そもそも“最初の合意は《カブトムシ》”だと認識して、「再確認するタイミング」を設定したほうが、良い結果を生むのではないでしょうか。少なくとも、私たちロゴスウェアのシステム開発部では“最適なタイミングで再確認する”ことで多くのリスクを回避しています。このマネジメント方法を、私は「《カブトムシ》に紐をつけておく」と名付けています。
****************************************************************************************
PMBOKでは9つのナレッジエリアを定義しています。
「《カブトムシ》に紐をつけておく」手法は、直接的には、その中の“コミュニケーション管理”のツールになります。
“コミュニケーション管理”は、“合意の積み上げ”を前提にしています。確かに“変更”のプロセスは存在しますが、“《カブトムシ》を前提にした合意”を扱うことは想定していません。この意味で異端なツールかもしれませんが、私自身はあくまでPMBOKの中のツールに組み込んでいるという認識です。
以上、“コミュニケーション管理”をより現実に即して実行できるツールとして、私たちの手法をご紹介しました。
本日のLOGOSWAREチャンネルに出演しました谷中です。
→メルマガ
→放送の録画
放送では、「LWのテスト手法」として、
・シナリオテスト
・網羅テスト
を説明しました。
その中で、「ペルソナに対してシナリオを作成する」と述べました。
ロゴスウェアのテストとして最も重視しており、さらに継続的に進化させたい点ですので、補足します。
****************************************************************************************
「ペルソナ」とは、製品の顧客として想定する架空のユーザ像です。
私たちが考える“テストのあるべき姿”とは、「ペルソナ」を満足させられるかを評価することです。
一般的なテスト工程の管理ツールにあるような、“バグ発生件数と修正件数の成長曲線を見る”ような方法は採用していません。別の機会に紹介すると思いますが、「バグがなければ良い製品である」とは、根本的に思っていない・・・からです。
その代わりに、「ペルソナ-シナリオ」を重要視しています。
私は、「時間的余裕がないのに、大量のコンテンツを作成しなければならない担当者」を常に想定します。
このペルソナは、“何らかのエラーが画面に表示されたら絶望的な気分になる”ことは容易に想像できます。
このような絶望的な状況でペルソナが必要とするのは「懇切丁寧なエラーの説明」ではありません。「次に、何をすれば良いのか」を具体的に説明したメッセージです。
“バグ件数ゼロ”という基準では、「アラートが出たからOK」という判断になる可能性があります。
私たちが「ペルソナ-シナリオ」を重要視している理由はここにあります。
目に見える現象ではなく、その意味を検証するのが、私たちが採用している手法です。
****************************************************************************************
「ペルソナ」は、当初はその名の通り“架空”の存在です。
しかし、お客様の声を聞けば聞くほど、そのペルソナに反映されて、“実在性”が増すと考えています。
ロゴスウェアのテスト工程も「お客様に真摯に向き合う」に真正面から取り組んでいる点をご紹介させていただきました。
昨日のLOGOSWAREチャンネルに出演しました谷中です。
→メルマガ
→放送の録画
放送では、「顧客に真摯に向き合う」方法として、
・顧客の声を正しく受け止める
・顧客のビジネスを理解する
を説明しました。
その中で、「製品開発は仮説思考である」とサラッと述べました。
主旨から外れるので深く言及をしませんでしたが、ここで補足します。
****************************************************************************************
仮説思考とは、まず結論を仮定する考え方です。
「結論を仮定し(=仮説)」、その仮説に基づいて実行し、検証し、修正するという方法です。
対立するのは「積み上げ思考」です。
製品開発における仮説思考は、「顧客が求めているのは○○だ」から開始することになります。
積み上げ思考では、「顧客が求めていることをすべて調べ上げて、リスト化して・・・」ということになります。
仮説思考の最大のメリットは「スピード」です。
仮説思考では、“ただ1つの実行すること”を検討するので、消費した時間はすべて“実行すること”に注がれます。
一方、積み上げ思考では、99.9%実行しないものを延々と調査するわけですから、時間というコストが無駄になります。
製品開発においては、“スピードが命”ですから、仮説思考が最適な手法であることは言うまでもありません。
1.仮説思考と思いつきは違う
「顧客が求めているのは○○だ」だけでは、これは「思いつき」というものです。
思いつきで実行したのでは、積み上げ思考よりも悪い結果になります。
仮説思考には「仮説を補強する」というプロセスが必要です。このプロセスがないものは仮説とは言えません。
「顧客が求めているのは○○だ。なぜならば、○○だからだ。」の「なぜならば」が必要です。
2.「仮説思考に網羅性は不要」は誤解
たまにこの誤解を耳にすることがあります。この誤解を持ったまま製品開発をすると、やはり悪い結果になります。
「網羅性が何についてのものなのか?」を誤解してはいけません。
仮説思考は“結果を仮定”しますので、“ありとあらゆる結果の可能性を考える”という網羅性は、最初から切り捨てています。この意味では、“結果の網羅性は不要”というのは正しいです。
しかし、“仮説を補強する証拠集め、論理の組み立て”には、網羅性が必要です。さもないと、「思い込みを補強するような都合の良い証拠を集めて、都合よくつなげた理屈」になってしまいます。
仕様検討の会議に参加するメンバーは、ここを理解する必要があります。“仮説を立てる段階”では網羅性は不要です。時間を無駄にする害悪です。しかし、一旦仮説を立てたら、その仮説については網羅的に検討をする必要があります。
3.仮説思考は、検知システムである
実はこれが一番言いたかったことなのですが、正しく仮説思考で製品開発をすると、この思考プロセスが「検知システム」の役割を果たします。
「検知システム」とは、仮説の真偽を判定する仕組みです。精度が高い検知システムならば「仮説と現実が少し乖離しているかな?」を察知することができます。
1で述べたように、仮説には「なぜならば」が付随します。製品リリース後の“顧客の声”に、この「なぜならば」に該当するものが全く存在しなければ、“仮説を修正すべきである”という警報になります。
もし、「思いつき」で製品を作ってしまったら、この警報は鳴り響くことはありません。いつまでも「なんで売れないんだろう?」と首をひねっていることになります。
2で述べたように、仮説には「網羅的な証拠、論理」が付随します。製品リリース後の“顧客の声”の一言一句を丁寧に読むと、この「証拠と論理」に合致しているのかどうかが明白になります。ちょっとした顧客との会話の中でも、充分に確認ができます。「仮説の証拠」が詳細であり、網羅的であるほど“会議室では気づかなかったこと”がはっきりと見えてきます。これが精度が高い検知システムということです。
もし、恣意的な証拠集めしかしていなかったら、“自分たちが何について気づいていなかったのか”を知ることはないでしょう。
****************************************************************************************
私たちはベンチャーですので、絶対的なスピード感が最大の武器です。
大切なのは、“どこに時間をかけるのか?”です。
LWでは多くない社員数の中で、品質部門を作ったり顧客アンケートを実施したりなど、さまざまな品質に関する取り組みをしているのは、“品質には時間をかけるべきだ”と考えているからです。
私たちが、「顧客の声を正しく受け止める」「顧客のビジネスを理解する」を重要視しているのは、このような考えに基づいているものだとご理解をいただけたら幸いです。
私がXcodeを使っていてストレスが溜まる原因がキーバインド。普段からvimを使っているので、それはもう悩める日々です。
いつもの調子で dd とか yy とか、そんな感じですよ!
そのたびに、ストレスを感じ、円形脱毛症にでもなってしまうかのような、そんな日々ですよ!
そんな悩みを解決してくれるPluginを開発してくれた方がいます!
http://programming.jugglershu.net/softwares/xvim.html
素晴らしいの一言ですね!これでvim使いにも春が来ました!
前回は bash を利用して git の diff で差分のあるファイルを抽出するためのスクリプトを詳解しました。
今回は Subversion の diff での抽出方法を詳解します。ほとんど同じですが・・・。
#!/bin/bash
rm -rf ~/diff_file
echo "以下のファイルを作成しました"
cmd="`svn diff | grep \"^Index: \" | sed 's/^Index: //'`"
for file in $cmd
do
path=${file%/*}
mkdir -p ~/diff_file/${path}
cp $file ~/diff_file/$file
echo $file
done
前回の git 版と違う部分のみ説明します。
■ 4行目
grep "^Index:"
svn で diff を表示すると色々出てきますが、その中から grep で先頭が「Index:」で始まる行のみを抽出します。
その後「Index:」という文字はいらないので、
sed 's/^Index: //'
にて「Index:」を空文字で置換します。
すると、ファイルパスのみの文字列情報になります。
あとは、Gitの時と同じですね!
git の diff で差分のあるファイルをサーバーにアップロードするため抽出したい。ということがたまにあります。 私はMacを使っているのでbashでスクリプトを作りました。Windowsな方はMacを買ってください。ナンチャッテ。
#!/bin/bash
rm -rf ~/diff_file
echo "以下のファイルを作成しました"
cmd="`git diff --name-only $1 $2`"
for file in $cmd
do
path=${file%/*}
mkdir -p ~/diff_file/${path}
cp $file ~/diff_file/$file
echo $file
done
■ 全体の流れ
コマンドを実行するときに、.git のあるディレクトリに移動します。コマンドを実行するとホームディレクトリ下にdiff_fileというディレクトリを作成し、ファイルが格納されます。
■ 2行目
~/diff_file を削除します。
■ 4行目
次にgitのdiffコマンドを実行します。
git diff –name-only
とすることにより、差分のあるファイル名のみが出力されます。
$1、$2は引数です。例えば、–cachedや origin/master など引数を2つまで与えら得ます。
■ 5行目
for文の中では、ファイルのpathを取得し、~/diff_fileの中にディレクトリを作成し、その後ファイルをそのディレクトリにコピーすることを繰り返します。
■ 10行目
確認のため、作成したファイルを echo します。
簡単なスクリプトですが、アップロード対象が多い場合には助かりますね!
昨日のLOGOSWAREチャンネルに出演しました谷中です。
→メルマガ
→放送の録画
放送では
・「製品の価値はユーザーが決定する」を判断基準の根底として受け入れること
・すべての行動はこの基準の上に構築すること
を説明しました。
放送は、“お客様に対して我々が品質について約束する”という視点で話しました。
この主旨から外れるので触れなかった話題、特に開発者に訴えたい点について、述べたいと思います。
****************************************************************************************
私の好きな言葉・・・好きというレベルではなく・・・行動の規範とする言葉があります。
「ある人間の価値は、まず何よりも彼が自分自身からどれくらい解放されているかで決まる」
(アルベルト・アインシュタイン)
人間は感情の動物です。
反論されたり、批判されたり、ややもすると評価をされることすら、感情的に受け入れられなくなることがあります。
これは「自分自身から解放されていない」のです。
プログラマで言えば、「ソースレビュー」が耐えられないほどの苦痛であったり、自分のコードを修正されることがまるで自分の存在を否定されたかのように感じるなどが該当します。あるいは、テスト工程でのバグの指摘に過剰な防衛反応を示す(『パーフェクト・ソフトウェア』G.M.ワインバーグ)のも、同じ原理です。
“自分が書いたプログラム”を、自分とは無関係の“プログラム”として、客観的にかつ批判的に議論の俎上に載せることができるかどうか?
他者からの評価を、純粋にそのプログラムが良くなるためのアドバイスとして認識できるかどうか?(“受け入れる”のでは、まだ解放されていません)
まるで、最初からそこに存在していた“モノ”のように扱うことができるかどうか?
・・・それが“人間の価値”である、ということです。
そうは言っても、やはり人間には感情があります。ある種の名誉欲や自己顕示欲もあるでしょう。失敗を恐れる気持ちもあります。
「品質」に取り組む場合、どうしてもここが問題になります。
開発者は“素晴らしいもの”を作ろうとしています。そしてそこに多大な労力と知識と自己犠牲を払います。
その行動は、会社の文化としてとても価値があることですし、製品自体にストーリーを与えます。これは、素晴らしいことです。
しかし、一旦出来上がって手を離れたら、その製品から“解放”されなければなりません。
“自分がその製品に対してどれだけ尽くしたか”から“解放”されなければなりません。
「製品の価値はユーザーが決定する」というのは、このような意味も含んでいます。
今日のLOGOSWAREチャンネルに出演しました いしかわ です。お題は「とにかくやってみる」についてでした。
ロゴスウェアチャンネルの放送後記でもご紹介いただいています!
http://channel.logosware.com/archives/2165
「とにかくやってみる」とは何でしょうか。これ、なかなか難しいんですよね。ロゴスウェアでは以下のように定義しています。
いろんな場面で判断を迫られると思います。そして、断る理由はたくさんあるし、断っても誰も責めません。また、成功するかどうかもわかりません。そんな中で勇気を持って判断することはできるでしょうか。
ロゴスウェアには「インターネットや情報技術を使って学習に革命的進化をもたらすこと。そしてそれにより、育った環境や働く環境の差を乗り越えた学習機会の平等を実現させること」というミッションがあります。
私は判断を行なうとき、未来が分からないとしても、ミッションを達成する方向に向いていると確信できるのであれば、躊躇なく挑戦していきたいと思います。また、そのために日々、心のトレーニングを積み重ねていきたいと思います。
全く新しい、魅力的な製品を生み出すには、まずその第一歩として「不満に感じること」が必要だなとしみじみと感じます。
人間は環境に順応する能力が高いせいか、まず現状を受け入れて、その制約の中で行動しがちです。この結果、一本のライン上に乗っかったイノベーションは日々絶え間なく行われ、これはこれで人類に貢献しています。制約の中でこそ発展すると言う人もいますが、確かに真理ではあります。
しかし、私たちベンチャーは、現状から断絶した先の未来を創り出すこと、ビッグバンのように何もなかったところに驚くようなソリューションを出現させることに最大の喜びを感じるタイプの人間の集団ですので、”目の前の道がそのまま延びた先”には、あまり興味がないわけです・・・かなり言い過ぎましたが。
馬車を改良して多くの荷物を積めるようにしたり、車輪の回転を滑らかにすることには全く興味がなく、馬車道に突然F1マシンを登場させ、疾走させて周囲を驚かせることに無類の喜びを感じたりするのです。あまり良い例えではない気もしますが。
”現状の延長ではない何か”を考え出すには、”これじゃだめだ、もっといい方法があるはずだ”と感じる能力、不満の感度を100倍高めなければなりません。
これは素晴らしい、これでとても助かった、便利すぎて手放せない・・・というような製品は、たぶん、ぼんやりと「何かいいものないかな?」と考えていても出てこないのではないでしょうか。
自分が心の底から「こんなんじゃダメだ」「俺が世界を変えてやる」と思うような、そういう強烈な動機が必要で、これは、半分自己暗示に近いものかも知れませんが、自分で信じ込む必要があります。
一人ひとりだけでなく、会社全体がそういう雰囲気だったとしたら、私の理想とするベンチャーの姿になります。
ロゴスウェアでは、”誰かが感じた現状への不満”を積極的に共有したいと考えています。
「それはしょうがないじゃん」とか「今でも何とかなってるよ」とか、そういう周囲の反応は、生まれたてのイノベーションの卵をいきなり踏み潰すようなものです。
自戒の念も込めて思い直すとともに、自分が先頭切って”現状への不満”を探そうと思っています。
分かりにくかったので、メモ
■サンプル
(ZendFramework 1.11.11を使用)
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Docs');
Zend_Loader::loadClass('Zend_Gdata_Spreadsheets');
Zend_Loader::loadClass('Zend_Oauth_Token_Access');
Zend_Loader::loadClass('Zend_Oauth_Consumer');
// 2-legged oauth
$config = array(
'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
'version' => '1.0',
'signatureMethod' => 'HMAC-SHA1',
'consumerKey' => "yourdomain.com",
"consumerSecret" => "xxxxxxxxxxxxxxxxxxxx" // ※ドメインの秘密キー
);
$token = new Zend_Oauth_Token_Access();
$httpClient = $token->getHttpClient($config);
// Spreadシートの場合
$service = new Zend_Gdata_Spreadsheets($httpClient);
$spreadsheetKey = "xxxxxxxxxxxxxxxxxxxxxxx";
$sheet_id = "odx";
$query = new Zend_Gdata_Spreadsheets_ListQuery();
$query->setSpreadsheetKey($spreadsheetKey);
$query->setWorksheetId($sheet_id);
// ※この処理を追加する
$account = "you@yourdomain.com";
$query->setParam("xoauth_requestor_id", $account);
$listFeed = $service->getListFeed($query);
$list = array();
$rows = $listFeed->entries;
foreach ($rows as $row) {
// 行データ
$rowData = $row->getCustom();
}
?>
Tags: PHP, ZendFramework