2005 6 7 8 9 10 11 12
2006 1 2 3 4 5 6 7 8 9 10 11 12
2007 1 2 3 4 5 6 7 8 9 10 11 12
2008 1 2 3 4 5 6 7 8 9 10 11 12
2009 1 2 3 4 5 6 7 8 9 10 11 12
2010 1 2 3 4 5 6 7 8 9 10 11 12
2011 1 2 3 4 5 6 7 8 9 10 11 12
2012 1 2 3 4 5 6 7 8 9 10 11 12
2013 1 2 3 4 5 6 7 8 9 10 11 12
2014 1 2 3 4 5 6 7 8 9 10 11 12
2015 1 2 3 4 5 6 7 8 9 10 11 12
2016 1 2 3 4 5 6 7 8 9 10 11 12
2017 1 2 3 4 5 6 7 8 9 10

ホーム

2012年02月22日

ソフトウェア開発っていうのは新しいものを作るのが宿命づけ
られてるんですね。

ソフトウェアっていうのは使っても減らないし、コピーも安価
だし、一度手に入れてしまえば同じものを買いなおす必要という
のは原則的にはない。だから、買ってもらうためには新しい
何かを作らないといけない。

新しいものを作るっていうのは未知の領域に踏み込むっていう
ことで。未知の領域に踏み込めば転ぶこともある。

だとすると、新しいものを作るのが宿命づけられているのなら、
転ぶというのも宿命づけられていることになる。ソフトウェア
開発というのはよく転ぶものだということ。

なら、転ぶことを前提に進んでいくほうが利口というもので。

不意を突かれて転ぶと大抵は痛いもの。だから、不意を突かれ
ないために用心する。計画を立てたりとか、回帰テストを
やったりとか。

スピードを出しているときも転ぶと痛い。今のスピードが周囲の
状況と合っているか、本来やらなきゃいけないものを省いて
いないかということを確かめる。

ただ、転ばないように用心すると、どうしてもスピードが落ちる。
どのくらいのスピードがいいかは人によっても組織によっても
プロジェクトによっても違うでしょう。

でも、どんなに用心しても、転ぶときは転ぶ。まったく転ばない
というのであれば、それは未知の領域でなく、新しくなく、高く
売れるものじゃないということ。

転んでしまったらできるだけ早く起き上がる。でないと、状況は
ひどくなる一方。道で転んだままだと後ろから来た車に轢かれるし、
リングで転んだままだとタコ殴りにされる。

起き上がるというのは体勢を立て直すこと。傷を手当てして、
これからのことを決める。治すべきものがあれば治し、見直す
ものがあれば見直す。

当然、転ぶよりも前の段階、つまづく程度の段階で体勢を立て
直すほうがいい。だから、自分の体勢が今どうなっているかを
把握する。

--

「転ぶ」というのは「失敗」を言い換えたもの。XPでも失敗は
原則の1つになっているんだけど。

失敗が生まれるのは挑戦があったからなんですよね。逆にいうと、
絶対に失敗しない挑戦は挑戦ではない。

挑戦というのとリスクというのは語感としてずいぶん違う。
どちらも失敗がつきものなんだけど、挑戦には夢を感じるし、
リスクには感じない。

失敗が貴重だというなら、挑戦だって同じように貴重だし。

--

「碁は殴るか構えるか」王銘エン著、毎日コミュニケーションズ

メイエン九段の「ゾーンプレスパーク」は前にも紹介したことが
ありました。この本はその続編ともいえるものです。

碁を格闘技として捉え、着手を「殴る手」と「構える手」とに
大別して打ち進めようという話。ぶっちゃけ「殴る手」が
「プレス」で、「構える手」が「ゾーン」で、「ゾーンプレス
パーク」の焼き直しという側面もあるんですけど(笑)。

でも、「構え」という言葉を導入したのは、自分にとっては響き
ました。構えは防御であり殴るための準備でもあると。

この本、つい先日読み終わって、あれこれ考えていたんですけど、
ちょうど今日、toRubyの@track8さんが転ぶことについて
つぶやいていて。そのとき、「転ぶこと」と「構え」が自分の
中でつながったんですね。

まぁ、碁を打たない人に薦められる本でもないんで。

--

で、いわゆるウォーターフォールって、上段の構えなんですね。
防御を捨てて攻撃に賭ける構え。相手の変化に付き合わず、己の
攻撃を信じる。だから上段。まぁ、実際はスケジュールにバッファ
持たせたりするんでしょうけど。

