ためすう

メソッドオブジェクトによるメソッドの置き換え (リファクタリング-p135)

2018-11-11

目的

「リファクタリング」を理解するためにサンプルコードを PHP で書き換えてみました。

今回は「メソッドオブジェクトによるメソッドの置き換え」について書きます。

「メソッドオブジェクトによるメソッドの置き換え」 について

メソッドの分解を困難にするのはローカル変数です。

変更前

class Account
{
    public function gamma($inputVal, $quantity, $yearToDate)
    {
        $importantValue1 = ($inputVal * $quantity) + $this->delta();
        $importantValue2 = ($inputVal * $yearToDate) + 100;

        if (($yearToDate - $importantValue1) > 100) {
            $importantValue2 -= 20;
        }
        $importantValue3 = $importantValue2 * 7;

        return $importantValue3 - 2 * $importantValue1;
    }

    private function delta()
    {
        return 200;
    }
}

$a1 = new Account();
echo $a1->gamma(100, 3, 22) . "\n";

変更後

class Account2
{
    public function gamma($inputVal, $quantity, $yearToDate)
    {
        return (new Gamma($this, $inputVal, $quantity, $yearToDate))->compute();
    }

    public function delta()
    {
        return 200;
    }
}

class Gamma
{
    private $_account;
    private $inputVal;
    private $quantity;
    private $yearToDate;
    private $importantValue1;
    private $importantValue2;
    private $importantValue3;

    public function __construct(Account2 $source, $inputVal, $quantity, $yearToDate)
    {
        $this->_account = $source;
        $this->inputVal = $inputVal;
        $this->quantity = $quantity;
        $this->yearToDate = $yearToDate;
    }

    public function compute()
    {
        $importantValue1 = ($this->inputVal * $this->quantity) + $this->_account->delta();
        $importantValue2 = ($this->inputVal * $this->yearToDate) + 100;

        if (($this->yearToDate - $importantValue1) > 100) {
            $importantValue2 -= 20;
        }
        $importantValue3 = $importantValue2 * 7;

        return $importantValue3 - 2 * $importantValue1;
    }
}

$a2 = new Account2();
echo $a2->gamma(100, 3, 22) . "\n";

パラメータへの代入の除去 (リファクタリング-p131)

2018-11-11

目的

「リファクタリング」を理解するためにサンプルコードを PHP で書き換えてみました。

今回は「パラメータへの代入の除去」について書きます。

「パラメータへの代入の除去」 について

引数への代入が行われている。

一時変数を使う

変更前

function discountVersion1($inputVal, $quantity, $yearToDate)
{
    if ($inputVal > 50) $inputVal -= 2;

    return $inputVal;
}

echo discountVersion1(100, 2, 2018) . "\n";

変更後

function discountVersion2($inputVal, $quantity, $yearToDate)
{
    $result = $inputVal;
    if ($inputVal > 50) $result -= 2;

    return $result;
}

echo discountVersion2(100, 2, 2018) . "\n";

一時変数の分離 (リファクタリング-p128)

2018-11-11

目的

「リファクタリング」を理解するためにサンプルコードを PHP で書き換えてみました。

今回は「一時変数の分離」について書きます。

「一時変数の分離」 について

複数回代入される一時変数があるが、それは、ループ変数でも一時変数を集める変数でもない

1つの変数が2つのことに使われていると、コードを読む人が非常に混乱します。

変更前

$_height = 10;
$_width = 8;

$temp = 2 * ($_height * $_width);
echo $temp . "\n";

$temp = $_height * $_width;
echo $temp . "\n";

変更後

$_height = 10;
$_width = 8;

$perimeter = 2 * ($_height * $_width);
echo $perimeter . "\n";

$area = $_height * $_width;
echo $area . "\n";

説明用変数の導入 (リファクタリング-p124)

2018-11-10

目的

「リファクタリング」を理解するためにサンプルコードを PHP で書き換えてみました。

今回は「説明用変数の導入」について書きます。

「説明用変数の導入」 について

その式の結果または部分的な結果をその目的を説明する名前をつけた一時変数に代入する

「メソッドの抽出(110)」が適用できるときは、そっちの方を選びます

変更前

$platform = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0';
$browser = 'IE';
$resize = 1;

function wasInitialized()
{
    return true;
}

if ((strpos(strtoupper($platform), 'MAC') > -1) &&
    (strpos(strtoupper($browser), 'IE') > -1) &&
    wasInitialized() && $resize > 0) {
    // 略
    echo '変更前' . "\n";
}

変更後

$platform = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0';
$browser = 'IE';
$resize = 1;

function wasInitialized()
{
    return true;
}

$isMacOs = strpos(strtoupper($platform), 'MAC') > -1;
$isIEBrowser = strpos(strtoupper($browser), 'IE') > -1;
$wasResized = $resize > 0;

if ($isMacOs && $isIEBrowser && wasInitialized() && $wasResized) {
    // 略
    echo '変更後' . "\n";
}

問い合わせによる一時変数の置き換え (リファクタリング-p120)

2018-11-10

目的

今回は「問い合わせによる一時変数の置き換え」について書きます。

※ コードはありません。

「問い合わせによる一時変数の置き換え」について

一時変数を使って式の結果を保持している。

新たなメソッドが他のメソッドでも使えるようになる

一時変数は長いメソッドの誘因となります。

外部ストレージのアクセスがある場合は、一時変数に入れた方が良いかもしれないです。

関数の役割を絞れば、再利用しやすいというメリットはありそうです。

