Factoryパターン〜FactoryMethod〜

そこに、Factoryパターン一族

– Simple Factory[正確にはFactoryパターンではない]
– Factory Method
– Abstract Factory
の章があったので、
ぜひアウトプットしたく書きます!

今回はFactory Methodについてです!

Factory Method

オブジェクトを作成をカプセル化し、依存度を下げるために使います。
(Simple Factory、Abstract Factoryと同じ)

オブジェクト作成のためのインターフェースを
抽象クラス(スーパークラス)に定義しますが、
どのクラスをインスタンス化するかについてはサブクラスに決定させます

→抽象クラス(親クラス)は、
サブクラスの作成したオブジェクトを利用するだけで
具体的なオブジェクトが何なのかを知らない。

AbstractFactoryと違う部分
– 継承を使うので、サブクラス(子クラス)が
作成するオブジェクトの具体的な型を実装する。

 

クラス図でみるとこんな感じ

 

factoryMethodはサブクラスに任せるために、
Factoryクラス(スーパークラス)は抽象クラスになる。

クラス図からもわかるように、
Factoryクラス(スーパークラス)は
Prodoctオブジェクトを作成する具体的な方法は全く知りませんが、
factoryMethodを使えばProdoctオブジェクトを作成できることを知っています。
なので、anOperationメソッド内でfactoryMethodを使用することが多いです。

 

 

HeadFirstでは、
地域スタイルでピザの作り方が異なる
フランチャイズでの例がありました。

FactoryMethodのサンプルコード

 

クラス図はこんな感じ。

 

▶︎ PizzaStore(スーパークラス)
Pizzaオブジェクトを作成する具体的な方法は全く知りませんが、
createPizzaメソッドを使えばPizzaオブジェクトを作成できることを知っています。
→orderPizzaメソッド内でcreatePizzaを使用して実装している。

▶︎ NYPizzaStore(PizzaStoreのサブクラス)
具象Pizza(NYスタイル)オブジェクトを作成する

▶︎ChicagoPizzaStore(PizzaStoreのサブクラス)
具象Pizza(Chicagoスタイル)オブジェクトを作成する

▶︎ Pizza
抽象Pizzaクラス。
PizzaStoreのサブクラスにより、具象Pizzaオブジェクトが作成される。

└ NYCheesePizza 具象Pizzaクラス
└ NYClamPizza 具象Pizzaクラス
└ ChicagoCheesePizza 具象Pizzaクラス
└ ChicagoClamPizza 具象Pizzaクラス

 

メリット1:
地域ごとにピザメニューの作り方が異なっても大丈夫

地域ごとの具象PizzaStoreクラス、具象Pizzaクラスがある。
そのため、同じチーズピザでも、
NY店はゴーダチーズ、Chicago店はモッツアレラチーズにしたり
切り方はサブクラスでオーバライドするなど
多種多様に対応することができる。

 

メリット2:
ChicagoにあるけどNY出身者が多い地区のピザ屋にも対応可能

こんなクラスを作ればいい。
– ChicagoPizzaStore_ManyNewYorker.php

class ChicagoPizzaStore_ManyNewYorker extends PizzaStore
{
    public function createPizza(string $type): object
    {
        $pizza = null;
        if ($type == "チーズ(NY風)") {
            $pizza = new NYCheesePizza();
        } else if ($type == "チーズ(Chicago風)") {
            $pizza = new ChicagoCheesePizza();
        } else if ($type == "野菜(NY風)") {
            $pizza = new NYVeggiePizza();
        } else if ($type == "野菜(Chicago風)") {
            $pizza = new ChicagoVeggiePizza();
        }

        return $pizza;
    }
}

 
ピザ食べたくなりました。
やっぱりマルゲリータですよね。

 
 

Factoryパターン〜Simple Factory〜

この前、domicoのライブが宮崎であるというレアな事象ありました。
行かないわけにはいかないので、行ってきました。
めっちゃ、カッコ良いかったです。

 

