ただふれたものについて書くブログ

あんまり正しくない話を適当に書くブログ

競争社会の歩き方 - 自分の「強み」を見つけるには

読んだ。経済学、特に行動経済学の目線から最近の競争社会についての考え方のエッセイ集。

よくネットでも話題に上がるチケット転売の話もあれば、選挙や落語の話もある。題材は他の行動経済学の本(ファスト&スロー(上) あなたの意思はどのように決まるか? (ハヤカワ・ノンフィクション文庫) とか)だけど、それを持って世の中の話題に踏み込んでいる。

これからIT化やらAIやら高齢化やらに、格差の問題も21世紀の資本の「資本収益率が経済成長率を常に上回る」と言われている中で、どう考えていけば良いかのヒント集って印象。

ドラクエ11感想(ネタバレなし)

ドラクエ11、裏のボスまで倒したところまで。レベルは75くらい。

たしかに評判通りシリーズ歴代と並ぶ面白さかもしれない。

6以降はどこか惰性みたいなところがあって、途中で飽きて時間を置いてまたやりだしたりしていたけれども、今回は飽きずに最後までプレイできた。ストーリーが王道(というよりジャンプっぽい)で、かつ、テンポが良い。特にテンポの良さは相当気を使っていそうで、レベルは簡単に上がるし、村の誰が次は何をするべきかが話してくれるかがマップで表示されているので詰まることはあまりない。また、よくある「○○を6つ集めよ」というイベントがあっても、別のストーリーを進めているといつのまにか手に入っていることが多い。

キャラクターもパッケージみた時はあまり特徴なさそうな印象だったけれども、どれもよくできている。うまい具合にパーティが固定されないようにできていて、序盤使えたけれども、後半は後ろに引っ込んだり、常時トルネコみたいなことはなかった。

もう少したったら、PS4版(Switch版でるのかな)でもやってみようと思う。

2016年に買って良かったもの

去年iPhone7に買い換えたことをキッカケにBluetoothのヘッドホンを使い始めたのだけど、今となっては生活必需品になってしまっている。

数年前にジムで音楽聴きたいからと安いBluetoothのヘッドホンを買ったのだけど、音声途切れ気味だったり、ちょっと使っただけですぐ壊れてしまっていてあまり良い印象なかったのだけど、Bose QuietControl 30 wireless headphones : ワイヤレスノイズキャンセリングイヤホン ネックバンド式/Bluetooth対応/コントローラブル・ノイズキャンセレーション機能搭載/リモコン・マイク付き ブラック QuietControl30 WLSS BLK【国内正規品】を使ってもうそういった不満要素ふっとんだ。

簡単にペアリングできる。ネックバンド最高。無くさない。ノイズキャンセリング十分。装着感も良い。こんなに安定しているイヤホンのはなかなかない。

だけどジムで試してみたところ、走っているときにネックバンドが鎖骨に当たって痛かったので、ジム用のものを買ってみた。

ペアリング問題なし。値段のわりに使いやすい。でもネックバンドない。適当に置いておくと無くしそう。

なので、Bluetoothヘッドホンはネックバンドがあったほうが良いという結論。

スーパーマリオランやってみた

supermariorun.com

スーパーマリオラン週末から結構やっている。

f:id:taizo_onexone:20161218184141p:plain

家庭用ゲーム機のゲームをそのままスマホに持って来た。

家庭用ゲーム機のゲームバランス

普通にワールドをクリアするのは難しくない。アクションゲームに慣れている人ならば、2時間あれば全コースクリアできる。だが、クリア以外にカラーコインを集めるというやりこみが用意されている。カラーコインは、各コースにそれぞれ、ピンクコイン、バープルコイン、ブラックコインがあり、ブラックコイン集めは難しめ。

このコイン集めが家庭用ゲーム機のゲームバランスをそのまま持って来ている。やり込めばプレイヤーのステータス数字が上がっていずれクリア出来る類ではない。あくまでもプレイヤーのゲームの上達にかかっている。

レベルデザインも他のマリオシリーズと変わらず、いろいろ考え抜かれている。ミスする可能性が上がるがコインがいっぱい取れる進め方などが随所にあるし、コインの位置でどう進むべきかがなんとなく示唆をして難易度をちょうどよく調整しているようにみえる。

1,200円が高いかどうか

1,200円くらいの価値があるかというと、昔ながらのゲームをやり込む人ならば価値があると思う。キノピオラッシュも面白い。だけど、今までのソーシャルゲームのようにパラメータを上げたらクリア出来るゲームではない。ソーシャルゲームならもったいないなどの理由も含めて、平気で1年くらいプレイできるけれど、それに比べれば、飽きは早いと思う。楽しかったねーと1,200円払えるかどうか。

