カテゴリー別アーカイブ: 未分類

書評 | Adaptive Code (C#実践開発手法 第2版) by @masaru_b_cl

監訳者の長沢智治氏(@tnagasawa)より献本御礼。

https://shop.nikkeibp.co.jp/front/commodity/0000/P53540/

本書は以前書評を書いた「C#実践開発手法」の第2版です。

新刊『Adaptive Code 〜 C#実践開発手法 第2版』 – 長沢智治のブログ
https://nagasawa.blog/entry/adaptive-code-second-edition-japanese

本書の特徴は何といっても「C#」がタイトルからなくなったことです。初版の書評で、私は次のように書きました。

「C#ならでは」というものも、それほど多くはないという印象でした。この点については少し残念でした。

しかし、本書ではC#かどうかは重要ではなく、いかに「適応力のある(≒Adaptive)」なコードを書くかに主眼があることがより明確になりました。これは非常に素晴らしいことです。

本エントリでは、初版から変わったところを中心に、私が思ったことを紹介します。

レガシーコード改善がより実践的に

本書は初版では一緒の章になっていた「テスト」と「リファクタリング」が別々の章になりました。これにより、元の「Adaptive」でないレガシーコードの改善の手順が、より実践的になりました。

特に良いと思ったのは、最初に「仕様化テスト」を用意するところです。しかも、テスティングフレームワークを使うのではなく、ただのコンソールアプリでよいという割り切りが素晴らしいです。

テスティングフレームワークを使うと、どうしても入出力ファイルの扱いで制約を受けて、うまくテストすることができないことがあります。それを、対象コードをそのまま動かすことで、とにかく変更前後の結果が同じかどうかを比較できるようにすることが、何よりも大事だというメッセージと受け取りました。

テストが手厚い

前述のように「テスト」と「リファクタリング」が分かれたことにより、「テスト」についてより包括的に書かれています。初版ではほぼ「ユニットテスト」しか扱っていませんでしたが、より大きなテストアンチパターン、「テスト駆動開発」と「テストファースト開発」の違いなど、かなり情報が増えており、とても良いと思いました。

Code ContractとUnity(DIコンテナの方)はちょっと……

初版から「契約による設計」を強制するツールとして第9章に「Code Contracts」が出てきます。ただ、正直最新のVSに対応していませんし、製品としても今はあまりメンテナンスされていない印象ですので、ちょっとなーと思いました。

また、Unityを使ったDI(依存性の注入)についても、今は「Unity」といったらゲーム開発ツールの方を先に思い浮かべてしまいますし、.NET Coreに標準でDIの仕組みが入ったこともあり、ちょっと古い感じはあります。


初版の書評でも述べた通り、本書は初心者がSOLID原則などを学ぶのにも適しています。タイトルからC#もなくなりましたし、他の言語を扱っている人にもぜひ読んでもらいたいと思います。

それでは、最後に恐らく間違いを見つけたので、そちらも紹介しておきます。

「第9章 リスコフの置換原則」のp.299 リスト9-30は、p.297の図9-6と見比べてみると、IEntityRepository<TEntity>の型引数にoutキーワードが足りません。おそらく正しくは、IEntityRepository<out TEntity>の間違いだと思います。

master以外でgit svn dcommitできなくする

!!! CAUTION !!!

このエントリはGit Advent Calendar 2014 – Qiitaではありません。

 

背景

訳あってセントラルリポジトリがSubversionだった場合、”当然”git-svnを使って開発を進めていきます。

そんなとき、たまに間違ってフィーチャーブランチ上でgit svn dcommitしてしまうことがあります。これをやってしまうとmasterをSVNと同期させるのが少し手間だったりします。

そこで、master以外ではgit svn dcommitできなくしてしまおうというのが、このエントリの趣旨です。

 

前準備

gitには当然コマンドをフックする仕組みがあります。しかし、標準のフック機構はgit-svnでは使えません。

そこで、まずは以下の「git-svn-hooks」を導入します。

rkitover/git-svn-hooks

導入手順がREADME.mdに書いてありますので、参考にして導入します。

なお、私の場合、次のような手順で入れました。

  1. ダウンロードしたgit-svn.shを~/binにコピー
  2. ~/.bashrcに次の記述を追加
    source ~/bin/git-svn.sh

 

フックスクリプトの作成

あとはgit svn dcommitをフックして、master以外のブランチでは警告メッセージを出すようにします。例えば、こんな感じの.git/hooks/pre-svn-dcommitファイルを作成します。


#!/bin/sh
WORKING_BRANCH=`git branch -l | grep "*" | cut -d " " -f 2`
if [ $WORKING_BRANCH != "master" ]
then
echo "WARNING: curret branch is NOT \"master\""
exit 1
fi
exit 0

view raw

pre-svn-dcommit

hosted with ❤ by GitHub

 

動作確認

任意のgit svn cloneしたリポジトリで、フィーチャーブランチを作ってgit svn dcommitすると、次のようにエラーになります。

$ git checkout -b some-feature
$ git svn dcommit
WARNING: curret branch is NOT "master"

これで安心してgit svn dcommitできますね!

実例で学ぶASP.NET 4.5 Webフォーム 新機能活用法:第3回と第4回が公開されています

ASP.NET 4.5の「モデルバインド」を活用する
ASP.NET 4.5の「モデル検証」を活用する

ご無沙汰していましたが、CodeZineで公開中です。

バックナンバーはこちら↓

実例で学ぶASP.NET 4.5 Webフォーム 新機能活用法:CodeZine(コードジン)

TDDしないケースについてのUncle Bobの考え

なごや方面のテストエンジニアの@kyon_mmさんが、こんなことを呟いていました。

で、紹介されていたのが、以下のエントリ。

The Pragmatics of TDD – The Clean Coder Blog

(※2019/1/16 エントリのURLが変わっていたので差し替え)

読んでみると、ボブおじさん(Uncle Bob)ことRobert C. MartinがTDDしないケースについて言及していて素晴らしいエントリでした。

ので、勝手訳してみます。(添削していただいた@liliputさんに感謝!)

Original blog entry is The Pragmatics of TDD

#The Pragmatics of TDD

#TDDの実例

So my last blog: The Startup Trap raised quite a ruckus. Amidst the various shouts of agreement and support, there was also a group who vehemently disagreed. I’m not going to summarize all their disagreements here, since I’ve already used up my quota of curse words for the month. But one of those disagreements struck me as something I should address.

前回のblog「スタートアップの罠」は物議を醸した。様々な同意や補助といった叫び声のど真ん中に、激しく異議を唱えるグループがいた。その意見をまとめることはしないけど、思いつく限りの汚い言葉を全部使いきっちゃったよ。でも、言及する価値があると思われる、とても面白い意見がひとつあった。

It’s the old argument of pragmatism vs. dogmatism. In essence, the complaint was that I was being too dogmatic. That TDD might be great in some cases, but in others it might have too high a cost. So you have to be pragmatic and choose wisely.

「実用主義」対「教条主義」のよくある議論だよ。まとめると「私が教条的すぎる」ということだそうだ。TDDはあらゆるケースで素晴らしいプロセスに違いないけど、高コストであるに違いない。だから、あんたは実用主義的になり賢明な選択をしなきゃならない。

At first this sounds perfectly reasonable. After all, pragmatism is a good thing, right? I mean, if you knew that TDD was going to make you miss your deadline; and that you could make the deadline by dropping it; you’d drop it, right?

一見するとこれは完全に理に適っているように聞こえる。結局のところ「実用主義は素晴らしい」、そうだろう?TDDでは締め切りを守れず、TDDをやめたら締め切りを守れるなら、TDDをやめる。違うかい?

Right. No question. And, in fact, there are times when that’s exactly the right course of action. The purpose of this blog is to lay out those times when I think TDD is too expensive.

そのとおり。疑問の余地はない。事実として、その一連の行動が正しいときはある。このblogの目的はTDDを使っても割に合わない場合を明確にすることにある。

But before I do I want to make a point. TDD is a discipline for programmers like double-entry bookkeeping is for accountants or sterile procedure is for surgeons. Are there times when accountants don’t use double-entry bookkeeping? Are there times when surgeons don’t use sterile procedure?

しかしその前に、言いたいことを言わせてもらおう。TDDは会計士にとっての複式簿記、外科医にとっての滅菌消毒と同じように、プログラマーにとっての”嗜み”だ。会計士が複式簿記を使わない時があるかって?外科医が滅菌消毒しない時があるかって?

The answer is yes in both cases. I rather doubt that accountants use double-entry bookkeeping when they balance their personal checkbooks, or when checking the total on a restaurant bill. I could be proven wrong about the former, after all, I used double-entry bookkeeping for years when balancing my checkbook. But I eventually grew to realize that the effort wasn’t worth the risk. As for the latter, I think we’d all agree that double-entry bookkeeping is overkill for a restaurant bill.

答えは両方「イエス」だ。会計士が個人的な小切手の勘定をしたり、レストランの支払いを集計するときに複式簿記を使っているとは思えない。前者については、経験上複式簿記を使うのは間違いだと分かった。数年間、自分で個人的な小切手を勘定するときに複式簿記を使ってみたんだけど、これにはそれだけのリスクを冒す価値が無いことに気付いたんだ。後者については、レストランの支払い集計に複式簿記を用いるのは、やりすぎだってことで同意が取れていると思っている。

As for surgeons and sterile procedure: I had a lipoma removed from my arm several years ago. My wife, an RN, observed the procedure. It was done under local in the doctors office. As the doctor was preparing I heard her question the doctor about the fact that he wasn’t using sterile procedure. He replied that for an operation of this size “clean procedure” was adequate. She and I accepted that statement; and the doctor completed the operation.

外科医と滅菌消毒については、何年か前に腕にできた腫瘍を取ってもらったことがあるんだ。僕の妻(看護師なんだけど)はその処置を見てたんだ。それは家の近くの診療所でやったんだよ。医師が処置する前に、彼女の「滅菌消毒しないの?」という質問が聞こえてきた。彼の答えは「このくらいの処置なら「洗浄処理」しとけばいいんだよ」だった。僕と彼女はそのことはに納得して、医師は処置を終えた。

A couple of days later, the incision became inflamed and painful. One of the sutures had become infected, and they had to reopen the incision and clean it out. I don’t know if this was because of “clean procedure” but from now on I will insist that the doctors who work on me use sterile procedure and not “clean procedure”.

二日後に、傷口に燃えるような痛みが現れた。縫い目の一部が炎症を起こしたんだ。で、彼らはもう一度傷口を開いて洗浄した。洗浄処理の理由は分からないけど、今からでも「洗浄処理」じゃなくて滅菌処理を医師にしてもらいたいよ。

Still, the point is valid. There are times when TDD is too costly, and a lower discipline should be used instead. I hope my stories have convinced you that those times are rare corner cases, and that the pragmatism meme should not be used to thwart your disciplines just because they seem inconvenient.

それでも、論点はあっている。TDDが高コストなら、代わりとなる低コストな原則を用いるべきだ。これらは重箱の隅をつつくようなまれなケースで、不便そうだからという理由で(TDDという)原則を曲げるために「実用主義というミーム」が使われるべきではない、ということを納得してくれたらいいなぁ。

The Pragmatics

So, when do I not practice TDD?

実際の例

では、TDDをしないのはどんなときか?

  • I don’t write tests for getters and setters. Doing so is usually foolish. Those getters and setters will be indirectly tested by the tests of the other methods; so there’s no point in testing them directly.
  • getterとsetterについてはテストを書かない。そんなことをするのはあほくさい。getterやsetterは他のメソッドのテストで間接的にテストされるだろうから(直接的にテストすることはTDDのポイントじゃないよ)。
  • I don’t write tests for member variables. They too will be tested indirectly.
  • メンバー変数にはテストを書かない。これも間接的にテストされるだろうから。
  • I don’t write tests for one line functions or functions that are obviously trivial. Again, they’ll be tested indirectly.
  • 明らかに些末なワンライナー関数についてはテストを書かない。もう一度言うけど、そういうのは間接的にテストされるだろうから。
  • I don’t write tests for GUIs. GUIs require fiddling. You have to nudge them into place by changing a font size here, an RGB value there, an XY position here, a field width there. Doing that test-first is silly and wasteful.
    • However, I make sure that any significant processing in the GUI code is removed into modules that are testable. I don’t allow significant code to go untested. So my GUI code is little more than glue and wires that pull data into place on the screen. (See articles on MVVM or Model View Presenter)
  • GUIについてはテストを書かない。GUIは「こねくりまわす」必要があるからね。フォントサイズを変えたり、色を変えたり、ポジションを変えたりするのに、いちいちちょこちょこ触らないといけない。テストファーストするなんてばからしいことこの上ないよ。
    • ただ、GUIコードを取り除いてテスト可能なモジュールに突っ込むのは重要なプロセスだと思ってる。重要なコードにテストを書かないなんて許されない。だから、僕のGUIコードはデータを引っ張ってきて画面に出すように紐づけてあるよ(MVVMやMVPの記事を見てくれ)
  • In general I don’t write tests for any code that I have to “fiddle” into place by trial and error. But I separate that “fiddling” code from code that I am surer of and can write tests for.
    • I have, upon occasion, fiddled code into place and then written tests after the fact.
    • I have also, upon occasion, deleted the code once “fiddled” and re-written it test-first.
    • Which of these you choose is a judgement call.
  • 一般的には、しっくりくるまでトライアンドエラーで”あれこれする(fiddle)”コードにはテストは書かない。でも”いじくりまわす(fiddling)”コードは確信をもってテストを書けるコードからは分けるようにしている。
    • ときどきは、しっくりくるまでいじくりまわした後にテストを書いている。
    • またときどきは、一度こねくり回し他コードを消してから、テストファーストで書き直している。
    • どっちを選ぶかは、みんなに任せよう。
  • A few months ago I wrote an entire 100 line program without any tests. (GASP!)
    • The program was a one-shot. It was used once and then discarded it. (It was for a special effect in one of my videos).
    • The program was all about the screen. In essence it was a pure GUI app. So I had to fiddle the whole thing into place.
    • I wrote it in Clojure, and so I had the REPL! I could run the growing program from the REPL, and I could see the results of every line of code I wrote instantly. It wasn’t TDD, it was EDD (Eye Driven Development).
  • 数か月前、全部で100行のプログラムをテストなしで書いた。(うぉっ!)
    • そのプログラムは一点物だった。一度しか使われずに捨てられたんだ。(僕のビデオに特殊なエフェクトをかけるためのモノだったんだ。)
    • そのプログラムは全部画面についてのモノだった。要するに純粋なGUIアプリだった。だから僕はしっくりくるまでコードをこねくり回す必要があった。
    • それはClojureで書かれ、REPL(Read Eval Print Loop、対話型評価環境)があった!REPLでプログラムを成長させながら走らせることができて、書いたコードの結果全てを、その場で見ることができた。TDDじゃないね、EDD(Eye Driven Development、目視駆動開発)だ。
  • I usually don’t write tests for frameworks, databases, web-servers, or other third-party software that is supposed to work. I mock these things out, and test my code, not theirs.
    • Of course I sometimes do test the third-party code if:
      • I think it’s broken.
      • The results are fast and predictable enough that a Mock would be overkill.
  • 普段フレームワーク、データベース、Webサーバーや、他の動作が保障されたサードパーティ製ソフトには、テストを書かない。こいつらはモックにして僕のコードのテストをする、そいつら(フレームワーク他自体)じゃなくね。
    • もちろん、たまにはサードパーティ製コードのテストを書くよ。例えば
      • こいつは壊れてると思うときとか
      • モックを使うより早く結果が分かって十分に結果が予想できるときはね。

It’s not all Dogma.

教条じゃないよ

This list isn’t complete. I’m sure I’ll think of some other times that I don’t write tests; but the spirit of this list ought to be evident. Pragmatics do come into play when doing TDD; it’s not all dogma.

このリストは完全じゃない。よく考えれば、他にもいろいろテストを書かないケースを思いつくだろうことはわかっている。でもこのリストの魂は明確にする義務がある。上の実例はTDDをするときに生きてくる。断じて教条じゃないんだ。

However, I respect the dogma; there is a reason for it. Pragmatics can sometimes override; but: I will not write any significant production code without making every effort to use TDD.

だけれども、教条もリスペクトしているし、そうするに足る理由がある。実例はたまに別の解釈をされることもあるけど、重要な製品コードはTDDを使う努力をせずには、書くことはないだろう。(訳註:TDDをはなから使わないという選択は無い、ということが「教条」ということかな?)

なお、他にも@Posauneさんが先に訳していましたので、一緒に紹介しておきます。

https://gist.github.com/posaunehm/5109379

Windows Live WriterでWordPress.comに投稿する際、パーマリンクURLを任意のものに変更する方法

WordPress.comにWindows Live Writerから投稿すると、「記事のURLが日本語になっちゃって嫌だなー」って思ってたんですが、任意のパーマリンクURLをつけられることが分かったのでメモ。

記事のプロパティの「スラッグ」を設定するだけでした。

image

 

ね?記事のURLがhttps://takanosho.wordpress.com/2012/01/04/live-writer-permalink-setting/になったでしょ?

 

#恥ずかしながら、今更気づきました・・・

「Code Snippet」プラグインのテスト

be freeとマルチポストする関係で、あちらはSyntax Highlighterが使えないので、別のコードハイライト方法を考えんといかんということで、「Code Snippet」を試してみます。

(正確には使えるけど、こちらのblogみたいに自前でJS動かすわけじゃない)

   1: var q = from i in Enumerable.Range(1, 100)

   2:         where i % 2 == 0

   3:         select i;

var q = from i in Enumerable.Range(1, 100) where i % 2 == 0 select i;

どうかな?

 

ちなみに、C#3.0のクエリ式の構文でもハイライトするように、中身をちょっといじってあります。