HONDAのAndroid アプリ, Web アプリ開発備忘録

このブログはHONDAがAndroidアプリの開発開始と同時に作成したもので備忘録として記しています。最近Web系に就職が決まったのでwebアプリも勉強していきます。

PHPerKaigi2019レポート

最初に

PHPerKaigi2019に参加したので、そのレポートとして聞いたセッションの内容を書きます。

 

前夜祭

15分でわかった気になるGraphQL

https://speakerdeck.com/ichikawa/15fen-defen-katutaqi-ninarugraphql

  •  GraphQLとは
    ウェブAPIの規格の一つ。RESTの問題を解決するためのクエリ言語
  • RESTの問題とは 
    • アプリケーションで求めているデータと、APIレスポンスの乖離
    • オーバーフェッチング:クライアントの必要なものに対して余計なデータをAPIで返してしまう等
    • アンダーフェッチング:オーバーフェッチングの逆。レスポンスに対して情報量が足りないので別APIを叩いて取得する必要があり、ラウンドトリップが多くなる
    • ↑二つの問題を解決しようと、エンドポイントを乱立させてしまう可能性もある
  • どうやって解決するの?
    • GraphQLはクエリとレスポンスの構造が似ているので、クエリを見ればレスポンスが推測しやすい
    • エンドポイントも増加しないし、ラウンドトリップも抑えることもでき、オーバーフェッチングも解決する
  • 長所
    • データ構造が理解しやすいし、ラウドポイントも抑えられる
    • クライアントとサーバ間の型安全なコミュニケーションが可能
    • 豊富な開発ツールがある。
  • 短所
    • いくつかの処理はRESTより面倒になる可能性がある。
    • ファイルのアップロードやエラーハンドリング(Statusは200で帰るため)
    • クエリはPOSTがおおいのでCDNなどキャッシュ等も考慮は必要
    • パフォーマンス面ではone-to-manyなどのデータを取得するような場合、N+1問題が発生してしまう可能性がある。

質疑応答

Q:GraphQLとRESTを共存は可能ですか?
A:可能。既存のRESTAPIをのこしつつ、部分的にGraphQLに置くなどやってます。ファイルアップロードが苦手なので、そこはRESTにしてしまう等そういうこともできる。
Q : REST APIだとキャッシュの生きる時間を決めれるとかはできるが、クライアントサイドのキャッシュGraphQLにはあるのか
A : アポロとかはあるが、サーバーサイド側がきめるキャッシュについては不明

 

質の良いユニットテストを書くためのプラクティス