一方、アジャイルは正眼の構え。防御と攻撃を両立させようと
する。相手の変化に対応し、防御と攻撃を素早く入れ替える。

いわゆるカウボーイスタイルっていうのは、構えのない構え。
ボクシングでいうとナジーム・ハメドみたいな天才肌。

本家Permlink


2012年02月20日

う〜ん。自分は、アジャイルが正しいとか正義とか
思ったことはないし、これからもそう思うことはない
かなぁ。

角谷さんの言葉の中でいうなら、やっぱり自然というのが
いいかな。自然というのは、つまり、ソフトウェアの
性質(nature)に沿ったものであるということ。

http://www.jitu.org/~tko/doc-jp/OverTheTukuru/07.html

まぁ、アジャイルでない、ガチガチなプロセスは自分には
できないっていうのもあるんだけど。それもまた、
アジャイルが自分に合っている、自分にとって自然だと
いうこで、合わなければ即不正義ということもないし。

それと、自然の反対は人工じゃなくて不自然だと思うん
だよね。プロセスなんてアジャイルを含めて人工のもの
なんだし。

--

そういえばnariさんも「正しいツールを探す」みたいな
ことを書いてたけど。こういうふうに何かの言葉(ここ
では「正しい」)が同じ時期に現れると、みんなが
それ(ここでは「正しさ」)を求めてるのかなぁとも
思うんだけど。

自分なんかは正しさとか正義とかには懐疑的なんだけどね。

本家Permlink


2012年02月04日

条件式の塊を1つのメソッドに切り出すというのは、よくやる
リファクタリングの1つなんだけど。

たとえばjavax.sound.midi.MidiSystem#isAppropriateDeviceも、
そうした条件メソッドの1つ:

    private static boolean isAppropriateDevice(MidiDevice device,
                                               Class deviceClass,
                                               boolean allowSynthesizer,
                                               boolean allowSequencer) {
        if (deviceClass.isInstance(device)) {
            // This clause is for deviceClass being either Synthesizer
            // or Sequencer.
            return true;
        } else {
            // Now the case that deviceClass is Transmitter or
            // Receiver. If neither allowSynthesizer nor allowSequencer is
            // true, we require device instances to be
            // neither Synthesizer nor Sequencer, since we only want
            // devices representing MIDI ports.
            // Otherwise, the respective type is accepted, too
            if ( (! (device instanceof Sequencer) &&
                  ! (device instanceof Synthesizer) ) ||
                 ((device instanceof Sequencer) && allowSequencer) ||
                 ((device instanceof Synthesizer) && allowSynthesizer)) {
                // And of cource, the device has to be able to provide
                // Receivers or Transmitters.
                if ((deviceClass == Receiver.class &&
                     device.getMaxReceivers() != 0) ||
                    (deviceClass == Transmitter.class &&
                     device.getMaxTransmitters() != 0)) {
                    return true;
                }
            }
        }
        return false;
    }

まぁ、コメントがゴチャゴチャうるさいので消しておくと:

    private static boolean isAppropriateDevice(MidiDevice device,
                                               Class deviceClass,
                                               boolean allowSynthesizer,
                                               boolean allowSequencer) {
        if (deviceClass.isInstance(device)) {
            return true;
        } else {
            if ( (! (device instanceof Sequencer) &&
                  ! (device instanceof Synthesizer) ) ||
                 ((device instanceof Sequencer) && allowSequencer) ||
                 ((device instanceof Synthesizer) && allowSynthesizer)) {
                if ((deviceClass == Receiver.class &&
                     device.getMaxReceivers() != 0) ||
                    (deviceClass == Transmitter.class &&
                     device.getMaxTransmitters() != 0)) {
                    return true;
                }
            }
        }
        return false;
    }

あ、ちなみに、この書き方、Javaの標準から外れてるんで、それも
直すと:

    private static boolean isAppropriateDevice(MidiDevice device,
                                               Class deviceClass,
                                               boolean allowSynthesizer,
                                               boolean allowSequencer) {
        if (deviceClass.isInstance(device)) {
            return true;
        } else {
            if ((!(device instanceof Sequencer)
                 && !(device instanceof Synthesizer))
                || ((device instanceof Sequencer) && allowSequencer)
                || ((device instanceof Synthesizer) && allowSynthesizer)) {
                if ((deviceClass == Receiver.class
                     && device.getMaxReceivers() != 0)
                    || (deviceClass == Transmitter.class
                        && device.getMaxTransmitters() != 0)) {
                    return true;
                }
            }
        }
        return false;
    }