一時変数のインライン化 (リファクタリング-p119)

2018-10-29

目的

「リファクタリング」を理解するためにサンプルコードを PHP で書き換えてみました。

今回は「一時変数のインライン化」について書きます。

「一時変数のインライン化」 について

簡単な式によって1度だけ代入される一時変数があり、それが他のリファクタリングの障害となっている。

「一時変数のインライン化」はほとんどの場合、「問い合わせによる一時変数の置き換え(120)」の一部として使われます。

共通

class anOrder
{
    private $base_price;

    public function __construct($base_price)
    {
        $this->base_price = $base_price;
    }

    public function basePrice()
    {
        return $this->base_price;
    }
}

変更前

function hoge()
{
    $anOrder = new anOrder(500);
    $basePrice = $anOrder->basePrice();

    return ($basePrice > 1000);
}

var_dump(hoge());

変更後

function hogeNew()
{
    $anOrder = new anOrder(500);

    return ($anOrder->basePrice() > 1000);
}

var_dump(hogeNew());

メソッドのインライン化 (リファクタリング-p117)

2018-10-28

目的

「リファクタリング」を理解するためにサンプルコードを PHP で書き換えてみました。

今回は「メソッドのインライン化」について書きます。

「メソッドのインライン化」 について

「メソッドのインライン化(117)」を適用するのは、間接化し過ぎた結果、 すべてのメソッドが別のメソッドへと単純に委譲しているようにしか見えず、 委譲の途中で道に迷ってしまうようなときです。

変更前

class Sample
{
    public $_numberOfLateDeliveries = 3;

    public function getRating()
    {
        return ($this->moreThanFiveLateDeliveries()) ? 2 : 1;
    }

    private function moreThanFiveLateDeliveries()
    {
        return $this->_numberOfLateDeliveries > 5;
    }
}

// 呼び出し
$sample = new Sample();
echo $sample->getRating() . "\n";

変更後

class SampleNew
{
    public $_numberOfLateDeliveries = 3;

    public function getRating()
    {
        return ($this->_numberOfLateDeliveries > 5) ? 2 : 1;
    }
}

// 呼び出し
$sample_new = new SampleNew();
echo $sample->getRating() . "\n";

メソッドの抽出 (リファクタリング-p110)

2018-10-28

目的

「リファクタリング」を理解するためにサンプルコードを PHP で書き換えてみました。

今回は「メソッドの抽出」について書きます。

「メソッドの抽出」 について

どんな処理をするかではなく、何をするかによって命名する

私はメソッドが返す値は1つにする方がよいと思うので、複数のメソッドを準備して、さまざまな値に対応することを試みます。

変更前

class Sample
{
    private $_name;

    public function __construct($_name)
    {
        $this->_name = $_name;
    }

    public function printOwing($amount)
    {
        $this->printBanner();

        // 明細の表示
        echo('name: ' . $this->_name . "\n");
        echo('amount: ' . $amount . "\n");
    }

    public function printBanner()
    {
        echo 'call' . __FUNCTION__;
    }
}

// 呼び出し
$obj = new Sample('MyName');
$obj->printOwing(2000);

変更後

class SampleNew
{
    private $_name;

    public function __construct($_name)
    {
        $this->_name = $_name;
    }

    public function printOwing($amount)
    {
        $this->printBanner();
        $this->printDetails($amount);
    }

    // 明細の表示
    public function printDetails($amount)
    {
        echo('name: ' . $this->_name . "\n");
        echo('amount: ' . $amount . "\n");
    }

    public function printBanner()
    {
        echo 'call' . __FUNCTION__;
    }
}

// 呼び出し
$obj_new = new SampleNew('MyName');
$obj_new->printOwing(4000);

unix で script コマンドを使ってみる

2018-10-27

目的

unix でコマンドを実行した後、出力結果まで保存することができないか調べたところ

script コマンドというものがあったので使ってみます。

使ってみる

$ script /tmp/test.log
スクリプトを開始しました、ファイルは /tmp/test.log です
$ hostname
localhost.localdomain
$ pwd
/home/vagrant
$ date
2018年  3月  4日 日曜日 22:26:29 UTC
$ exit
exit
スクリプトを終了しました、ファイルは /tmp/test.log です

書き出しファイルを読み込みます

$ less -r /tmp/test.log

この -r オプションは、下記の目的で使用します。

「そのままの」制御文字を表示させるようにする。

参考URL

シェルで変数置換する方法

2018-10-22

目的

シェルスクリプトの中で変数の値を変換します。

やってみる

方法1. sedで変換する

#/bin/bash

TEST="abc abcdedfg 345 987 22222 345622"
echo "sedで置換する"
echo "変更前: "  $TEST
echo "変更後: "  $TEST | sed s/abc/ABC/g
echo ""

結果

変更前:  abc abcdedfg 345 987 22222 345622
変更後:  ABC ABCdedfg 345 987 22222 345622

方法2. シェル変数展開時に変換する

TEST="abc 'abcdedfg' 345 987 22222 345622"
echo "シェル変数展開時に置換"
echo "変更前: "  $TEST
echo "変更後 1箇所: "  ${TEST/\'/\\\'}
echo "変更後 全箇所: " ${TEST//\'/\\\'}

結果

変更前:  abc 'abcdedfg' 345 987 22222 345622
変更後 1箇所:  abc \'abcdedfg' 345 987 22222 345622
変更後 全箇所:  abc \'abcdedfg\' 345 987 22222 345622

参考URL