早速ですが、私「増補改訂版Java言語で学ぶデザインパターン入門
を読んでますが、並行して楽しく読めると噂のこれも読んでいます。

そこに、Factoryパターン一族

– Simple Factory
– Factory Method
– Abstract Factory

の章があったので、
ぜひアウトプットしたく書きます!

今回はSimpleFactoryについてです!

Simple Factory

正確にはFactoryパターンではない!ですが便利なやつです。

サブクラスが複数存在する場合、
if文などで、各サブクラスをインスタンス化する
→ アプリケーション部分の各部分にif文が分散してしまったり、
保守と更新が困難になったり、実装の間違いが多くなるという問題があります。

 

したがって、
アプリケーション内で、
インスタンス化する部分(変化する部分)と変化しない部分
を分けてカプセル化する
というのがSimpleFactoryです。

 

SimpleFactoryのサンプルコード

こんなな感じかと思います。

 

上記でいうと、SimplePizzaFactory = SimpleFactoryになります。

 

▶︎PizzaStore

SimplePizzaFactoryのクライアント。
ピザをインスタンス取得しますが、
「ギリシャピザやクラムピザなどの具象ピザ」については知る必要がありません。
「pizzaインターフェースを実装したピザ(具象ピザ)を取得し、
prepareメソッド,bakeメソッド,…を呼び出せる」ことを知ってるだけで良い。
ピザを取得する事に関しては、SimplePizzaFactoryに任せるだけでOK!

 

▶︎SimplePizzaFactory

SimpleFactoryの主役。
ピザをの作成方法だけを扱うクラス。
具象Pizzaクラスを参照する唯一の部分。

 

▶︎Pizza

SimplePizzaFactoryの製品であるPizzaの抽象クラス。
具象ピザはこれを実装する。

└ VeggiePizza   具象ピザ(具象製品)
└ PepperoniPizza 具象ピザ(具象製品)
└ ClamPizza    具象ピザ(具象製品)
└ CheesePizza   具象ピザ(具象製品)

新作ピザの追加、ピザメニューの削除があっても。。。

大丈夫!

SimplePizzaFactory.php

- use HFD\SimpleFactory\Pizza\PepperoniPizza;
  use HFD\SimpleFactory\Pizza\ClamPizza;
  use HFD\SimpleFactory\Pizza\VeggiePizza;
+ use HFD\SimpleFactory\Pizza\GreekPizza;

