ためすう

DIとDIコンテナとサービスロケータ その2

2018-02-18

本記事の範囲

本記事では、DI コンテナについて書きます。 サービスロケータは別記事で。

DI コンテナとは

DIを楽にしたり、オブジェクト生成のコードをまとめるための便利なツール

DI コンテナ の例

Main.php ( 1 ファイルに全部まとめました)

<?php

require_once './vendor/autoload.php';

use Pimple\Container;

class Service
{
    public function log($message)
    {
        echo $message . "\n";
    }
}

class Client
{
    private $service;

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

    public function log($message)
    {
        $this->service->log($message);
    }
}

$container = new Container();

$container['service_interface'] = function ($container) {
    $service = new Service();
    return $service;
};

$container['client'] = function ($container) {
    $client = new Client($container['service_interface']);
    return $client;
};

$client = $container['client'];
$client->log('ssssss');

今回は Pimple を使用して、依存性について定義しました。

これによって、呼び出し元で依存性の注入を直接記述しなくても良くなりました。

(Client に渡すクラスが インターフェースになったら、一工夫が必要そうです。)

参考

DIとDIコンテナとサービスロケータ その1

2018-02-17

本記事の範囲

本記事では、DI までを記事の範囲とします。 DI コンテナ、サービスロケータは別記事で書きます。

DI とは

依存性の注入(いそんせいのちゅうにゅう、英: Dependency injection)とは、コンポーネント間の依存関係をプログラムのソースコードから排除し、外部の設定ファイルなどで注入できるようにするソフトウェアパターンである。英語の頭文字からDIと略される。

依存性の注入の方法

注入の方法は下記のような手法がある。

  • インタフェース注入
  • setter注入
  • コンストラクタ注入

DI の例

Main.php

<?php

require_once './LoggerInterface.php';
require_once './ExampleLogger.php';
require_once './DummyLogger.php';
require_once './Application.php';

// $logger = new ExampleLogger();
$logger = new DummyLogger();
$app = new Application($logger);
$app->error('エラーが発生');

Application.php

<?php

class Application
{
    protected $logger;

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

    public function error($message)
    {
        $this->logger->log($message);
    }
}

LoggerInterface.php

<?php
interface LoggerInterface
{
    public function log($log);
}

ExampleLogger.php

<?php

class ExampleLogger implements LoggerInterface
{
    public function log($log)
    {
        echo $log . "\n";
        return $this;
    }
}

DummyLogger.php

<?php

class DummyLogger implements LoggerInterface
{
    public function log($log)
    {
        return $this;
    }
}

DI の特徴

  1. オブジェクトの生成と使用が分離されている
  2. クライアントがサービスを呼ぶのではなく、サービスが外部からクライアントに注入される。つまり、制御が反転している

また、この例では、 - ExampleLogger、DummyLogger の実装が完了していなくても、Application の実装ができます。 - LoggerInterface を実装した新しいクラスに切り替えるとき、呼び出し元の変更だけでokです。

参考

オブジェクト指向について

2018-02-15

本記事の概要

参考URLに良いまとめがあったので、自分用のメモとして抜粋させて頂きました。

オブジェクト指向の特徴

  • 継承
  • カプセル化
  • ポリモーフィズム (多態性)

継承

  • 継承の本質はインターフェイスです。

  • 継承は機能を受け継ぐためのものではありません。継承の本質は、犬や猫を「動物」という抽象概念としてまとめ上げられるインターフェイスなのです。

  • 継承は親クラスの機能を受け継ぎますが、これは開発効率を上げるための優しさ的仕様であり、継承の本質はインターフェイスなのです。

継承を親クラスの機能を受け継ぐ目的で使って、失敗した記憶があります。

継承をインターフェースとして捉えて、抽象概念の抽出という目的で使うのが大切なようです。

カプセル化

  • カプセル化は、外から見てそのものが複雑でない状態を作るということ

  • クラスの役割は一つにする

これはクラスの利用者とクラスとの接点で、意識するべきところを理解しやすくするためかなと考えています。

ポリモーフィズム (多態性)

  • ポリモーフィズムはそのインターフェイス(抽象)に対してプログラムするということです

  • ここで衝撃的な事実をお伝えしましょう!実は「new」は具象です!ですから、ポリモーフィズムを意識する上でnewの扱いには最大限の注意を払う必要があります。

ポリモーフィズムは自分の中でしっくり来ていなかったのですが、腑に落ちた気がします。

デザインパターンでオブジェクトの生成と利用を分けているものがある理由もそこにあるのかもしれません。

(Factory Method パターンとか)

まとめ

自信を持って、クラス設計がしていけるように上記を頭に入れてやっていきたいと思います。

参考

composerをインストールする

2018-02-12

目的

Pimple という DIコンテナ(Dependency Injection Container)を使いたかったため、

手元の Mac にて composer 経由でインストールします。

解決策

