読者です 読者をやめる 読者になる 読者になる

実績があるコードと製品に使った事があるコードは違う

よくあることなんだけれど、「社内の実績があるコードを使え」と言われて見てみると、
「これはひどい」というコードであることがある。
そういう人が言っている「実績がある」は「製品に使用した事がある」なんだよな。

例えばあるデバイスから、非同期で読み書きするようなモジュールがあったのだが、
書き込みに対する操作で、
HogeDeviceWriteInitialize
HogeDeviceWriteExecute
となってて、
Initializeの中で書き込み先アドレス、書き込み元アドレス、書き込みサイズを記憶し、
「なぜか」
Executeの中で、デバイスに対する非同期リクエストを発行し、以降はそれを待つなんていう仕組みになってた。

// 構造だけ
void HogeDeviceWriteInitialize(int addr, const void* data, size_t size)
{
    ... 変数に記憶
}

HogeResultCode HogeDeviceWriteExecute()
{
    switch (mode) {
    case INIT:
       SDKWriteAsync(...); // init の処理で記憶した値で非同期書き込みリクエスト
       break;
    case WAIT:
        result = IsSDKAsyncWaiting(); // 非同期処理が終わったか問い合わせ
        break;
    case SUCCESS:
        // なんか上の方での成功を見てる
       result = SDKResultCode();
       break;
    case FAILURE:
        // なんか上の方での失敗の詳細を見てる
       result = SDKResultCode();
       break;
   }
...
}

こんな感じ。
非同期処理というのに、Executeを一度呼び出さないと処理が開始されないわ、
Executeの中にリクエストと、非同期待ちと、成否を返す機能がごった煮にされていて「これはひどい」。
普通に、
writeAsync……非同期で書き込みをリクエストする機能
isAsyncWaiting……非同期処理を待っているか成否を返す機能
getResultCode……最終的な成否及び、失敗なら失敗の原因を返す機能
みたいに分けるだけでええやん?(もともとのSDKはそういう構造だし)
なのになぜ、ごった煮にしたがるのかなあ。
InitとExecしかないから使いやすいだろー!?
ってことなのかなあ。


そして、これが「実績があるので使え」と言われると、
そんなものは死んでも使いたくないという罠。