function createPizza(string $type): object
{
        $pizza = null;
        if ($type == "チーズ") {
            $pizza = new CheesePizza();
-       } else if ($type == "ペパロニ") {
-           $pizza = new PepperoniPizza();
        } else if ($type == "クラム") {
            $pizza = new ClamPizza();
        } else if ($type == "野菜") {
            $pizza = new VeggiePizza();
+       } else if($type == "ギリシャ"){
+           $pizza = new GreekPizza();
        }

GeekPizza.php(新作ピザ)

+namespace HFD\SimpleFactory\Pizza;
+
+
+class GreekPizza extends Pizza {
+
+    public function __construct() {
+        $this->name = "ギリシャピザ";
+    }
+
+}

 

ピザの作成を
SimplePizzaFactoryに任せてるので、
SimplePizzaFactoryの修正と
新作ピザクラス(具象ピザ)の追加のみで対応できる。
さらに、PizzaStoreと分けているので
PizzaStoreには影響が少ない!

 

なによりシンプルでわかりやすいですね。

次は、FactoryMethodについて書きたいと思います!

Singleton(シングルトン)を使ってみる

 

今回は、ご存知デザパタの
第5章 Singleton 〜たった一つのインスタンス〜
について自分なりにまとめたいと思います。

 

シングルトンって音がかわいいですよね、「トン」とかがw

シングルトン(Singleton)とは

何も考えず、実装をしているとなんども同じインスタンスを生成しがちです。
・指定したクラスのインスタンスが絶対1つしか存在しないことを保証したい
・インスタンスが1つしか存在しないことを、プログラム上で表現したい

そんなときに、インスタンス生成コストを下げるためにも、
Singletonパターンを使います。

 

参考:
PHPで書き換えてくれてるソース
https://github.com/HappyDays-jQuery/GoF/tree/master/src/Singleton

 

 

こんな感じ

全体コード→https://github.com/kin29/DezaPata/pull/4/files

– Singletonクラス
– コンテキスト(使う側)

Singletonクラス

<?php

namespace DP\Singleton;

class Singleton
{
    /**
     * @var Singleton
     */
    //static宣言がされているため、
    //クラスのインスタンス化の必要なしにアクセスできる。
    //ただしprivateなので同クラス内のからしかアクセスできない
    private static $singleton;

    //privateなので、同クラス内からしかインスタンス生成をできない。
    //他のクラスからnew Singletonをするとエラーになる。
    //このクラスではgetInstanceがインスタンス生成をしている。
    private function __construct()
    {
        echo "create SingletonClassInstance\n";
    }

    //すでに$singletonにインスタンスがセットされている場合は、newしない。
    public static function getInstance()
    {
        //$singletonがstatic宣言されているため、
             //$this->singletonでアクセスできない。
        if (is_null(self::$singleton)) {
            self::$singleton = new Singleton();
        }
        return self::$singleton;
    }
}

 

 

contextSingleton.php ←コンテキスト(使う側)

<?php

use DP\Singleton\Singleton;

echo "Singletonクラスを普通にnewしてみる。\n";
new Singleton(); //たぶんおこられる。

外部クラスからnewすると
Singleton::__construct()がprivateなので怒られます。

$ php contextSingleton.php

Singletonクラスを普通にnewしてみる。
PHP Fatal error: Uncaught Error: Call to private DP\Singleton\Singleton::__construct() from invalid context in /Users/XXXXX/DezaPata/contextSingleton.php:10
Stack trace:
#0 {main}
 thrown in /Users/XXXXX/DezaPata/contextSingleton.php on line 10

 

 

contextSingleton.php ←コンテキスト(使う側)

<?php

use DP\Singleton\Singleton;

echo "getInstanceしてみる(instance1)\n";
$instance1 = Singleton::getInstance();
echo "もう一度、getInstanceしてみる(instance2)\n";
$instance2 = Singleton::getInstance();
echo "2回目のgetInstanceはインスタンス生成を行わないため、constructを通らないはず\n";
echo "(instance1 === instance2)なのか確認\n";
echo ($instance1 === $instance2) . "\n";

$ php contextSingleton.php

getInstanceしてみる(instance1)
create SingletonClassInstance
もう一度、getInstanceしてみる(instance2)
2回目のgetInstanceはインスタンス生成を行わないため、constructを通らないはず
(instance1 === instance2)なのか確認
1

Singletonクラスのインスタンスを得ることができるgetInsranceメソッドを
2回実行してみる。
1回目でインスタンス生成によりコンストラクラにて初期化でいを行い、
2回目はインスタンス生成していないことがわかる。
さらに、1回目と2回目のインスタンスは同じであることもわかる。

→ Singletonクラスは1つしか存在せず、
getInstanceで毎回同じSingletonクラスのインスタンスを得ることができました!!!

 

<<追記 2019-03-12>>

ただし、このままの方法ではタッチの差で、

if (is_null(self::$singleton))

判定をした場合には
インスタンスが1つ以上作られる可能性があります。

この対策としては二つがあります。
●同期化
●初期化時点でインスタンスを生成し、
getInstanceでは常にそのインスタンスを返すようにする。

class Singleton
{
    private static $singleton = new Singleton();

    private function __construct()
    {
        echo "create SingletonClassInstance\n";
    }

    public static function getInstance()
    {
        return self::$singleton;
    }
}

 

 

static宣言

HogeClass.php

class HogeClass
{
    public static $staticProperty = "staticなプロパティです。\n";

    public static function staticMethod()
    {
        return "staticなメソッドです。\n";
    }
}

 

staticなメソッド、staticなプロパティともに
インスタンス化せずとも外部からアクセスが可能である。

echo HogeClass::$staticProperty;  //staticなプロパティです。
echo HogeClass::staticMethod();   //staticなメソッドです。

 

HogeClass内からのアクセスもself::で行う。
$this->で行うと、エラーとなる。

PHP Fatal error: Uncaught Error: Using $this when not in object context in

 

※注意!

staticなプロパティはインスタンス化されたクラスオブジェクトから
アクセスすることはできない(static なメソッドにはアクセスできます)。

$HogeObj = new HogeClass;
echo $HogeObj->staticProperty;
//PHP Notice:  Accessing static property HogeClass::$staticProperty as non static in...
echo $HogeObj->staticMethod();   //staticなメソッドです。

 

 

イテレーターを(iterator)を使ってみる

 

今回は、ご存知デザパタの
第1章 Iterator 〜1つ1つ数えあげる〜
について自分なりにまとめたいと思います。

 

イテレーター(iterator)とは

何かの集合体を、数える人
→ 何かの集合体(=aggregate)つまり数える対象が必要
→ 何かの集合体(=aggregate)がいてこその役に立つ

参考:
PHPで書き換えてくれてるソース
https://github.com/HappyDays-jQuery/GoF/tree/master/src/Iterator

 

※PHPでは組み込みで複数のインターフェースがあるので便利!
Iteratorインターフェース
IteratorAggregateインターフェース ..など

何かの集合体(aggregate)と、それを数える人(iterator)を別クラスにすることで、
役割分担ができ、疎結合になる。
→ ただし、aggregateとiteratorを別にする必要がない場合は、
両方の役割をもつIteratorAggregateを使うこともできる。

 

こんな感じ

全体コード→https://github.com/kin29/DezaPata/pull/2/files

– Bookクラス
– BookShelfクラス(=aggregate)
– BookShelfIteratorクラス(=iterator)
– コンテキスト(使う側)

BookShelf(集合体)の中にBook(要素)があり、
BookShelfIteratorが本を一つ一つ数えていく感じです。

BookShelfクラス

<?php

/**
 * 何か(=本)の集合体[Aggregate]
 */
class BookShelf
{
....
    public function getIterator(): BookShelfIterator
    {
        return new BookShelfIterator($this);
    }
}

コンテキスト(使う側)

<?php 

$bookShelf = new BookShelf();
$bookShelf->appendBook(new Book('星の王子様'));
$bookShelf->appendBook(new Book('かいけつゾロリ'));
$bookShelf->appendBook(new Book('ミッケ!'));
$bookShelfIt = $bookShelf->getIterator();

while ($bookShelfIt->hasNext())
{
    echo $bookShelfIt->next()->getName() . "\n";
}

実行すると、appendした本の名前が入れた順番に1つずつ表示されます。

$ php contextIterator.php
星の王子様
かいけつゾロリ
ミッケ!

 

イテレータのいいところ

何かの集合体(=aggregate)や数え方(=iterator)を変更しても、
イテレータを使う側には変更の必要がない。

例)
変更前:数え方→集合体へ要素を追加した順番(FIFO)
変更前:数え方→集合体へ要素を追加した逆の順番(FILO)

