Code

2014年2月24日月曜日

アジャイル、新しい理解

 前から、アジャイル開発はいいなと思ってました。最近チーム内で実際やってみたら、いろいろ新しい理解ができました。まずは一つの図です:
http://findingmarblesdotcom.files.wordpress.com/2011/12/agile_mindset.jpg

 これは Retro の後、うちの Scrum Master がちょっと怒ったらしくて、みんなに送信したものです。なるほどと思われるところは赤いエリアです。アジャイルは完全に自由ではないです。自由すぎると、混乱にもなります。
 ソフトウェアへの変更依頼はなくならないです。以前から、何人かの先生から品質のいいソフトを作るために、まず全部の仕様をまとめて、決まって、開発に入ると聞きました。が、それは完全に間違っていると思います。変更依頼は本来ソフトウェアについたもので、それがないと、いいソフトが作れません。
 だから、人の弱みをカバーするために、顧客本当のニーズをわかるために、各 Sprint で成果物をみんなに見せて、変更しながら、よくして行きます。
 アジャイルを実施するためにはチーム内2以上のシニア開発者が必要だと思います。まず、一人ではみんなに行動を見せて、上達して行くのは大変です。自分の作業もあるから、手本を見せながら、やって行くのは大変です。二人いると、負担がかなり減ります。それに、まずチームメンバーになぜそうするか、どうしたら良いか、何でデザインパタンを使うかなど、いろいろ理解してもらう必要があります。次、見積もりのところ、必ずシニア開発者を混ぜて、みんな一緒に見積もりしましょう。そうでないと、見えない作業が発生したりしますので、また後で無理矢理詰め込んで、みんな疲れます。
 ソフトウェアは一般的な製品と違って、必ず人の手に頼りますから、その理解大切です。
 まぁ、いろいろ書きたいけど、具体的にどうやって行くかのプロセスを後日詳細を。
それでは。

2014年2月16日日曜日

CSS Tips 3: float, clear

 Web Page を作る際に、よく要素を横で並べたりするので、リストを使うと、通常縦並びになりますが、このとき、li に float: left をつけると、横並びに変わります。もちろん、li の width を注意しなければならない。一般的に親要素の 100% width を割り算して、設定します。例えば、三つ li の場合、width を 33.33333% に設定します。
 ですが、 float になった要素はポジションとして height が計算されないから、他の要素が上にかぶるとか、親要素が高さが足りないとか、そういうことがたびたび見かけます。
 このとき、親要素の height を設定しましょう。または li:first-child に float: none を設定して、位置とサイズをちゃんと与えましょう。自分の後ろの方法が好きですけど。
 clear: both も一つの方法です。ul の後ろに、div clear の要素を挿入することで、ちゃんと境界が作れいます。通常 div に内容がない場合、height と width がともに 0 ですので、見えないです。 clear : both というのは float の要素と別に、次のブロックを始まります。

それでは。

Spring Framework で Strategy パタン

 これから、私たちのシステムの Generalisation をしますが、なかなかやり方が決まらなくて、どうするかを考えてみました。一応メモをとっておきます。
 まず、事情を説明すると、現行システムは一つの顧客しか対応してなくて、顧客が増えるたびに、同じクラスで関係ありそうなところを if... else... や、 switch 文を入れたりして、分枝を作っていました。それが良くないことだとみんながわかっています。顧客が増えるたびに、すべてのソースコードをいじりますし、他の顧客を影響しないようにテストの負担も大きいです。それで、今回で、もう Unit テストや、 E2E テストをすべて一回整理して、システムの Refactoring をやろうと決めたのです。最初はコストのかかる仕事ですけど、将来の開発を考えると、やらざるえない選択だと思います。
 いろいろ考えた結果、今使っている Spring Framework をベースにして、DI を使います。最初は共通処理をインターフィースとスーパークラスに抽出します。 Eclipse の Refactoring 機能を使って、簡単にできるはずです。次、各顧客独自の仕様を抽出して、チャイルドクラスに移ります。そうすると、顧客の間は影響しないようになります。もし何か特別な市よりがあったら、顧客の実現クラスにスーパークラスのメソッドを override したら、問題ない。システムの構造も理想です。将来開発担当者を変わっても、他のプログラマーもすぐ何所でどのように修正するかはすぐにわかります。
 肝心なところはどのように対象クラスを選択して、処理を Delegate するかになります。一つの方法は Factory クラスを作って、顧客の名前を渡して、対象クラスを返すようになります。ただ、そうすると、顧客が増えるたび、Factory クラスをいじらなければならないです。前よりかなり進んでますが、もっと良い方法がないかと考えました。
 どうせ顧客の名前や ID に基づいて選択するから、マップを作って、そこから選択しようと。
 まず、各顧客のクラス Bean を定義します。
<bean id="Customer1Strategy" class=" xxx.xxx.Customer1StrategyImpl" />
<bean id="Customer2Strategy" class=" xxx.xxx.Customer2StrategyImpl" />
<bean id="Customer3Strategy" class=" xxx.xxx.Customer3StrategyImpl" />
 次、 Strategy マップを作ります。
