2016振り返りと2017目標
毎年恒例になってきた。
2015振り返りと2016目標
Run
- 目標
- 600km ( 月50km )
- 結果
- 274km ( 月50km達成は1ヶ月 )
- 昨年との差3.1km
- もしかしたら、270kmくらいが自身の限界なのか?!
- 4月にジムに入会し、出社前にトレッドミルのランに挑戦したが3ヶ月目で失速
- 出社前にジムにいくという習慣を2ヶ月くらい続けられたのは楽しかった
Learn ( TOEIC )
- 目標
- over 600
- 結果
- 520どまり
Learn ( Other )
- 目標と結果 ( 2015のブログから )
- 目標にない部分
他に年始に考えていた事
- 環境変化
- 2016/7に引っ越し
- 2016/11より新しい職場への転職
- 家族
2017目標
- 追記予定
雑感
いろいろ考えながら振り返ってたら考えがまとまらず時間オーバー
続きは近日
今年の書き初めはPHPでした
PHP5.4から利用できるTrait(Scalaでも同名)とInterfaceを利用した場合、 お作法としてTraitとInterfaceはセットで定義しておく。
理由としては、Traitは型宣言に利用できない(タイプヒント出来ない)為、 メソッドが特定の型を要求する場合は、タイプヒントする為にInterfaceを定義しておく必要がある。 (独習PHP10.5.4より参照で、この文の意味が理解不足)
・型を継承するインターフェース
・実装を継承するトレイト
この違いは理解したと思うが、メソッドが特定の型を要求する場合の為にInterfaceを定義しておくという 説明についてはコードレベルで理解出来ていない。
<?php // 型を定義 interface IFax { function send(); } interface IPrinter { function printer(); } // 実装を定義 trait FaxTrait { public function send() { print 'sending Fax...sended!'; } } trait PrinterTrait { public function printer() { print 'printing ... complete!'; } } class FaxPrinter implements IFax, IPrinter { use FaxTrait, PrinterTrait; } $fp = new FaxPrinter(); $fp->send(); $fp->printer();
AppleWatchを活かしたい
ただそれだけ。
最近は完全にSuica端末になりきっているAppleWatch。
走っているときはRunkeeperの子機として十分に役立つが、日常生活では?
完全にFitbitが一枚上手。なぜかといえばバッテリーライフの関係から、睡眠中もつけていられる。
そうなると、睡眠時間のデータもFitbitに入るため、つけない訳にはいかなくなる。
そんな中、社内LTを行うという事があり、これはチャンスと実装をした。
家の近くのバス停に到着するバスの時間を、Webページから取得しWatchに表示するだけの機能。
実際にやってみるといろいろハマった。
ハマったこと
- そもそもiOS / watch OSと複数のターゲットが存在する(CodeSigning)
- table view とラベルの紐付け
- watch OSのデバッグは(process を atach する必要がある)
- Cocoa Pods を利用する場合は、xxx.xcodeproj -> xxx.xcworkspace を利用する
- Httpクライアント(Alamofire)の利用方法
- HTML parser(Kanna)の利用方法
- 取得したいページがhttpなので、ATS無効
- 実機で確認する為のXcode + iPhone + Apple Watchの設定というかデバッグする為の設定
- Apple Watch のイベント(awake -> willActive -> didDiactive)
このあたりは細かくブログに書きたいが、今日はクリスマスという事で家族との時間に充てる。
PHPでTemplate Method パターン
DBへの接続オブジェクトを継承した各テーブル毎のクラスでinsert() / update() 実装を想定
- ハリウッドの法則
- 親クラスが子クラスのメソッドを必要なタイミングで呼ぶ
- 今回でいくと、regist(親クラス)から子クラスで実装したinsert / update をcallする
- 同じ処理を集約し、抽象クラス、抽象メソッドとしてインターフェースを用意する
<?php // DBへの接続、validateを行うようなDB処理のスーパークラスを想定 abstract class DBObject { private $target_object; public function __construct($obj) { $this->target_object = $obj; } public abstract function insert(); public abstract function update(); public function regist() { if ($this->target_object->id) { $this->update(); } else { $this->insert(); } } } // 各テーブルへの実装を、具象クラスでテーブル毎に行う想定 class ObjectA extends DBObject { public function insert() { // insert 処理 echo "--insert--" , PHP_EOL; } public function update() { // update 処理 echo "--update--" , PHP_EOL; } } // 実際に利用する場合は、idの有無でinsert / update を判定する事を想定 $sample = new stdClass(); $sample->id = 111; // idがありのため、updateを行う //$sample->id = null; $obj = new ObjectA($sample); $obj->regist(); // cliantからはオブジェクトを生成し、registメソッドをcallするのみ。
雑感
さっと思った事を実装してみたが、Template Methodパターンにマッチする仕様なのか不明な部分が残る
他パターンをサンプル実装していく中で、戻って修正する事もあると思う
何か気になる箇所があったら是非コメント下さい
PHPでStrategyパターン
使うメリット
- メール、SMS、プッシュ通知、今後増える可能性がある通知手段を、他実装に影響せず追加が行える
2016/12/11 に追記し、本記事最下部に変更したソースあり
<?php // 抽象クラス abstract class MessageStrategy { public abstract function send(); } // コンテキストクラス class MessageContext { private $strategy; public function __construct(MessageStrategy $message) { $this->strategy = $message; } public function send() { $this->strategy->send(); } } // 具象クラス class ConcreteMailMessage extends MessageStrategy { public function __construct() { // 前処理 } public function send() { echo 'mail'.PHP_EOL; } } class ConcreteSMSMessage extends MessageStrategy { public function __construct() { // 前処理 } public function send() { echo 'sms'.PHP_EOL;; } } class ConcretePushNotificationMessage extends MessageStrategy { public function __construct() { // 前処理 } public function send() { echo 'push'.PHP_EOL;; } } $strategy = new ConcreteMailMessage(); $contextMessage = new MessageContext($strategy); $contextMessage->send();
これから調べる事
- 送信時にユーザクラスからmail/tel/token などを取得したいが、どのクラスで行うか
- Userクラスに依存するので、Strategyパターンを使うのではなく、違うパターンが正解かもしれない
追記 2016/12/11
- Uesrクラスは具象クラスにコンストラクタインジェクションする事にした
- コンストラクタで注入する事で、各通知処理の前処理が行えると考えた
- 仮にアプリユーザというクラス(mail / name を持たずtokenだけ持つクラスを利用する事があっても、具象クラスのみ影響があるため、他クラスは影響を受けないと考えた
- テストコードを追加したい
<?php // 送信対象のUserクラス class User { private $name; private $mail; private $tel; // 仮に利用するpropertyを定義 public function __construct($name, $mail, $tel) { $this->name = $name; $this->mail = $mail; $this->tel = $tel; } // 仮に名前だけ出力するためにgetter設置 public function getName() { return $this->name; } } // 抽象クラス abstract class MessageStrategy { protected $user; public abstract function send(); public abstract function __construct(User $user); } // コンテキストクラス class MessageContext { private $strategy; public function __construct(MessageStrategy $message) { $this->strategy = $message; } public function send() { $this->strategy->send(); } } // 具象クラス(Mail) class ConcreteMailMessage extends MessageStrategy { public function __construct(User $user) { $this->user = $user; // mailに関する前処理 // ... } public function send() { echo 'mail->to('. $this->user->getName(). ')'. PHP_EOL; } } // 具象クラス(SMS) class ConcreteSMSMessage extends MessageStrategy { public function __construct(User $user) { $this->user = $user; // smsに関する前処理 // ... } public function send() { echo 'sms->to('. $this->user->getName(). ')'. PHP_EOL; } } // 具象クラス(PushNotification) class ConcretePushNotificationMessage extends MessageStrategy { public function __construct(User $user) { $this->user = $user; // Push通知に関する前処理 // ... } public function send() { echo 'push->to('.$this->user->getName(). ')'. PHP_EOL; } } // 送信対象のテストUserインスタンス $user = new User('Pさん', 'test@example.com', '090xxxxyyyy'); // Mail送信 $strategy = new ConcreteMailMessage($user); // $strategyにどのクラスを代入するかでMail / SMS / PushNotification とsend()の振る舞いを変える // SMS送信 // $strategy = new ConcreteSMSMessage($user); // Push通知 // $strategy = new ConcretePushNotificationMessage($user); // Contextクラスにstrategyクラスを注入 $contextMessage = new MessageContext($strategy); // 送信処理 注入されたオブジェクトのsend()メソッドをcall $contextMessage->send(); // mail->to(Pさん) と出力される
TravisCIで実行したPHPUnitの結果がCoverallsに反映されない
TravisCI Build時のRowLogで、environment variablesをSetしろの文言あり。
Read environment variables Requirements are not satisfied. - TRAVIS='true' - TRAVIS_JOB_ID='1713xxxxx' - CI_NAME='travis-ci' - COVERALLS_REPO_TOKEN='********(HIDDEN)' Set environment variables properly like the following. For Travis users: - TRAVIS - TRAVIS_JOB_ID
対応としてTravisCIのEnvironment VariablesにSet
TravisCI Repository > Settings > Environment Variables
参考:php-coveralls issue
export CI_BUILD_NUMBER="$TRAVIS_BUILD_NUMBER" export CI_PULL_REQUEST="$TRAVIS_PULL_REQUEST" export CI_BRANCH="$TRAVIS_BRANCH"
こういう場合は、UIからではなく、.travis.yml の before_script; にexport書くのが良いのか。