<?php 

namespace DP\Iterator; 

/**
 * 何か(=本)の集合体を数える人[Iterator]
 *
 * Class BookShelfIterator
 * @package DP\Iterator
 */ 

class BookShelfIterator {

    private $bookShelf;
    private $index;
  
    public function __construct(BookShelf $bookShelf)
    { 
        $this->bookShelf = $bookShelf;
-       $this->index = 0;
+       $this->index = $this->bookShelf->getLength() - 1;
    }

    public function hasNext(): bool
    {
-       return $this->index < $this->bookShelf->getLength();
+       return $this->index >= 0;
    }

    public function next(): Book
    {
        $book = $this->bookShelf->getBookAt($this->index);
-       $this->index++;
+       $this->index--;
        return $book;
    }
}

実行結果

$ php contextIterator_FILO.php
ミッケ!
かいけつゾロリ
星の王子様

 

イテレータ、便利だしスマートですね!

しかし未だ、これイテレータパターン使えるっ
って言う場面に直面したことがないので、
何か集合体を見つけては、ソースに落とし込むとかして
そういう直感を養っていこうと思います。

デザインパターン入門を読み始めました。〜GoFとは〜

 

有名なやつですね。

存在はもちろん知っていましたが、
難しそうという思い込みで読んでいませんでした。