まぁ、returnなのにelseでつなぐ人が多いんだけど、インデントが
深くなるだけコードのムダなので:

    private static boolean isAppropriateDevice(MidiDevice device,
                                               Class deviceClass,
                                               boolean allowSynthesizer,
                                               boolean allowSequencer) {
        if (deviceClass.isInstance(device)) {
            return true;
        }
        if ((!(device instanceof Sequencer)
             && !(device instanceof Synthesizer))
            || ((device instanceof Sequencer) && allowSequencer)
            || ((device instanceof Synthesizer) && allowSynthesizer)) {
            if ((deviceClass == Receiver.class
                 && device.getMaxReceivers() != 0)
                || (deviceClass == Transmitter.class
                    && device.getMaxTransmitters() != 0)) {
                return true;
            }
        }
        return false;
    }

で、これだけやってもまだよくわからんと。で、引数であるallowSynthesizerと
allowSequencerに注目する。これがfalseのときの挙動を
考えると:

    private static boolean isAppropriateDevice(MidiDevice device,
                                               Class deviceClass,
                                               boolean allowSynthesizer,
                                               boolean allowSequencer) {
        if (deviceClass.isInstance(device)) {
            return true;
        }
        if ((device instanceof Sequencer) && !allowSequencer) {
            return false;
        }
        if ((device instanceof Synthesizer) && !allowSynthesizer) {
            return false;
        }
        if ((!(device instanceof Sequencer)
             && !(device instanceof Synthesizer))
            || (device instanceof Sequencer)
            || (device instanceof Synthesizer)) {
            if ((deviceClass == Receiver.class
                 && device.getMaxReceivers() != 0)
                || (deviceClass == Transmitter.class
                    && device.getMaxTransmitters() != 0)) {
                return true;
            }
        }
        return false;
    }

こうすると、最後のダラダラと長いinstanceofの連なりがまったくの
無意味であることがわかったのでバッサリ消す:

    private static boolean isAppropriateDevice(MidiDevice device,
                                               Class deviceClass,
                                               boolean allowSynthesizer,
                                               boolean allowSequencer) {
        if (deviceClass.isInstance(device)) {
            return true;
        }
        if ((device instanceof Sequencer) && !allowSequencer) {
            return false;
        }
        if ((device instanceof Synthesizer) && !allowSynthesizer) {
            return false;
        }
        if ((deviceClass == Receiver.class
             && device.getMaxReceivers() != 0)
            || (deviceClass == Transmitter.class
                && device.getMaxTransmitters() != 0)) {
            return true;
        }
        return false;
    }

これで終わりにしてもいいんだけど、最後の条件式がまだ長いん
で、これもバラす:

    private static boolean isAppropriateDevice(MidiDevice device,
                                               Class deviceClass,
                                               boolean allowSynthesizer,
                                               boolean allowSequencer) {
        if (deviceClass.isInstance(device)) {
            return true;
        }
        if ((device instanceof Sequencer) && !allowSequencer) {
            return false;
        }
        if ((device instanceof Synthesizer) && !allowSynthesizer) {
            return false;
        }
        if (deviceClass == Receiver.class && device.getMaxReceivers() != 0) {
            return true;
        }
        if (deviceClass == Transmitter.class && device.getMaxTransmitters() != 0) {
            return true;
        }
        return false;
    }

この例では、「条件式の束をメソッドに切り出したところまでは
よかったけど、その切り出したメソッドの中身がゴチャゴチャ
していた」というわりとよくある光景を見た。

「素直に書く」というのはやっぱり間違いを生みやすい表現なので、
「バカ単純に書く」という表現のほうがいい。||や&&を巧みに
つなぎ合わせたほうが賢く見えるかもしれないけど、そんなことは
気にしない。バカに見えてもいいから単純に書く。

自分がよくいう「丁寧に書く」というのは、「バカ単純に書く」と
いうことも含まれていて。バカ単純なコードというのはサラっと読み
流せるもんだから、その凄みに気づかないことも多いんだけど、
手間をかけないとなかなかバカ単純にはならない。

本家Permlink


Copyright © 1905 tko at jitu.org

バカが征く on Rails