「みんなでアジャイル」を読んだ

みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた

みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた

  • 作者:Matt LeMay
  • 発売日: 2020/03/19
  • メディア: 単行本(ソフトカバー)

同僚の何人かが読んでいたので手にとってみた。

アジャイル」という言葉は「単なる方法論」あるいは「宗教のような何か」と誤解されがち。

そんな「アジャイル」の根本的な価値観を職種問わずわかり易い言葉で説明している。

またそれを実現する組織にするためのヒントが散りばめられていた。

アジャイルマニフェストの成り立ちにまで言及しているところにとても好感がもてる。

ページ数もそんなになくてサクッと読めた。

その代償なのだろうけど、エンジニアリングと絡むような(技術的な)側面への言及はほとんどない。

コンウェイの法則的な話もあるけど、こういった組織論を語るときに一緒にテーブルに乗っていないと、個人的には何か片手落ちな気がしてしまうのであった。

この本で特によいなぁと思ったのは、組織構造の問題点に触れているところ。

構造の観点が最近自分の中でもホットなので、読んだタイミングがよかったのかもしれない。

「そう振る舞うことが自然」という構造にすることが、組織づくりにおいてとても大切な気がする。

みんなでアジャイル読書メモ · GitHub

SQL アンチパターンを読んだ

SQLアンチパターン

SQLアンチパターン

  • 作者:Bill Karwin
  • 発売日: 2013/01/26
  • メディア: 大型本

ちょこちょこつまみ読みはしていたけれど、改めて通しで読んでみた。

そこそこキャリアのある人であれば、どこかで見かけ、そして苦しめられたパターンがいくつかあると思う。

この本がとてもいいなぁと思ったのは、アンチパターンがなぜよくないか、どういうデメリットがあるかということを言語化してくれているということ。

「当然これはやらない方がよい」と考えたことでも、それを明確に論理立て、かつ具体的に人に伝えるというのはすごく難しい。

この本があることで、少なくとも議論の前提が揃えられるというのは大きいと思った。

SQLアンチパターン読書メモ · GitHub

1365. How Many Numbers Are Smaller Than the Current Number

LeetCode の挑戦ログ

Problem

https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/

  • 数字の配列が与えられる
  • それぞれの値より少ない値がいくつ含まれているか数える
  • その数を同じ index の配列にして返す

Solution

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        return Arrays.stream(nums)
                .map(base -> (int) Arrays.stream(nums).filter(num -> num < base).count())
                .toArray();
    }
}

Impressions

  • count に詰め替えているところは可読性を考えると関数に切り出してもいいかも
  • 結局コードの考え方としては総当たりに近いのでもうちょっといいアプローチがありそう

1342. Number of Steps to Reduce a Number to Zero

LeetCode の挑戦ログ

Problem

https://leetcode.com/problems/number-of-steps-to-reduce-a-number-to-zero/

  • 正の整数が渡される
  • 偶数なら 2 で割る、奇数なら 1 を引く
  • 0 になるまでの回数を数える

Solution

class Solution {
    public int numberOfSteps(int num) {
        return countSteps(num);
    }

    private int countSteps(int num) {
        int steps = 0;
        while (num != 0) {
            num = reduce(num);
            steps += 1;
        }

        return steps;
    }

    private int reduce(int num) {
        return num % 2 == 0 ? (num / 2) : (num - 1);
    }
}

Impressions

  • 最初は再起で書いたけど、ループに書き直した
  • Java には言語での末尾再帰最適化はないらしい
  • Kotlin の tailrec は便利だな

再起で書いたやつ

class Solution {
    public int numberOfSteps(int num) {
        return countSteps(num, 0);
    }

    private int countSteps(int num, int steps) {
        num = reduce(num);
        steps += 1;

        if (num == 0) {
            return steps;
        }

        return countSteps(num, steps);
    }

    private int reduce(int num) {
        return num % 2 == 0 ? (num / 2) : (num - 1);
    }
}

PHPUnit のモックで、引数に応じて戻り値を変更する #php #PHPUnit