読まなくては!といういい機会をいただき読み始めました。
入門なのもあり、Javaを知らない私でも意外に読める感じでした!
(思い込みはだめですね。)

 

PHPerな方が、この本と一緒によむといいのが、
デザパタをPHPで書いてくれてるやつ → HappyDays-jQuery/GoF

 

今回は、この本の導入部分のまとめを
自分なりに書いていきたいと思います。

 

GoF(ゴフ)とは

\「GoF」ってよく聞くけど、なんですか?/
という、私の初歩的な疑問がありました。
「はじめに」部分に詳しく書いてくれてました。

開発する上でのよくあるパターンを「デザインパターン」という形で整理したのが、
GoF(ゴフ)と呼ばれた4人だそうです。※GoF = the Gang of Fourの略

もっと詳しく言うと、このGoFにより
オブジェクト指向における再利用のためのデザインパターン
という本がかかれました。
この本では、23個のデザインパターンに「名前」をつけ、
「カタログ」としてまとめられています。

 

–まとめ–
GoF(ゴフ)とは、
デザインパターンを整理してくれた4人の人たちの名称。

 

デザインパターンを学ぶ前に

デザインパターンとは、クラスやインターフェースの関係性である。

デザインパターンの目的は、プログラムを再利用可能なものにすること。
→プログラムを部品として再利用すること
→プログラムを常に、機能拡張や変更を加えていくものとして見る必要がある。

なので、デザインパターンの理解を深めるためには以下を考えると良い。
・どんな機能が拡張される可能性があるか
・その拡張が行われると、修正が必要になるクラスはどれか
・逆に、修正が不要なクラスはどれか

 

また、役割を理解する必要がある。
この本では、デザインパターンをドラマに例えて整理しています。

– 白雪姫(というドラマ) … デザインパターン
– 白雪姫(登場人物) … クラスA
– 王子様(登場人物) … クラスB

白雪姫には、りんごを食べて永遠の眠りについてしまうという役目があるように、
クラスAは役割がある。
また、王子様には、白雪姫にキスをして目覚めさせるという役目があるように、
クラスBには役割がある。
白雪姫が眠らなければ王子様も役目を果たせないように、
し役割をまっとうする必要がある。
登場人物全員が役割を果たしてドラマができあがるように、
デザインパターンもできるという感じでしょうか。

 

次は、第1章Iteratorについてまとめたいと思います!

 

PHP7.3からbreakの代わりにcontinueを使うとWarningになる。

最近PHP7.3にしました!
すると、以下のエラーで大好きなcomposerが使えなくなりました。

 "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?  

Google翻訳さんを使って、
「continue」ターゲティングスイッチは「break」と同じです。 “continue 2″を使用するつもりでしたか?
的なことをいってるみたいだなとわかりました。

 

( 解決策はQiitaに書いてます! )

composer installができなくなった時の解決法(PHP7.3)

 

 

そこでまず、
▶︎PHP7.3から、continueをbreakの代わりに使うと、Warningになる?
▶︎continue 2とは?使ったことない!
と私は直感で思いました。

 

 

よくわからなかったので、

とりあえず、やってみます。

参考:https://blog.ohgaki.net/php-7-3#continue

$ php -v
PHP 7.3.1 (cli) (built: Jan 10 2019 13:15:37) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.1, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.1, Copyright (c) 1999-2018, by Zend Technologies

 