個人的には、このゲーム売り上げ的に成功して、今の課金を前提にしたゲームとは違ったゲームが増えることを願ってる。

レビュー時の議論を避けよう

プルリクエストベースでレビューをしているとたまに、コメントのやり合いが起こることがある。

 

特に設計ベースでレビュアーの考えと修正が違った場合に起きやすい。

 

ただ、レビューの時に議論が起きる時点で開発の仕組みに問題があると思ったほうがいい。議論はレビューの前に終わらせてコードレビューはコード自体の品質に集中できるようにしたほうが無駄な差し戻しがなくなるからだ。

 

よく行う対策にはこんなのがある。

 

  • 設計レビューを実装開始前に行う
  • プルリクエストの大きさを小さくする
  • Work In Progress(WIP) のプルリクエストを初期に出してどのような修正をするかを予め見ておいてもらう
  • プロダクトのissueを適時出しておいて後でその内容をチームで議論する時間を設ける

 

よくよく考えれば、まずissueでアイデアをぶつけてから修正をするみたいなフローもよくあるわけで、コードを直す前にレビュアーと認識はきちんと合わせておいたほうが結果的にスムーズにいくという些細だけど大事って話でした。

 

serverless を試す

API Gateway + Lambda を使ってHTTP APIを作るには、何を使うのが一番良いのだろうと まずは Apex – Serverless Infrastructure を試してみたものの、API Gatewayとlambdaを繋げるところまでがサポートされていなく そこをterraformでやるのは厳しいかなと思って別なものを探していたら、Serverless というそのままの名前のツールがちょうど良さそうだった。

Serverless

serverless.com

AWS Lambda を使ったAPI サーバーの設定などを管理できるビルドツール。

install

npm install -g serverless

Create credentials

まずパッケージで必要なcredentialsを設定する。 これをすると ~/.aws/credntialにファイルを作成してくれる

$ serverless config credentials -p aws -k <aws-key> -s <aws-secret>

テンプレートの作成

$ serverless create -t aws-nodejs

いくつかテンプレートが用意されているので、それを使うと、 handler.jsserverless.yml が作成される。

handler.js

module.exports.hello = (event, context, callback) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,
    }),
  };
  callback(null, response);
  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
};

serverless.yml

service: aws-nodejs # NOTE: update this with your service name
provider:
  name: aws
  runtime: nodejs4.3
functions:
  hello:
    handler: handler.hello

serverlessにawsの設定などを記載していくことになる。

とりあえずエンドポイントを実行できるようにしてみる

functionsにイベントを記載する

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: /
          method: get

http イベントを設定すると、API Gateway と紐づけてくれる。 イベントは他にもいくつかある Serverless - AWS Lambda - Events

あとはデプロイをするだけ。

$ serverless deploy -r ap-northeast-1 -s dev

deploy

devにデプロイしてみる

$ serverless deploy -r ap-northeast-1 -s dev

Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3 (583 B)...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
............................
Serverless: Stack update finished...
Service Information
service: aws-nodejs
stage: dev
region: ap-northeast-1
api keys:
  None
endpoints:
  GET - https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/
functions:
  aws-nodejs-dev-hello: arn:aws:lambda:ap-northeast-1:59XXXXXXXXXX:function:aws-nodejs-dev-hell

色々なものを一気に作ってくれる

role も作ってくれる。 arn:aws:iam::59XXXXXXXXXX:role/aws-nodejs-dev-ap-northeast-1-lambdaRole

アクセスできるようになる

% curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/
{"message":"Go Serverless v1.0! Your function executed successfully!","input":{"resource":"/","path":"/","httpMethod":"GET","headers":{"Accept":"*/*","CloudFront-Forwarded-Proto":"https","CloudFront-Is-Desktop-Viewer":"true","CloudFront-Is-Mobile-Viewer":"false","CloudFront-Is-SmartTV-Viewer":"false","CloudFront-Is-Tablet-Viewer":"false","CloudFront-Viewer-Country":"JP","Host":"xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com","User-Agent":"curl/7.49.1","Via":"1.1 25e2bd4c76e5ce50a0e42ea7d68cb8be.cloudfront.net (CloudFront)","X-Amz-Cf-Id":"vNC5HOdFJ9wDxnmXVq9MwGrMwsFGtFHwKCohNx3PGyWbw6mJiXeT3Q==","X-Forwarded-For":"xxx.xxx.xx.xx, xx.xxx.xxx.xx","X-Forwarded-Port":"443","X-Forwarded-Proto":"https"},"queryStringParameters":null,"pathParameters":null,"stageVariables":null,"requestContext":{"accountId":"592382460000","resourceId":"7wt5tp3333","stage":"dev","requestId":"e2bef286-bf5c-11e6-8ed0-8b69baa26de7","identity":{"cognitoIdentityPoolId":null,"accountId":null,"cognitoIdentityId":null,"caller":null,"apiKey":null,"sourceIp":"xxx.xxx.xx.xx","accessKey":null,"cognitoAuthenticationType":null,"cognitoAuthenticationProvider":null,"userArn":null,"userAgent":"curl/7.49.1","user":null},"resourcePath":"/","httpMethod":"GET","apiId":"qeg4d8alu6"},"body":null,"isBase64Encoded":false}}

