プログラムをオブジェクト指向にするには
プログラムをオブジェクト指向にするには、
- そのプログラムがなにをするか、に加えて、
- それをどこにやらせるか、
が重要になる。
気を付けるのは、他のクラスのプロパティを使って、いろいろ計算しているところ。次の例では、適用期間 (ApplicableTerm) クラスを使うクラスが、ApplicableTerm の Start と End プロパティから期間内かどうかを求めている。
using System; namespace ObjectOrientedBadSample { public class ApplicableTerm { private TimeSpan _start; private TimeSpan _end; public TimeSpan Start { get { return _start; } } public TimeSpan End { get { return _end; } } } public class ApplicableTermUser { public void BadUser(ApplicableTerm term) { TimeSpan someTimePoint = new TimeSpan(); // ある時点 if (term.Start <= someTimePoint && someTimePoint <= term.End) // ======================================================== { // 適用期間内 } } } }
他のクラスのプロパティを使って自分で計算するのではなく、そのプロパティを提供するクラスにやってもらう。
using System; namespace ObjectOrientedBetterSample { public class ApplicableTerm { private TimeSpan _start; private TimeSpan _end; public bool IsIncluded(TimeSpan timePoint) { return _start <= timePoint && timePoint <= _end; } } public class ApplicableTermUser { public void GoodUser(ApplicableTerm term) { TimeSpan someTimePoint = new TimeSpan(); // ある時点 if (term.IsIncluded(someTimePoint)) // ============================== { // 適用期間内 } } } }
知識レベル-操作レベルを使うとき(1)
アナリシスパターンの知識レベル-操作レベルを使うときとして、
- プログラムの再コンパイルなしで、
- なにかの種類を増減したい。
場合がある。
たとえば、測定の種類として身長や体重などがあるとする。これらがプログラムのコンパイル時点で決定できるならば、以下のように enum で表現できる。
namespace KnowledgeOperation1 { public enum MeasurementTypeEnum { Height, Weight, // . . . . . } public class WrittenInSourceCode { MeasurementTypeEnum _measType; } }
測定の種類が増減し、プログラムを再コンパイルせずに対応するには、
- 測定の種類をクラスにして、
- そのインスタンスを生成・破棄する
ようにしておけばよい。
namespace KnowledgeOperation1 { // new MeasurementTypeClass("Height"); // new MeasurementTypeClass("Weight"); // . . . . . public class MeasurementTypeClass { public MeasurementTypeClass(string name) { // } } public class UsingReference { MeasurementTypeClass _measType; } }
参考: アナリシスパターンを読もう
Windbg で sosex を使ってマネージコードのソースレベルでブレークポイント設定
Windbg でマネージコードをデバッグするとき、sosex を使えば、ソースレベルでブレークポイントを設定できる。
- '.load sosex.dll' で sosex をロード。
- '!mbp ソースファイル名 行番号' でブレークポイント設定。
- 'g' で実行開始。
- ブレークポイントにヒットした。
- '.loadby sos.dll clr' で sos をロード (フレームワークが 3.5 までは 'clr' を 'mscorwks' に変更する、参考: Unable to load SOS in WinDbg)
- '!ClrStack' でマネージスタックを表示。
- 指定の位置でブレークしている!
Visual Studio のインクリメンタルサーチ
Visual Studio のインクリメンタルサーチを使えば、1文字打つごとにカーソルが移動し検索できる。
- Ctrl + I でインクリメンタルサーチ開始。マウスカーソルが双眼鏡の形に変わる。
- サーチする文字を入力すると、その文字へカーソルが移動する。下の例では 'c' を入力。
- 次の文字を入力すると、さらにカーソルが移動する。例では 'a' を入力し 'ca' へ移動。
- サーチ中に Ctrl + I を入力すると、次のサーチ文字列へカーソルが移動する。例では次の 'ca' へ移動。
- ESC を押すと、インクリメンタルサーチ終了。
Native Exe ファイルの実行開始アドレス
Dumpbin コマンドで exe ファイルのヘッダ情報を表示すると、その中に開始アドレスが含まれている。
ためしに windbg で、開始アドレスから逆アセンブルしてみる。
64 ビットのアドレスは ***長い***。