test_continue.php

<?php
//$month = 1;を想定

for ($day = 1; $day <= 31; $day++) {

    $message = "{$day}日は、";
    switch ($day) {
        case 1:
            $message .= "月初\n";
            continue;  //break;と同じらしい
        case 15:
            $message .= "月のど真ん中\n";
            continue;
        case 31:
            $message .= "月末\n";
            continue;
        default:
            $message .= "なんともいえない日\n";
            continue;
    }

    echo $message;
}

 

いざ、実行!

$ php test_continue.php 
PHP Warning:  "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /Users/kin29/php7_3/test_continue.php on line 11
...
/Users/kin29/php7_3/test_continue.php on line 14
...
/Users/kin29/php7_3/test_continue.php on line 17
...
/Users/kin29/php7_3/test_continue.php on line 20
1日は、月初
2日は、なんともいえない日
...
15日は、月のど真ん中
16日は、なんともいえない日
...
31日は、月末

やはり、warningでてますねえ。
おっしゃる通りにcontinue→breakにしてみる。

test_break.php

<?php

//$month = 1;を想定

for ($day = 1; $day <= 31; $day++) {

    $message = "{$day}日は、";
    switch ($day) {
        case 1:
            $message .= "月初\n";
            break;  //continue;と同じ動作をするはず
        case 15:
            $message .= "月のど真ん中\n";
            break;
        case 31:
            $message .= "月末\n";
            break;
        default:
            $message .= "なんともいえない日\n";
            break;
    }

    echo $message;
}

breakで実行すると、
warningも出ず、continueの時と同じ挙動のようです!!!

$ php test_break.php 
1日は、月初
2日は、なんともいえない日
...
15日は、月のど真ん中
16日は、なんともいえない日
...
31日は、月末

そもそも、switchには普段からbreak使ってます。
なんとなくcontinueを使わず、break使ってましたが、それが正しいようです。

ではcontinueの使い時は?continue 2とは?
の確信につきたいと思います。

 

test_continue_2.php

<?php 

//$month = 1;を想定

for ($day = 1; $day <= 31; $day++) {

    $message = "{$day}日は、";
    switch ($day) {
        case 1:
            $message .= "月初\n";
            break;
        case 15:
            $message .= "月のど真ん中\n";
            break;
        case 31:
            $message .= "月末\n";
            break;
        default:
            $message .= "なんともいえない日\n";
            continue 2; //抜けるループのレベル指定
    }

    echo $message;
}

 

さっそく実行!

$ php test_continue_2.php 
1日は、月初
15日は、月のど真ん中
31日は、月末

continueに引数を使うと、抜けるループレベルが指定できるようです。
今回の例でいくと、breakやcontinue(引数なし)ではswitch文しか抜けません。
ただし、continue 2(引数あり)とするとfor文からも抜けだすことができます。

 

まとめ

breakとcontinue(引数なし)は同じ意味なのに、別で存在しているので統一させたい。
あんど、continueは引数ありで使うべきと言いたいんでしょうか。
(そう私は解釈しました。)

短縮URL取得ボタンを記事編集画面に設置する。

 

わたし、ブログ書いたらTwitterに書いたよーって
宣伝してるんですが、その時のURLが長くてきもいって
言われたり思ってたりしてたので、
短縮URL取得ボタンを記事編集画面に設置しました。

なのでこの度、
\短縮URLをTwitterに貼れるようになりました!/

 

参考:https://tamore.net/add-shorturl-button/

 

before

 

after:パーマリンク横に「短縮URL取得」ボタンが追加されました!

 

●やり方

wp-content/themes/twentyfifteen/functions.php

の終了行に以下を追記するだけです!
わたしの場合、使用していたテーマがTwentyFiftyなのでtwentyfifteen/以下のfunction.phpをいじります。
ご使用のテーマに合わせてください。

/**
 * 「短縮 URL を取得」ボタンを編集画面に表示させる
 */