<bean id="CustomerStrategies" class="xxx.xxx.CustomerStrategies" >
   <property name="strategies">
     <map>
       <entry>
         <key>
           "Custromer1"
         </key>
           <ref bean="Customer1Strategy" />
        </entry>
       <entry>
         <key>
           "Custromer2"
         </key>
           <ref bean="Customer2Strategy" />
        </entry>
       <entry>
         <key>
           "Custromer3"
         </key>
           <ref bean="Customer3Strategy" />
        </entry>
    </map>
  </property>
</bean>
 まぁ、その後は簡単です。CustomerStrategies をサービスに Inject して、サービスを呼び出すとき、顧客の ID をセットして、
ICustomerStrategy strategy = (ICustomerStrategy)customerStrategies.get(custmoerID);
を呼ぶと、顧客ごとのクラスが取得できるようになります。
 
 とりあえず、ここまで。それでは。

2014年2月8日土曜日

jQuery の Why & When

 先日変なコードが見たから、自分の心得をシェアしようと。
 Web App を開発するとき、DOM を操作する必要があるから、一つ悩ますことはブラウザの間に区別が結構あります。最近は良くなりましたけど、IE6、IE7 の時代はひどかったですね。特に MS はあまり W3C を準拠してなかったが、IE の市場シェアは 80% 以上にあって、変なウェブページがいっぱい作られました。そうすると、現在のモダルブラウザ (Chrome, Firefox, Safari, IE9, IE10 など) どうしても対応できなくなっています。それで Quirks モードが出て来て、 IE の Dev tool にモード、ドキュメントモードなど分けわからないメニューアイテムが追加されました。
 じゃ、何で jQuery を使うの?いつ jQuery を使うべきでしょうか?答えは主に左記のことですが、jQuery もいろいろ便利な機能があるから、みんな使っています。注意すべきところはライブラリを使うと、必ずコストが着いてきます。例えば、jQuery のコードがロードする時、ブラウザは1万行ぐらいの JavaScript コードを解釈し、実行する必要があります。大きいウェブページの場合、ロード時間を気になる場合、light jQuery というものもあります。例えば、zepto js. 自分の会社もjQuery が重いから、自前の light jQuery Like lib を作りました。
 まず、複数のブラウザを対応する場合、DOM の操作するとき、できるだけ jQuery を使いましょう。複数のブラウザは Cross-browser と言います。例えば、ウェブページに選択された文字列を取得したい場合、IE では createTextRange を使いますが、Chrome や Firefox にはその関数がありません。option を select に追加したい場合、IE では innterText を使えますが、Firefox にはその属性がありません。(なぜか Chrome にはあります。。。) jQuery の作者 John の話では DOM is a mess. それで jQuery のコードにこれらの区別をカバーするようなコードが結構あります。使うと決めたら、もう全部 jQuery を使うべきだと私は思います。createElement の速度は速いが、その速さはもう jQuery のロードで消耗したから、意味がありません。
 次は開発のスピードをあげるため、CSS の Selector をよく操作する場合、jQuery の関数を使いましょう。Native の JavaScript はそこが難しくて、jQuery の関数はそこをカバーしてくれました。後、CSS の Class name で要素を取得する場合、jQuery の selector も結構便利です。中にはモダルブラウザの querySelector, querySelectorAll が使われてますので、スピード的には速いです。
 後、スピードの要求がさほど高くない場合、jQuery のアニメーション機能や、Event 機能が便利ですので、使いましょう。

 あまり良くないことは Native の JavaScript コードと jQuery を混在して使うことだと、自分は思います。なぜなら、Native の JavaScript 関数は各ブラウザに通用するかは調べるには時間がかかりますし、コードを読むとき一貫性がないというか、メンテが大変だと思います。
 もう一つは、もし一つの要素を高い頻度で使うなら、全局の変数でキャッシュすべきです。なぜなら、 $(".abc") にはコストがあります。$ は実は一つの関数です。後、毎回それを実行すると、メモリー的にはあまり良くないです。
 
 まぁ、いろいろ書きましたけど、いいたいことは、開発前にもし Cross-browser となりましたら、jQuery が便利です。:)

2014年2月4日火曜日

Google の検索結果から URL をコピーするな

 最近、iOS の UIWebView で URL を開こうとすると、変な文字が後ろについちゃって、開けなくなりました。変な文字と言うのは %E2%80%8E です。ちょっと UTF-8 のコードを検索すると、Left-Right-Mark のようです。
 詳細をテスターに聞いたら、その URL は Google の検索結果から直接コピーしたものでそうです。試しに、google で何かを検索して、web inspector で HTML を見たら、URL の後ろに&lrm;というものがありました。それは Left-Right-Mark です。
 詳しくは wiki をご覧ください。アラビア文字などにはよく使われるそうです。試しに、自分もコピーしたら、そのマークはやはりコピーされます。 Sublime text などのテキストエディターで見てみると、そのマークが見えないですが、矢印キーではちゃんと一文字があることがわかります。
 今後、アドレスバーからコピーするようと伝えました。
 
 このとき、Notepad を気づいた:Windows の Notepad はすべてのマークなどはすべて削除されます。コピーした文字しか残らないです。
 :D やっと Notepad の使い道を見つかりました。