確認

--region は必須

$ serverless deploy list -r ap-northeast-1
Serverless: Listing deployments:
Serverless: -------------
Serverless: Timestamp: 1481428344900
Serverless: Datetime: 2016-12-11T03:52:24.900Z
Serverless: Files:
Serverless: - aws-nodejs.zip
Serverless: - compiled-cloudformation-template.json

削除

remove でできる。

$ serverless remove -r ap-northeast-1
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
.................
Serverless: Stack removal finished.

roleも削除してくれる

すごい楽

アプリケーションを作る立場からするとすごい楽。だけど、構成管理としては 使っているサービスは terraform に寄せたいけれど、現実的に厳しそう(そもそもterraformでlambdaでデプロイするのに、毎回アプリケーションをまとめたファイルを用意しなきゃいけない)で、なんかもやもやしてる。

React + Flux アプリケーションを作るときに知っておきたかった2つのこと

数ヶ月くらいReact + Flux アプリケーションを3〜4つくらい業務で触ってみたら、知っておけば良かったという考え方がいくつかあった。

1. コンポーネントの分け方の考え方

Atomic Designと Presentational and Container Components

各要素をコンポーネントに分割するための考え方のひとつに Atomic Design がある。

f:id:taizo_onexone:20161123230719p:plain

パーツをコンポーネント単位で定義していくもの。

Reactのコンポーネントの分ける際にとても役に立つ考え方なので、実装側はこれを基準にデザイナーに考えてもらえるとフロントの実装側はとても助かる。

ただ、デザイナーがこのコンポーネント単位でデザインを起こすのにはそれなりに難易度が高い。

特に全体の設計をしてから、細部に落とし込むやり方に慣れていると大変らしい。

コンポーネント志向の場合、スタイルガイドのようなもので粒度の細かいものをひとつずつ実装してからそれをレイアウトしていく考え方になる。作業フローが逆になる。

一方でデータ設計の目線でみると Presentational and Container Components – Dan Abramov – Medium で書かれている Presentational と Container コンポーネントの分け方の考え方がある。

これは少しでも大きめなReactアプリケーションを作り始めると共感できるもの。stateの管理やらデザインのレイアウトやらをどのコンポーネントが責任を持つかをハッキリさせておくと複数人で開発する場合は良い気がした。特にレビューのコストが下がると思う。

Material-UIを Presentational Component とみなして、試しに実装してみるとわかりやすいと思う。

2. propsのバケツリレーをどう対応するか

Reactアプリケーションを作っていると、props のバケツリレーはどうしておくかも可能ならば事前に決めておきたい。せめて後で分割するときのことに思いを馳せておきたい。

props.children を使いこなす

単純にDOMをツリー上に記載していくと、コンポーネントの汎用性が良くならない。なので、外から内側のDOMを直接代入をしてコンポーネントの分離をしやすくしたりできる。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

const Item = (props) => {
  return (
    <p>{props.name}</p>
  );
}

const List = (props) => {
  return (
    <div>
      {props.children}
    </div>
  );
}

const names = ["a", "b", "c"];
const App = () => {
  const items = names.map((n, i) => <Item name={n} key={i} />);
  return (
    <List>
      {items}
    </List>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

ポイントはListコンポーネントでItemコンポーネントを記載せずに、props.children をそのまま表示するように書くこと。

const List = (props) => {
  return (
    <div>
      <Item name={props.name} />
    </div>
  );
}

モーダルUIなどで外側だけを作って中の要素を丸々propsで渡すなど、外側のレイヤーだけかっちりしているけれど中は汎用的にしたいときはこういったモジュールを実装する。

storeの更新の監視を子で行う

バケツリレーを避けるために、子でstoreデータを監視するのもあり。 ただ、コンポーネントを削除した際にそのstoreデータをきちんと削除するか残し続けるかという選択肢が出てくる。

まとめ

Reactはわかりやすいけれど、Fluxやコンポーネントデザインにまで話が及ぶと明確な正解がないので、ひとつひとつやり方を落とし込んでいくコストが結構かかるのは覚悟必要ってのが最近触った感想です。

参考

qiita.com