add_filter( 'get_shortlink', function( $shortlink ) {return $shortlink;});

 

wp-admin/edit-form-advanced.phpを見てみると、
「短縮URLの取得」ボタンはデフォルトで隠してるみたいですね。

wp-admin/edit-form-advanced.php

// As of 4.4, the Get Shortlink button is hidden by default.
if ( has_filter( 'pre_get_shortlink' ) 
    || has_filter( 'get_shortlink' ) ) {
   $shortlink = wp_get_shortlink($post->ID, 'post');

   if ( !empty( $shortlink ) 
        && $shortlink !== $permalink 
        && $permalink !== home_url('?page_id=' . $post->ID) ) {
      $sample_permalink_html .= '<input id="shortlink" type="hidden" value="' 
            . esc_attr( $shortlink ) 
            . '" /><button type="button" class="button button-small" onclick="prompt(&#39;URL:&#39;, jQuery(\'#shortlink\').val());">' 
            . __( 'Get Shortlink' )
            . '</button>';
   }
}

 

 

●感想

こんな簡単だったのかとびっくりしました。

ただ、Twitterカードの表示確認ツール「Card validator」で確認してみると、

WARMでてる・・・見逃していいやつですか・・・?

Firebaseを触ってみる!

今年末くらいから、Firebaseというワードを頻繁に耳にします。
なのでちょっとやってみました。

 

今回作ってみたのはFirebaseのCodelabにある
FriendlyEatsです。
Firebaseのサービスの一つであるCloud Firestore(DBみたいなやつ)を
使ったレストランオススメアプリです。

作ったと言っても、ソースはいじってません!

Firebase管理画面コマンドの操作のみです。

 

参考にしたのはこちら▽
https://github.com/firebase/quickstart-js/blob/master/firestore/README.md

 

1.Firebaseプロジェクトの作成

FirebaseConsoleより、Firebaseプロジェクトを追加します。

 

2.ユーザ認証方法の設定

FirebaseConsole >Authentication >ログイン方法 >ログイン プロバイダより、
「匿名」認証を有効にします。

ソースをいじれば、
GoogleとかTwitterユーザでの認証も利用できそうですね!

 

3.データベースの設定

FirebaseConsole > Databaseより、
Cloud Firestoreを選択し、データベースを作成する。
セキュリティルールは、ロックモードとテストモードがあります。
テストモードを選択します。

データベース作成後、ルールをみてみると、
「誰でもデータベース内のデータを窃取、変更、削除できる」状態です。

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

本来であれば危ないので設定するべきですが、今回はしません。

 

現段階では、DB空っぽです。

 

4.ソースをクローンする

git clone https://github.com/firebase/quickstart-js.git

 

5.FirebaseのCLIをインストールします。

$ npm -g i firebase-tools

 

6.FirebaseのCLIにプロジェクトをセットする

プロジェクトIDを選択して、エイリアス名を設定します。

$ cd firestore/
$ firebase use --add
? Which project do you want to add? [プロジェクトID]
? What alias do you want to use for this project? (e.g. staging) [エイリアス名]

Created [エイリアス名] eats for [プロジェクトID].
Now using alias [エイリアス名] ([プロジェクトID])

プロジェクトIDは、設定>全般>プロジェクト にあります。

 

7.Firestore(DBみたいなやつ)の
セキュリティルールとインデックスをデプロイする

$ firebase deploy --only firestore

 

8.ローカルサーバを立てて、ブラウザで確認をします。

$ firebase serve

http://localhost:5000でローカル環境でチェックできます。

 

ブラウザを開くと、こんな画面がでます。

 

http://localhost:5000/setup にアクセスして、

「ADD MOCK DATA」を押下するとモックデータを追加することができます。

 

押した後、こんな感じです! (データどっさり。)

 

FirebaseConsole  > Databaseをみてみます。


データがちゃんとはいってることが確認できました。

● 本番環境にデプロイする場合

firebase deploy

 

最後に

理解はまだまだ浅いですが、次は何かオリジナル作ってみたいです。