概要

  • returnValueMap を使うと引数に応じて戻り値を変更できる
  • 例外を返したいときは returnCallback() を使うと便利

returnValueMap を使う

returnValue に [引数, 戻り値] の配列を渡すと、引数に応じた戻り値を返す Mock を作れる。

引数が複数ある場合は、 [引数1, 引数2, 戻り値] のような形式にしてあげればよい。

// Mock を作成
$mock = $this->createMock(HogeClass::class);

// returnValueMap に [引数, 戻り値] の配列を渡す
$mock->method('doSomething')
      ->will($this->returnValueMap(
        [
          ['arg1', 'ret1'],
          ['arg2', 'ret2'],
        ]
      ));

// 引数に応じた値が帰ってくる
$this->assertSame('ret1', $mock->doSomething('arg1'));
$this->assertSame('ret2', $mock->doSomething('arg2'));

例外を返す場合は returnCallback を使うとよさそう

returnValueMap だと通常の戻り値と例外のケースを同時に同じ Mock ができなそう。

返り値を callback にできる returnCallback を応用して実現してみる。

$mock->method('doSomething')
      ->will($this->returnCallback(
        // doSomething が実行されると、callback が呼ばれる
        function ($arg) {
          if ($arg === 'arg1') {
            return 'ret1';
          } elseif ($arg === 'arg2') {
            return 'ret2';
          } elseif ($arg === 'invalid') {
            // 引数によって例外を投げる
            throw new InvalidArgumentException('doSomething called by invalid argumnet. Input was: '.$arg);
          }

          return 'retDefault';
        }
      ));

引数と返り値を切り出す

returnCallback でやりたいことは実現できたのだが、分岐を追記していくスタイルは辛いので、処理を切り分ける。

// 引数と戻り値の紐付けを切り出す
$map = [
  'arg1' => function () { return 'ret1'; }],
  'arg2' => function () { return 'ret1'; }],
  'invalid' => function () { throw new InvalidArgumentException('doSomething called by invalid argumnet. Input was: '.$arg); }],
  'default' => function () { return 'retDefault'; }],
];

$mock->method('doSomething')
      ->will($this->returnCallback(
        function ($arg) {
          if ($map[$arg]) {
            return $map[$arg]();
          }

          return $map['default']();
        }
      ));

補足

そもそも Mock に色々やらせすぎたり、 Mock を使いすぎたりするのは微妙だと思う。

ただ Mock をケースごとに差し替えるのは大変なときにはこういうやり方が使えそう。

参考

課題に正面から取り組むこと

経験を積むと、実現が難しい方法で苦しんでるときに、より容易な回避方法が浮かぶようになる。

手元に並べられる選択肢が増えるというか。

それはいいことなんだけど、「より最適な解として」別の手段を選んでるつもりで、「難しい方法を避けるために」別の手段を選んではいないか。

特に「納期」みたいなものは分かりやすく、そして言い訳にしやすい。

「今回はスケジュールが厳しいからこの方法にしよう」

安全策は最後のライフラインとして傍らに確保しつつ、正面から立ち向かう気持ちを忘れずにいたい。

私は弱い人間で、すぐ逃げようとするので。

DataGrip で クリアテキスト認証 を使う #DataGrip

概要

IAM 認証 による RDS 接続をする際などに、 MySQL のクリアテキスト認証が必要になる。

DataGrip から利用する方法をまとめておく。

おそらく Jetbrains 製品の Database Viewer でも同じ方法でできると思う。

参考: IAM認証によるRDS接続を試してみた | Developers.IO

設定方法

  • DataSource の設定項目の Advanced タブを開く
  • authenticationPlugin に com.mysql.cj.protocol.a.authentication.MysqlClearPasswordPlugin を指定する
  • VM environment に LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN=1 を設定する

ドライバーに MySQL for 5.1 を利用している場合

パッケージ名が異なるので、 com.mysql.jdbc.authentication.MysqlClearPasswordPlugin を指定する。

参考