ためすう

重複した条件記述の断片の統合 (リファクタリング-p243)

2019-02-12

目的

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

今回は「重複した条件記述の断片の統合」について書きます。

「重複した条件記述の断片の統合」 について

条件式のすべての分岐に同じコードの断片がある。

上記の場合に適用します。

変更前

<?php

function send()
{
    echo "send\n";
}

function isSpecialDeal()
{
    return true;
}

function main($price)
{
    if (isSpecialDeal()) {
        $total = $price * 0.95;
        send();
    } else {
        $total = $price * 0.98;
        send();
    }

    echo $total . "\n";
}

main(1000);

変更後

<?php

function send2()
{
    echo "send2\n";
}

function isSpecialDeal2()
{
    return true;
}

function main2($price)
{
    if (isSpecialDeal2()) {
        $total = $price * 0.95;
    } else {
        $total = $price * 0.98;
    }

    send2();

    echo $total . "\n";
}

main2(1000);

条件記述の統合 (リファクタリング-p240)

2019-02-11

目的

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

今回は「条件記述の統合」について書きます。

「条件記述の統合」 について

条件記述のコードを統合することが重要である理由は2つあります。

1つは、他の条件判定とorで繋げることで実際は単一の条件判定を行うことを示して、 その条件判定を明確にするためです。

もう1つの理由は、このリファクタリングはしばしば「メソッドの抽出」の下準備としての役割を持つためです。

変更前

<?php

class Dummy
{
    private $_seniority;
    private $_monthsDisabled;
    private $_isPartTime;

    public function __construct($seniority, $monthsDisabled, $isPartTime)
    {
        $this->_seniority = $seniority;
        $this->_monthsDisabled = $monthsDisabled;
        $this->_isPartTime = $isPartTime;
    }

    public function disabilityAmount()
    {
        if ($this->_seniority < 2) return 0;
        if ($this->_monthsDisabled > 12) return 0;
        if ($this->_isPartTime) return 0;

        // 後続の処理
        return 1;
    }
}

$d1 = new Dummy(2, 11, 0);
echo (int)$d1->disabilityAmount() . "\n";

変更後

<?php

class Dummy2
{
    private $_seniority;
    private $_monthsDisabled;
    private $_isPartTime;

    public function __construct($seniority, $monthsDisabled, $isPartTime)
    {
        $this->_seniority = $seniority;
        $this->_monthsDisabled = $monthsDisabled;
        $this->_isPartTime = $isPartTime;
    }

    public function disabilityAmount()
    {
        if ($this->isNotEligibleForDisability()) {
            return 0;
        }

        // 後続の処理
        return 1;
    }

    private function isNotEligibleForDisability()
    {
        return (($this->_seniority < 2) ||
            ($this->_monthsDisabled > 12) ||
            ($this->_isPartTime));
    }
}

$d2 = new Dummy2(2, 11, 0);
echo (int)$d2->disabilityAmount() . "\n";

JavaScript の正規表現

2019-02-11

目的

JavaScript の正規表現を使い、ユーザーエージェントから iPad を判別します

やってみる

iPadのユーザーエージェント を抽出する方法です。

var ipad_log = "Mozilla/5.0 (iPad; CPU OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A405 Safari/600.1.4";
var a = ipad_log.match(/ipad/i);
console.log(a);

// 実行結果
["iPad", index: 13, input: "Mozilla/5.0 (iPad; CPU OS 8_0_2 like Mac OS X) App…e Gecko) Version/8.0 Mobile/12A405 Safari/600.1.4"]

/ipad/i の i は大文字小文字の区別をなくすオプションです

AWS の ELB について

2019-02-10

目的

ロードバランサについて知ることです

ELB(Elastic Load Balanning)とは

複数のAmazon EC2インスタンス間で、アプリケーショントラフィックの負荷を自動的に拡散してくれる、ロードバランサのPaaSです。

ELBの特徴

  • スケーラブル
  • 高可用性
  • トラフィックの料金が低い

Saas、Paas、IaaS とは

  • Saas

SaaSとは、「Software as a Service」の頭文字を取った略語で「サース」と読みます。 これまでパッケージ製品として提供されていたソフトウェアを、インターネット経由でサービスとして提供・利用する形態のことを指します。

  • Paas

PaaSは「Platform as a Service」の頭文字を取った略語で「パース」と読みます。 アプリケーションソフトが稼動するためのハードウェアやOSなどのプラットフォーム一式を、インターネット上のサービスとして提供する形態のことを指します。

  • IaaS

IaaSは「Infrastructure as a Service」の頭文字を取った略語で「イァース」と読みます。 情報システムの稼動に必要な仮想サーバをはじめとした機材やネットワークなどのインフラを、インターネット上のサービスとして提供する形態のことを指します。

参考

Swift で Optional 型をアンラップする方法

2019-02-10

目的

Swift で Optional 型をアンラップする方法をまとめました。

方法1. Optional Binding

var str: String? = "Hello, playground"
var strNil: String? = nil