↑をしたら、また記事書きます!!

 

よりハイテクなブレース展開をしてみたいので、Bashのバージョンを4系にする!(Mac)

 

あけおめ、ことよろです!
「あけよろ」とかいうみたいですね、最近は。

 

基本情報技術者試験の勉強をしていましたら、
「ブレース展開」
とやらを初見しました。

解説を読んでみると、、、

UNIXの機能で、任意の文字列を生成するために使用されます。
たとえば、まとめてファイルやディレクトを生成するときに使われます。

とのこと。よくわからん!

「UNIX機能ってことはコマンドで試せるのでは?」と思い、ググりました。
その結果、コマンドで実際に試せるようでした!

あと、過去記事で「ブレース展開」っぽいことはしてますね。
seqを使ってワンライナー書くよ。

 

さきにまとめると、

ブレース展開 ≒ seqコマンド です。

ただし、seqコマンドでは各出力文字が改行されます。

▶︎ブレース展開

$ echo {1..4}
1 2 3 4

▶︎seqコマンド

$ seq 1 4
1
2
3
4

 

 

解説にあった、

まとめてファイルやディレクトを生成する

って、実際にやってみると、こういうことなんでしょうね。

$ touch test{1..5}      #ファイルを作成
$ ls
test1	test2	test3	test4	test5
$ rm -rf test{1..5}   #いらんので消す
$ ls

 

 

 

bashのバージョンが4系(※導入方法は下に書いてます)になると、
インクリメント数の指定もできるようになります。

echo {1..10..2}  #最小値1、最大値10、増加数2
1 3 5 7 9

seqコマンドでいうと、こんな感じですね。

$ seq 1 2 10
1
3
5
7
9

 

 

こんな感じで、理解できない用語は実際にやってみると理解深まるな〜

と改めて感じたそんな日でした。

 

[ 付録 ] Macでbashのバージョンを4系にする方法

<導入環境>
– Mac
– bash 3系

$ brew upgrade bash

$ brew info bash   #4系が導入されたことを確認します。
bash: stable 5.0.0 (bottled), HEAD
Bourne-Again SHell, a UNIX command interpreter
https://www.gnu.org/software/bash/
/usr/local/Cellar/bash/4.4.19 (146 files, 8.8MB)
  Poured from bottle on 2018-03-23 at 12:55:33
/usr/local/Cellar/bash/4.4.23 (146 files, 8.8MB)
  Poured from bottle on 2019-01-07 at 21:42:09
/usr/local/Cellar/bash/5.0.0 (150 files, 9.4MB) *
  Poured from bottle on 2019-01-08 at 21:37:06
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/bash.rb
==> Options
--HEAD
	Install HEAD version
==> Caveats
In order to use this build of bash as your login shell,
it must be added to /etc/shells.
==> Analytics
install: 10,644 (30 days), 36,411 (90 days), 188,613 (365 days)
install_on_request: 8,577 (30 days), 29,862 (90 days), 146,626 (365 days)
build_error: 0 (30 days)

$  ls /usr/local/Cellar/bash
4.4.19	4.4.23	5.0.0

 

今まで使ってたbashをバックアップ的に残しておく。

$ sudo mv /bin/bash /bin/bash_old
$ sudo mv /bin/sh /bin/sh_old
$ sudo chmod a-x /bin/bash_old /bin/sh_old

 

bashの4系にシンボリックリンクを新しく登録する。

$ sudo ln -s /usr/local/Cellar/bash/4.4.23/bin/bash /bin/bash
$ sudo ln -s /usr/local/Cellar/bash/4.4.23/bin/bash /bin/sh

 

バージョンを確認→4系になっていることを確認。

$ echo $BASH_VERSION
4.4.23(1)-release
xxxxxx:/usr/local/Cellar$ /bin/bash --version
GNU bash, バージョン 4.4.23(1)-release (x86_64-apple-darwin18.0.0)
Copyright (C) 2016 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.