1. composer をインストール

$ curl -sS https://getcomposer.org/installer | php

2. path の設定

$ mv composer.phar /usr/local/bin/composer

3. Pimple を composer 経由でインストール

$ composer require pimple/pimple ~3.0

4. ライブラリを autoload する

例えば Pimple を利用したい場合は、下記のようにして autoload します。

<?php
require_once './vendor/autoload.php';

use Pimple\Container;

$container = new Container();

参考URL

phpのdate関数の計算で気をつけること

2018-01-15

目的

php で date関数を使用するときに少し嵌るところがあったので、

メモとして残しておきます。

日付の計算で1ヶ月後の末日を求めるときに 2ヶ月後の末日を求めてしまうという問題に遭遇しました。

解決策

事象の確認

sample.php

<?php

date_default_timezone_set('Asia/Tokyo');
$time = '2017/10/31';

echo date('Y-m-t', strtotime('+1 month ' . $time)) . "\n";

下記を実行する

$ php sample.php

結果

2017-12-01 00:00:00

解決策

月の1日から末日を計算する

<?php

date_default_timezone_set('Asia/Tokyo');
$time = '2017/10/01';

echo date('Y-m-t', strtotime('+1 month ' . $time)) . "\n";

結果

2017-11-30

gitのファイル名で日本語を使うとき

2017-12-24

目的

日本語ファイルを git で管理しているのですが、

ステータスを確認したときに、日本語がきちんと表示されていなくてファイルが判別できなかったので、

日本語で表示する方法がないかを調べました。

解決策

$ git config --local core.quotepath false

おまけ

.git/config と ~/.gitconfig の読み込み順番

1. ~/.gitconfig
2. .git/config (リポジトリの中)

参考

MacVimを使うときに設定が反映されない

2017-12-03

目的

下記に vim の設定を書いていたのですが、

~/.vimrc

MacVimには反映されないので原因を調べました。

解決策

方法1. ~/.gvimrc を編集する

MacVimでは ~/.vimrc が読み込まれないようなので、


source ~/.vimrc


私はこちらの方法で解決しました。

#### 方法2. MacVim に入っている設定を削除する(※未確認)

こちらはあまり良い方法ではなさそうです。

最後の手段くらいに考えておいてください。


MacVim にビルドインされた```vimrc```の方が読み込まれいているのが原因のようです。

(下記のコマンドは試していないため、注意してください!)

$ rm /Applications/MacVim.app/Contents/Resources/vim/vimrc $ rm /Applications/MacVim.app/Contents/Resources/vim/gvimrc ```

参考

Middlemanのtagで日本語名を使うと空文字になってしまう問題

2017-11-26

目的

Middlemanのtagを入力するときに、日本語名を使うと

空文字になってしまうという問題に遭遇しました。

解決策

tag名を全てエンコードする方法を採用しました。

1. config.rb を修正する

$ vim config.rb

追加内容

after_configuration do
  module TagPagesExtension
    def link( tag )
      safe_tag = CGI.escape(tag)
      apply_uri_template @tag_link_template, tag: safe_tag
    end
  end
  Middleman::Blog::TagPages.prepend(TagPagesExtension)
end

参考

https://blog.leko.jp/post/how-to-use-japanese-tag-in-middleman/

MiddlemanにGoogleアナリティクスを導入

2017-11-25

目的

Middleman でサイトを運営しており、

Googleアナリティクスを導入するための Gem があったので、

Gemに慣れるために利用しました。

(scriptを埋め込むだけではあるのですが)

解決策

1. Gemfile に gem を追加する

middleman-google-analytics という Gem を利用しました。

$ vim Gemfile

追加した記載

gem 'middleman-google-analytics', '~> 2.0'

2. config.rb の修正

$ vim config.rb

下記の記載を追記します。

activate :google_analytics do |ga|
  ga.tracking_id = 'UA-XXXXXXX-X'
end

3. Middlemanのレイアウトに埋め込み

<% if build? %>
  <%= google_analytics_tag %>
<% end %>

参考

http://webfood.info/middleman-how-to-use-google-analytics/#configrb

Nginxでbasic認証を設定する

2017-11-23

目的

nginxでbasic認証のユーザーを追加した時のメモになります。

解決策

※ nginxの設定ですでにbasic認証が使えている状態とします。

ユーザの追加

$ sudo htpasswd /etc/nginx/.htpasswd [ユーザ名]

結果

New password:
Re-type new password:
Adding password for user [ユーザ名]

ユーザの削除

$ sudo htpasswd -D /etc/nginx/.htpasswd [ユーザ名]

結果

Deleting password for user hogehoge

ユーザの追加(新しいファイルにする)

$ sudo htpasswd -c /etc/nginx/.htpasswd [ユーザ名]

結果は -cオプションをつけない場合と同様になります。

※ -c オプションは既存の設定が上書きされてしまうので注意してください