// nil の場合は空文字を返却する
func message(argStr:String?) -> String {
    if let unwrappedStr = argStr {
        return unwrappedStr.uppercased()
    }
    return ""
}

print(message(argStr:str))
print(message(argStr:strNil))

方法2. Optional Chaining

var str: String? = "Hello, playground"
var strNil: String? = nil

print(str?.uppercased())
print(strNil?.uppercased())

方法3. Forced Unwrapping

強制的にオプショナル型をアンラップします。

これを使用するときは、nil ではないことを保証しないとエラーが発生します。

print(str!.uppercased())

// 注意!!! エラーが出る
// Fatal error: Unexpectedly found nil while unwrapping an Optional value
// print(strNil!.uppercased())

方法4 ImplicitlyUnwrappedOptional

var implicitlyStr: String! = "Hello, playground"
var implicitlyStrNil: String! = nil

print(implicitlyStr.uppercased())

// 注意!!! エラーが出る
// Fatal error: Unexpectedly found nil while unwrapping an Optional value
// print(Int(implicitlyStrNil)!)

参考

Swift の guard を使ってみる

2019-02-03

目的

Swift の guard を使ってみました。

関数呼び出し時に後続の処理にいくかどうかを判定している処理を書いてみました。

  • register() guard 文を利用
  • register2() if 文を利用
var isEnalbed = true

func register() {
    guard isEnalbed else {
        print("not registered")
        return
    }

    print("register")
}

func register2() {
    if (!isEnalbed) {
        print("not registered2")
        return
    }

    print("register2")
}

register()
register2()

出力

register
register2

メリット

guard 文は return を書かないといけないので、書き忘れを防止できます。

参考

Swift から Objective-C のコードを呼ぶ方法

2019-01-31

目的

Objective-C から Swift を呼ぶ方法を調べました。

方法


Build Settings -> Swift Compiler – Code General の

```Bridging-Header.h``` が指定されているか確認します。

指定されている場合は、 import 文を書いていきます。

Bridging-Header.h

#import “Hoge.h” ```

参考

Swift、Objective-Cでバックグラウンド、フォアグラウンドへの遷移する方法

2019-01-28

目的

iOS アプリでバックグラウンドに遷移したとき、フォアグラウンドに遷移したときにある処理を実行する方法を調べました。

Notification 一覧

イベントタイミング Swift Objective-C
フォアグラウンドになる直前 NSNotification.Name.UIApplicationWillEnterForeground UIApplicationWillEnterForegroundNotification
アクティブになったら NSNotification.Name.UIApplicationDidBecomeActive UIApplicationDidBecomeActiveNotification
アクティブでなくなる直前 NSNotification.Name.UIApplicationWillResignActive UIApplicationWillResignActiveNotification
バックグランドになったら NSNotification.Name.UIApplicationDidEnterBackground UIApplicationDidEnterBackgroundNotification
終了する直前 NSNotification.Name.UIApplicationWillTerminate UIApplicationWillTerminateNotification

Objective-C で実装

アクティブでなくなる直前、hogehoge1 を呼び出します。 フォアグラウンドになったとき、hogehoge2 を呼び出します。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hogehoge1) name:UIApplicationWillResignActiveNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hogehoge2) name:UIApplicationDidBecomeActiveNotification object:nil];

また、登録したイベントを削除します。

[[NSNotificationCenter defaultCenter] removeObserver:self];

Swift で実装

アクティブでなくなる直前、hogehoge1 を呼び出します。

バックグラウンドになったとき、hogehoge2 を呼び出します。

NotificationCenter.default.addObserver(self, selector: #selector(self.hogehoge1), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.hogehoge2), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)

参考

Swift の第一引数がある関数を Objective-C で呼び出すとき、@objcを使う

2019-01-21

目的

Swift で第一引数がある関数を定義して、 Objective-C で呼び出すときに@objcキーワードを使う方法を試しました。

今回は、Objective-C で呼び出すときの関数名も指定するようにしました。

嵌った例

下記記事を参照してください

Swiftの第一引数がある関数をObjective-Cで呼び出すときの

解決した方法

Swift 側のコード

@objcMembers class Calc: NSObject
{
    @objc(addNew: b:) static func add(_ a:Int, b:Int) {
        print(a+b)
    }
}

Objective-C 側

[Calc addNew:2 b:3];

Swift の as でキャストする方法

2019-01-14

目的

Swift の as でキャストする方法をまとめました。

as について

クラスの型変換時に使われます

as

キャストの成功が保証されているときに利用します

as!

強制ダウンキャストするときに利用します

as?

ダウンキャストが成功するか分からないときに利用します

// as
// var a11 = a as Man // ダウンキャストはエラーが発生
var a12 = a as Human // 上位クラスへ

// as!
var a21 = a as! Man // 強制ダウンキャスト
// var a22 = a as! Woman // エラー

// as?
var a31 = a as? Woman
var a32 = a as? Man // 常に成功する