iOS7 WebView media query update

 今日、テスターがある変なバグを発見しました。それは、iOS 7 retina であるホームページのアイコンがずれました。
 もともt、background-size と background-position で sprite イメージをいろんなところにある小さいアイコンを表示していますが、その background-size が効かなくなって、background-position も正しく計算できないようになって、その現象が起きました。
 ただ、起きるところと起きないところがあって、どうしただろうなと思いました。詳しく見て、比較したら、css の書き方に問題があるような気がしていました。
 media query では、-webkit-device-pixel-ratio をチェックして、2 だったら、retina 用のイメージを background-image に再設定すべきですが、@2x のイメージをまた background-size でリサイズして、半分に変更して、また前の background-position が同じように使えます。
 問題あるところは background: url(../images/sprite@2x.png) no-repeat 0 0; となっていて、background-size はその前で設定していました。
 iOS6 以前だったら、background-image しか影響しないですが、 iOS7 だと、background の値がすべてリセットするそうです。そうすると、background-size が auto auto になり、リサイズが失敗します。
 直し方が簡単です、background の代わりに、background-image だけ設定して、他のものを触らないようにすれば、直ります。
 これは background というものは結構暗黙に設定する値があるので、明示的に各値を設定すべきだと思います。
    background -> background-color, background-image, background-repeat, background-position...

 ついてに、すべての背景イメージは sprite にすべきです。これはまた書きます。
 それでは。:)

2014年2月3日月曜日

CSS Tips 2: z-index

 複雑な Web App を作るときに、必ず overlay や、ダイアログなど、ある要素の上に他の要素を表示するケースが出てきます。このとき、CSS の z-index をよく使います。
 z-index は名前とおり、レイヤーを定義する属性です。例えば、z-index を 200 を指定すると、z-index の値がそれ以下の要素の上に、対象要素が表示されます。
 注意すべきところは z-index が position 属性と関係あります。いわば、 position が static 以外の要素しか z-index が効かないのです。
 position については前の記事をご参考ください。
 つまり、何で z-index が効かないと思ったら、要素の position を確認してから z-index を数字を確認すべきです。
 IE6 からこういう動きですので、現在のブラウザもその通りに動きます。知らないのはちょっと面倒なことになりますので、メモしておきます。

何で Auto test をやるか

 最近、隣の方になんで Auto test をやるかを聞かれました。。。今の時代はそれは主流だと答えましたが、いまいち彼がわかってないようですので、Test Driven Development からいろいろしゃべりました。
 テストって大事だと、どんなコードでもバグがあるとみんなはわかっているかもしれませんが、実はバグに関してかなり前から面白いエピソドがあります。
 コンピュターの原始時代、いくつかの天才より航空券のブッキングや、科学計算システムが作られました。これらのシステムは結構できてたそうです。(何十年前のことだから、実際使ったことがないから、聞いただけですが。でも、Linux のコードを読むとき、たまに天才がいるなと思いました。)その中、ある顧客が航空券を予約した時、本来人数を入力すべきところを大文字の”P”と間違って入れたそうでした。そうすると、システムが狂って、変な結果になりました。。。
 それから、みんな初めて使用者はエラーを起こすと気づいたそうです。それで、Validation などいろんなロジックをプログラムに追加されて、システム全体がめちゃくちゃ複雑になって行きました。もう一つは、コードが一人で書くものではないので、モジュール化しないと、機能がバラバラになると、もうメンテーできなくなるからです。
 また話を戻って、そのようなエラーとか、全数テストが不可能だから、境界値などのテスト理論が出てきました。人が一つ一つテストすると、時間がかかるし、大変だから、世の中のいいプログラマーはまたこれを軽減しようと、テスト専用のパッケージを作りました。JUnit とか、Jasmine とか、最近の Karmaや、Projector など、言語別、機能別のライブラリが結構出てきました。
 もう一つは Agile の普及より、Continuous Integration が常識になりつつあるから、一つのモジュールが何人か開発して、その後変更しつつ、テストしつつ、システムを完成して行きました。
 じゃ、何でアジャイルを使うかまた説明が必要になりましたけど。それは開発者の弱点が克服できないから、みんな協力して、一つの機能づつ、顧客とも確認しながら、前進して行くのはいい結果に結びつけるからです。
 それで、毎回の Sprint とか、毎回のリリースで、ある一人のテスターが全部テストをやり直すのは不可能ですので、Unit Test や、End to End テストのスクリプトによって、テストするのが速いし、バグもいちはやく発見できます。

 まぁ、ここまで話すと、多分もう理解するだろう。以前自分もあまり気づいてないことがあったりして、一応メモしとこう。

 それでは。