https://speakerdeck.com/hgsgtk/practices-to-write-better-unit-test

  • なぜテストをするのか

    •  "質"について定義:費用対効果の高い

    • 品質向上、バグを防ぐ

    • テストに依るドキュメンテーション化、設計改善の指標にする等、テストをするには、様々な"コスト削減がある"

  • ユニットテストによるコスト削減

    • 手動ユニットテストのコスト削減

    • 欠陥の早期発見(バグを防ぎたい

    • 単体仕様書などのかわりにテストを設ける

    • デバッグコストの削減

    • 設計改善などメンテナンスコスト

  • 逆にテスト自体のコスト

    • 新規テストの作成コスト

    • 既存テスト維持コスト

    • テスト実行時間の待ち時間のコスト

    • 自動テストのためのCI維持コストや学習コスト

  • テストの経済性:最初のうちははテスト自体のコストで膨らむが、時間がたつに連れて自動化などによりコストが減っていく

  • テストの非経済性:テストの可読性が悪い、そもそもテストの修正が難しいなどがある。など, テストに依る節約コストも少ないと結果的にしんどい

  • いかにコストを削減するか。

    • 意図を伝えるテスト(ドキュメンテーションコストやデバッグコスト、既存テストが期待される):
      テストとはメンテナンスされていき、読み手にとって理解しやすくメンテナンスしやすいテストへ変わっていくべきである。

      • ユニットテストがない場合

        • 動作コードを読んで理解、ドキュメントや、blameとか

        • 動作コードを読むときに複雑だとしんどい、ドキュメントそもそもないとか古いとか

        • 対象だけ動かすのが難しいとか繰り返し実行するのも手間

        • 作成者がそもそもいない場合、もある
          ユニットテストがある場合、対象だけ動かすことも可能だし、ドキュメントの代わりにもなる。そしてテスト自体読めばだいたい中身は理解可能

    • テストは読み書きする上でシンプルであることは重要:一回に付き一つのことをテストする
      ポイント:”テストを書くことではなく、テストをすることが重要”
      そのためには:意図と、期待値を伝えるための命名、ラベリングが必要で、読み手に親切にすべき
    • テストを独立させる
      • SUTに対して疎結合にするべき
      • SUT:テストしている対象を示す(System Under Test):ユニットテストの場合、テスト対象のクラスやメソッドなど
      • クラス感の密結合はテストにおいて問題になりうる。
      • SUTをブラックボックスとしてみるべきで、ブラックボックスの外から見えるPublicMethodに対して、テストするのがBetter
      • 見えないもの(Private method)に対してテストするのは???
        • プライベートメソッドは変更頻度が高い。変更頻度がたかいものはメンテナンスコストの増大になる。
        • 基本的にはパブリックメソッドでプライベートメソッドは使われるので、パブリックメソッドをテストして大丈夫であれば、大丈夫なはず
      • テスト感の独立
        • テストが独立する場合、「ローカルでは通るがCIでも通らない」など
        • 順序依存するテスト
          • Fixtureを用いる。全テストケースで共有するFixtureを使うなど、
    • 重複を最小限に
      • DRY(Don't Repeat Yourself)
    • テストの可読性を上げる
      • テスト容易な設計
      • TDDが例として挙げられる。動作するきれいなコードがゴール。Red Green Refactoringのサイクルをまわす。
      • テストファーストによって、テスト容易性が矯正される。なぜならテストから先に書くので、基本的な欠陥はテスト実行によって気づくことができる

質疑応答

Q: 重複をなるべくDRYでやるということだが、DRYでやりすぎるとデータの部分がDSKみたいになって何やってるかわからなくなりがち?

A:バランスが大事、わかりやすさに寄せてテストに書くべきだと思う。ある程度冗長的なことも許容する
Q:このプライベートメソッドだけは確認すべきだとある場合がある。
A:やりたいと思ってる段階で、プライベートにするべきではない、つまり責務が存在しているので、メソッドは切り出すべき

Q:プライベートメソッドの変更の頻度といってもいろんな種類の変更があるがどれも一緒?
A:外に影響があるかないかがまず、見分けるポイント

1日目

PhpStorm30分集中超絶技巧

https://speakerdeck.com/yusuke/phpstorm30fen-ji-zhong-chao-jue-ji-qiao-number-phperkaigi-number-a

  • 基本設定
    • キーマップはデフォルト:ペアプロがはかどる
    • 開発はUSキーボード、[入力ソース]半角英数を使うとショートカットが衝突しちゃう
    • タッチバーよりファンクションキーのほうが高機能
    • キーボードのショートカット、前の入力ソースを選択を無効化
  • 検索:シフト二回押すと、どこでも検索
  • ↑のシフト二回はやや重い!のでどこでも実行のCtrlを二回
  • ナビゲーション超絶技巧
    • プロジェクトペイン:cmd+1
    • 戻るときはエスケープ
  • ファイル切り替え
    • cmd + e : 最近開いたリストが開く
    • shift+cmd+e: 最近編集した場所の周辺に戻れる
    • 一つ前のファイル:ctrを押してtab一回おす
  • 編集した箇所にジャンプ: Shift + Cmd
  • 定義箇所でCmd + Bで使用箇所が出てくる
  • 特定の行に飛ぶときはコマンド lで飛べる
  • Cmd+Oでクラス検索
  • 「kernel:15」でジャンプすれば15行目でジャンプできる
  • 補完
    • tab、エンターの違い:エンターは挿入される、タブは置換して補完完了なので通常はタブキー
  • ステートメント完結:"とか書くと閉じるとかある、セミコロン打つときまたがないといけない
    →Shift + Cmd + enterおすと文法が通る形にしてくれる
  • Live Templates
    • thr + tabでthrow
    • fore + tabでforeach
  • 式+ . + ifでif文にしてくれる
  • 変数名 + . + で変数に入れてくれる
  • Opt + enterで警告が出てくれる
    • sprintfやいろんな空気を読んでくれる

抽象化ってなに

https://speakerdeck.com/hidenorigoto/chou-xiang-hua-tutehe-what-is-abstraction-5057a1f2-24e5-4268-bf50-c8b706cc7013

  • 抽象化はわかりにくいことを指したり、不遇な扱いを受けている。
    →そもそも"抽象化"がどんなことかふわったとしているからこのような扱いをうけがち
  • "設計の問題はソースコードの中にこそある"
  • あるあるな事例
    • 逆転の原則、クラスとクラスの間にインターフェイスを挟む
    • 例えば、数独のチェックプログラムで、checkクラスとMtrixクラスがあったときにCheckableMatrixInterfaceを挟むなど。
  • 現実世界の抽象化
    • S. I. ハヤカワの抽象のはしごp173から
    • "目の前の一頭牛がいて、子供が生まれました。子供からの視点で、牛をみるとする。
      • 最初:いつもそこにある何かがある。ところから始まる
      • 一段抽象のはしごを登る。家族が「名前」を読んでいる(言葉で表す)、目の前のものを名前で読んでいるだけ、具体的じゃないの?
        →言葉だけが箚すものと個体に識別子を与えただけ
      • もう一段のぼる。それは他の家にもいて、似たようなやつでそれは「雌牛」という
        →眼の前の個体ではなく大きくなっている
    • 抽象化における変化
      • 特徴量は"多い"から"少ない"
      • 対象の数は"少ない"から"多い"に
    • 抽象レベルがおかしい文:"わたしは朝、私達の資産に餌を与えなければならない"
  • プログラミニングにおいては?
    • プログラミングにおいて抽象化とは、"InterfaceやAbstractをつかうのではなく"、扱っている問題や概念を抽象化することである。
      そのためにインターフェイスアブストラクトを使う
  • 指針は?
    • 後藤さんの経験則からの指針
      • 適切な命名:名前と内容が一致していること
      • 抽象度の統一:ある側面で取り出したものだけで辻褄が合う
      • 狭い範囲:特徴量が小さくなっていること
    • あるあるの例、マトリックスは他にもメソッドがあるのにたいして一つだけしか持ってない
      →checkerとcheckAbleMatrixInterfaceはマトリックスのメソッドを呼び出したときとなにもかわってないので、特徴量は減ってない、つまり抽象化は行われていない。
  • 改善:3つの指針のうちどれかを解決する。例だと:「狭い範囲」について改善を行っていた。

質疑応答

Q : 抽象化はモデリングってこと?

A : 抽象化とモデリングは一緒

Q : どうすればモデラーになれるのか、教えがあれば
A : そもそも抽象化、モデル化そのものが難しい、どうすればいいのかっていう質問
モデリングエバンスの本ではブレイクスルーでしかないと書かれている。いろんな論理学や数学的観点から考えるといいかも

設計力をあげるバリエーションの見極め術

https://speakerdeck.com/77web/she-ji-li-woshang-geru-bariesiyonfalsejian-ji-meshu

  • バリエーションの発生源と発生パターン
    • 例えば、else if書きまくりな経験
    • バリエーションとは、変化変動、種類、スピーカーTシャツのサイズSML。
      プログラムにおいては分岐のきっかけ(ex : 例えば注文日時によって消費税がかわるなど
  • なぜ発生するのか?→ビジネスが変化するから
    つまり、”バリエーションの発生源とは、ビジネスの変化”
  • 変化には二種類ある
    • 横の変化:あとから種類が増える【例】本とトイレットペーパー:本だったら作者や、価格 トイレットペーパーはWかシングルかとか
      Google AdsかYahoo Sponsored Searchなど、ヤフー向けに対応しなくてはいけないなど
      • どう予測する? 
        →同じ種類の別のものを扱うか想像、同業他社とも取引することはないか想像  
    • 縦の変化:年月とともに変化するもの (ex : 消費税や、元号など)
      • どう予測する?
        →過去の歴史から想像する、他国の先行事例から想像するなど
    • どちらの変化にも、"想像する"ことが必要がある。
    • バリエーションが二種類で増えそうにない場合は無理に作り込む必要はない。
      さらに、業務知識をともなわない想像力は、妄想力と化すことがあるので注意

コメント:https://speakerdeck.com/hidenorigoto/solidfalseyuan-ze-tutedonnahuunishi-ufalse

このセッションのさらなる理解は、「抽象化ってなに?」を発表したメルカリの後藤さんの去年のセッション内容を見ると幸せになります。

たった1人のAPI開発 BEAR.Sundayで解決した課題たち

https://speakerdeck.com/gamu1012/phperkaigi2019-trackb-1445

  • (APIフルリニューアルに伴い)開発速度やインフラの変更に強い、低コスト、変更しやすさ、可読性など、様々な「理想」があるのに対して、サーバーサイド担当は一人、Webのツール等も作る必要があるといった「制約」がある
  • その中で、重要視したのは「開発速度」、「変更追加容易」、「インフラの変更に強い」、「DBの変更につよい」
  • その理想を実現するために、BEAR.Sundayを用いた。
  • BEAR.SundayのDIを用いることで、インフラの変更に強い理想を実現した。
  • 開発速度をあげるにはクライアント(ios, android)とのコミュニケーションコストの削減することが大事
    →モックを利用することで、APIとクライアントが同時に開発スタートすることが可能になった
  • Json-Schema, Api.DocをつかうことでAPIのドキュメント整合性を担保しつつエンドポイントに関するコミュニケーションコストを下げれた
  • 理想と制約→選択し、振り返りができる。プロダクトを作って終わりの時代ではない。理想と制約の中で振り返りを続けるというのが大事

質疑応答

Q : BEAR.Sundayをつかってるということで、他の有力なフレームワークがあって悩んだのか、

A : 実質は一択で、Laravelも選択肢にあったが、DIの部分とかかゆい部分に手が届く、BEAR.Sundayを選択した

Q : レイヤー間をArrayにしちゃってのはよくなかったということだが、ほかにいい方法がありますか?
A:arrayの改善策はオブジェクトで渡すべき、それでやり取りするので境界線などがわかりやすい
Q: 途中の実現方法でショートカットリソースなどをつかったとあるが、クライアント開発のメリットはあるがサーバーサイドでデメリットが有るか
A:キャッシュ等は細かくできるので、いいがステータスの返却値のエラーとかどうするか
サーバーサイドのショートカットリソースにステータス分岐を入れている。

Q: APIドキュメンテーションにAPいDocを採用しているが、Swaggerが流行ってる理由は?
A : 最近流行りのSwaggerじゃなくてApiDocを使ったのはとにかくApiDocで整合性を担保されるのを重視した

RESTの力

https://speakerdeck.com/koriym/the-power-of-rest-24bf1cf0-1af8-45dd-bce6-6a5553511775

  • 重要なのはURIではなくリンクである。
  • RESTプラクティスとはバージョニングしない。”進化の可能性”である
  • キャッシュはなんのためにするのか、時間資源や返却速度のため?
    →"スケーラビリティ"にするために使う。
    ネットワークのリクエストそのものをキャッシュをするのはクライアントだけど指示するのはサーバー

コメント:内容が難解でしたが、バージョニングに関しては、v1からv2に行くとき、v1の事がv2でできなくなることはナンセンスである。ということはわかりました。
つまり、v1の内容がv2でもできるのであれば、そもそもバージョニングはする必要はないということになりますね。

 

PHPerのための計算量入門

https://speakerdeck.com/hanhan1978/basic-knowledge-of-time-complexity

  • よくあるコード例から理解みる
    ex : Databaseからひっぱってきて撰さしてforeachを回してifに引っ掛けていく
    →そうするとデータの増大に伴い処理時間もn^2のオーダーに上がっていく
  • この問題をどのように検出する?
  • 計算量とは、時間計算量と、空間計算量の2つ存在するがこの発表では時間計算量について発表
    • 時間計算量:プログラムの演算の回数
      O記法:計算量の目安を表す便利な記法
      O(1):一回で処理が終わる。
      O(logn):データ量が増えてもそんなに変わらない。
      O(n):線形
      O(n2):急激に伸びていく
    • よくあるコード例の改善方法についてはin_arrayではなくarray_key_existを使うなど
    • 計算量、データ量が少なければ問題ないので、in_arrayではなく必ずarray_key_existをつかう。なんてすると本末転倒になるので注意

質疑応答

Q : どうやってオーダーを計算できますか?

A:自分でforループなどを回して時間を計測するなど、あとは実際に中身を読むなど

2日目

PHPでURLルーティングをつくる

https://speakerdeck.com/bmf_san/urlruteinguwotukuru

  • 動機
    goでルーティングを自前で実装したかった
  • URLルーティングとは、リクエストされたURLに対して、実行したい処理を書く
  • 158行でつくれる。再帰処理とパワープレイでなんとかなる、ちゃんとやるなら木構造アルゴリズムが必要

Phpstormでコードを理解する技術

  • コードを理解するためのアプローチ
    • コードを読む・構造を知る
    • シンボル(クラス名、メソッド名等の総称)、
      • コードジャンプ
      • 使用箇所を検索する機能、show usages/find usages (コードジャンプと似ている)
    • コードを変更するための敬意をたどる
      • Annotate(git blame相当)、コード行の最終更新日時を出してくれる
      • Find in Pull Requestプラグインを使うとコード業から最終変更したプルリクエストを出してくれる
    • コードを実行する
      • Ctr+Shift+R+Enterで実行してくれる
      • Cmd+Shift+Dでデバック実行
    • テストコードを利用して理解する
      • テストを実行し、コードジャンプしすればおk

メルカリ・ランチセッション

https://speakerdeck.com/hidenorigoto/31

  • ソフトウェアエンジニアが成長を加速させるとこんな動き方をするべきかを話す
  • VALUEを体現するには。
  • Go Bold:自分の限界よりさらに上にチェレンジする
    限界」までは「今のやり方の延長」でできる
    →つまり今のやり方のままではできない。
  • 自分を変化させる必要があるので、成功体験などに縛られないようにするべき。
    成功しているほど、縛られるので、新しいやり方にチャレンジするべき
  • ときには自分自身にこだわらない
    • 自分を変化させるには、時間がかかる。
    • 成功へ到達するために、他の人に頼んだほうがはやいときもある。
    • 最短ルートに到達するために自分だけに拘る必要がない。
    • 今自分が成功するべきか、チームとして成功するべきかは考えるべき
  • 自分の成功に縛られない、こだわらないっていうのは客観的な視点、論理的な視点が必要
    • 視点ってなに?→視線の注がれるところ、ものを見る立場
    • →視点、視野、視座の違いって何?似てるよね?
      • 視座:見ている人自身の位置、視野:見ている角度、視点:見ている点
        視座を変えると、視野も変わる。
      • 変化のある環境に身を置く、飛び込む
      • 人は環境に流されやすいから環境は大事

アンチパターンから学ぶRDBの正しい設計

https://speakerdeck.com/soudai/learn-from-failure-2

  • フレームワークをつかうっていうのはトレードオフ
  • 制約を受け入れる必要がある
    • 制約
    • ORマッパー:モデルとDBをORマッパーで経由してPHPで取得する(SQLをラップしている)
      → N+1問題が出てくる
      どういうふうにSQLが実行されているか意識する必要がある
    • Active recordパターン
      • ビューとモデルが1 : 1(制約)なので、マジックビーンズ、ポリモーフィック関連、ORマッパーを作るときは主キーでIDを使おうとか漏れのある抽象化とうまく付き合うべき
    • コツはメリット最大化するためにビジネスロジック
      • ORM禁止は本末転倒
      • ビジネスロジックを実現するツール、つまり視野を広げるべき
        ただデータを保存するだけならS3、すばやく取り出したかったらNoSQLをすればいい、データを安全にロックするのがRDB
    • デッドロック
      • 順番というルールを決めるべき、なんでロックしているか意図しないと起きる
    • キャッシュは中毒
      • キャッシュっていい、キャッシュをつかうとパフォーマンスがあがる。
      • キャッシュはヒットしないとボトルネックになる。
        • キャッシュのヒット率はサービスの向上に伴い変化する
        • 大事なことはキャッシュありきで考えない

Webアクセシビリティへようこそ

https://www.slideshare.net/shiorikoga/phperkaigi2019helloa11yverphper

  • Webアクセシビリティ:アクセスの可能性を指している
  • フロントエンドエンジニアの担当?
    マークアップをちゃんとやろうとか、アクセスを阻害しないような動き
  • サーバーサイドとしてアクセシブルするには?
  • フロントエンドのことをどれだけ意識してAPI設計をしていますか?
    • スクリーンリーダーのためにaltを設定したり、サーバーサイド側で持たせたりするべき
    • ただし、いらない情報は返しすぎないように