AngularJSコトハジメ
どうもお久しぶりです。
tomigunguです。
本日はAngularJSコトハジメ、ということでAngularをさわる前に知っておくべきことを書いていこうと思います。
AngularJSとは?
MVWフレームワークである
WはWhateverの略です。まあ、ModelとViewが重要なのでその他って感じですかね笑
重要なこのMVWフレームワークですが、重要なポイントが3点あります。
ModelとViewの分離
これはjQueryを触っている方ならわかると思います。jQueryを使うとUIのコンポーネントを簡単に配置、構築することができる反面、ModelがViewの役割を担いすぎてしまうので、ModelとViewがほぼ一緒になってしまいます。これはメンテナンス性や再利用性を低下させる原因となります。
そこでAngularのようなMVWフレームワークを使うことで、完全にModelとViewを分離させることができます。内部的にはHTMLとJSの値のやりとりは全てAngularが吸収し、Modelに格納することで双方向にデータのやりとりが可能になります。
Data Binding
UIとModelの双方向のデータのやりとりを可能にします。例をあげると、inputタグに書かれた文字列が即時別のDOMに反映されて表示されます。これはAngularがModelで吸収し、EL式のような{{str}}で囲まれた要素と結びつけるからです。
DI
- コントローラーの関数置き換えができる
- モック用のコンポーネントが使える
- UIだけ最初に作りこむことができる(テストデータなどを用いて)
- 環境構築の手間が省ける
- テストデータも埋め込んだ形でデバッグができるから
本当はもっと奥が深いのですが、僕の知識ではここまで。。。
以上3点の重要なポイントを抑えた上で、まずはmoduleについての説明です。
module
- バケツのようなもの
- アプリケーション立ち上げの際に最初に定義する
定義は以下のように行います。
var myApp = angular.module("MyApp", []);
第2引数には依存するモジュールを配列で指定することができます。
この「myApp」という変数にcontroller、filter、directiveなどのコンポーネントを追加していきます。
myApp.controller("MyController", function() {...});
さて、ここからはmoduleに追加できるコンポーネントの説明をしていきます。
template
主にviewの要素を定義する。HTMLで特定の部品を書いておける。
directive
自分でHTMLのタグもしくは属性を作成できる。
これら2つのコンポーネントはViewの役割を担います。
controller
- ロジックの集合体
- この中でViewを操作しない
- 変更したデータをバインドする($scopeを使う)
scopeについて
scopeには親子関係があります。
- その実体はオブジェクト
- この変更は親に反映されない
- オブジェクトを作成することで、参照できる
- 子のscopeで見つからなかったら、親のscopeを辿っていく
Controllerの使い方
- directiveの初期化の際に渡す
- 外部からscopeを渡す
- テストがしやすくなる
- スコープが変わっているかを確認することでテストが成功したかどうかがわかる
service
- scopeに紐付かないロジックの集合
- 画面とは関係ない処理を定義する際に利用
- 例えば単純な計算など
filter
- UIで表示する式の値をフィルタリングする
- 標準で提供されているが、カスタムで作成することもできる
constant
- 初期化が1度のみできる定数を定義(製品名、会社名など?)
value
- 何でも入れられる変数を定義
factory
- サービスを登録する際に使用
- 作るサービスを変更しなければいけない場合
- 例えば、処理を加える、DIを変える...etc
provider
- factoryを作る担当
- UIのコンポーネントを使う、デフォルト値を上書きする際に使用
以上でコンポーネントの説明は終わりです。
今回勉強してみて、AngularJSは学習コスト高いし覚えること多いなぁ・・と感じました。
ただこれを使いこなすことができれば、メンテナンス性が高く、テストのしやすいコードを書くことができると確信しました!
それでは(^^)
仕事はそんなに甘くない。tomigungun説教わず。
今日は入社以来初にして最大級に説教を受けました。
その時に言われたこと、感じたことを連連と書こうと思います。
自分の頭で考えずにテキトーに返答するな
確かにその通りですよね。僕の場合、すぐに知ったかをしてしまい、自分の頭で考えずに薄っぺらな知識で答えてしまう癖があります。それがいけないとのことです。
確かに自分で考える前にすぐに口が出てしまう、簡単に言うと答えのみを求めている状態です。そんな状態ではせっかく教えてもらったことも、すぐに忘れてしまうでしょう。
質問する際も、わからないと思った瞬間思考が停止してしまい、「聞けばいっか」と思ってしまう悪い癖があります。
それでは聞かれた方も困りますよね。まず僕が何がわかっていないかわからない状態ですし、質問の具体性に欠けます。
サンプルコードを参考にするのはいいが、その本質を理解せずにそのまま書くな
僕の場合、わからないことがあるとまずはサンプルコードを探しに行きます。それを少し読んで「わかった気」になると、それをそのまま写して利用していました。
そんなんじゃ信用出来ないと。もし他の人にソースコードの説明を迫られた時に、すぐに回答できないしなぜそのように書いたかを自分の中で理解していません。それじゃ〜議論する余地もないですよね。
質問の返答に対し、「〜ですよね?」などと知ったかするな(決めつけるな)
これはものすごくグサリときました。僕の場合、癖なんですよねこれが。確かに質問した方からすれば、「コイツ知らないくせに知った風を装ってるな」と思うわけです。さらにこの「〜ですよね?」が全く自分の頭で考えずに返答しているとなったら、もう相手はオコです。
今後は質問されたら、知らないものに対しては素直に知らない、少し自分の頭で考えて解答が見つかったら「〜ですか?」と語尾を改める必要があります。
人に相談もせずに勝手に実装し、それが設計に沿っていない場合は最悪
今日これをやらかしました。まあその上司がすごく僕に厳しい人で、「聞きづらいな〜(聞かなくていっかな〜)」とか思って実装した内容がまさに設計にそぐわないものでした。「テキトーだなおい」とみんなの前で言われ、とても恥ずかしい思いをしました。
自分で考えたものをまずは上司に相談、アドバイスをもらってから実装すべきだと痛感しました。
リファレンスは全部読め
サンプルコードを使いまわしている僕にとっては全然習慣化できていないことでした。実装するからには仕様はちゃんと理解しておけってことです。
若いうちは迷惑をかけてもよい。それが仕事(期間限定)。
質問したり、質問した上での迷惑に関しては、若いうちはかけなさいと。しかし何も聞かずに迷惑をかけるのは悪。迷惑をかけるのが仕事のうちなのは、期間限定である(人によってその期間は異なる)。
連連と書きましたが、こんな感じです。
2時間近く?これらのことを厳しく説教されました。言い方がキツイ方だったので、「は?」とか思ったり、凹んだりもしましたが、言ってくださったことに感謝しています。
若いうちが華とは良く言いますが、まさにそれを痛感した一日でした。。。
もっと努力しなきゃ。。。
Shaping up with Angular.js Level1
どうもこんばんは。
tomigungunです。
会社でAngularJSを利用したプロジェクトに携わることになったので、勉強したことをブログに書きます。
以下の公式サイトのスライドを読んでまとめたものになります↓
http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro
とりあえず今回はLevel1のみ。
Level1: Getting Started
知っておいてほしいこと
必須
- HTML・CSS
- JavaScript
知っていると良いこと
- テスト自動化
- BDD(振る舞い駆動開発)
- TDD(テスト駆動開発)
それほど重要でないこと
- jQuery
- Ruby on Rails
- Rython, PHP, etc
- Databases
なぜAngularなのか?
- JavaScriptを組織化してくれる
- レスポンシブ(高速な)ウェブサイトを構築できる
- jQueryとの親和性が高い
- テストがしやすい
今までのページ再読み込み
- ブラウザからサーバーへリクエストを送信
- サーバーからWebpageとAssetsを含んだレスポンスが返ってくる
- ブラウザはウェブページ全体を読み込む
- リンクをクリックし、新しいリクエストを送信
- 同じくサーバーからレスポンスが返ってくる
- 再びブラウザはウェブページ全体を読み込む
Angularを使った"レスポンシブ"なウェブサイト
- ブラウザからサーバーへリクエストを送信
- サーバーからWebpageとAssetsを含んだレスポンスが返ってくる
- ブラウザはウェブページ全体を読み込む
- リンクをクリックし、新しいリクエストを送信
- サーバーからJSONデータが返ってくる
- ブラウザはすでに読み込んでいるページヘデータを埋め込む
AngularJSとは何か?
- HTMLとの双方向性を提供する、クライアントサイドのJavaScriptフレームワーク
ディレクティブ
ディレクティブとは、JavaScriptのコードを動作もしくは参照することをAngularへ伝えるためのHTMLタグのこと
<!DOCTYPE html> <html> <body ng-controller="StoreController"> ・・・ </body> </html>
function StoreController() {
alert('Welcome, Gregg!');
}
ライブラリのダウンロード
- AngularJSのダウンロードhttp://angularjs.org/
- angular.min.jsが必要
- Twitter Bootstrapのダウンロードhttp://getbootstrap.com/
- bootstrap.min.cssが必要
はじめに
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Getting Started</title>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<script src="angular.min.js"></script>
</body>
</html>
モジュール
- Angularアプリケーションの部品を書く場所
- 書いたコードをよりメンテナンスしやすく、テストしやすく、そして読みやすくする
- アプリケーションの依存関係を定義する場所
- モジュールは他のモジュールも利用できる
モジュールを作ってみよう
var app = angular.module('store', []);
- 第一引数:アプリケーション名
- 第二引数:必要なライブラリ
表現
HTMLへ動的な値を入れることができる
- 数値
- 文字列
- その他
<!DOCTYPE html>
<html ng-app="store">
<head>
<meta charset="utf-8">
<title>Getting Started</title>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<script src="angular.min.js"></script>
<script src="app.js"></script>
<p>
I am {{4 + 6}}
</p>
<p>
{{"hello" + " you"}}
</p>
</body>
</html>
var app = angular.module('store', []);
コントローラ
- アプリケーションの振る舞いを定義する場所
- 関数や値を使用
コントローラーへの値の入れ方
- クロージャーの利用
- アプリケーションの中に定義
(function() {
var app = angular.module('store', []);
app.controller('StoreController', function() {
this.product = gem;
});
var gem = {
name: 'Dodecahedron',
price: 2.95,
description: '・・・',
}
})();
コントローラーの適用
- divの中にディレクティブを記載
- コントローラー名とエイリアスを代入
- コントローラーのスコープはdiv内のみ
<body>
<div ng-controller="StoreController as store">
<h1> {{store.product.name}} </h1>
<h2> ${{store.product.price}} </h2>
<p> {{store.product.description}} </p>
</div>
{{store.product.name}}
<script src="angular.min.js"></script>
<script src="app.js"></script>
</body>
ng-showディレクティブ
- 値がtrueの時に要素が表示される
<body>
<div ng-controller="StoreController as store">
<h1> {{store.product.name}} </h1>
<h2> ${{store.product.price}} </h2>
<p> {{store.product.description}} </p>
<button ng-show="store.product.canPurchase"> Add to Cart </button>
</div>
<script src="angular.min.js"></script>
<script src="app.js"></script>
</body>
var gem = {
name: 'Dodecahedron',
price: 2.95,
description: '・・・',
canPurchase: true
}
ng-hideディレクティブ
- 値がtrueの時に要素が非表示になる
<body ng-controller="StoreController as store">
<div ng-hide="store.product.soldOut">
<h1> {{store.product.name}} </h1>
<h2> ${{store.product.price}} </h2>
<p> {{store.product.description}} </p>
<button ng-show="store.product.canPurchase"> Add to Cart </button>
</div>
<script src="angular.min.js"></script>
<script src="app.js"></script>
</body>
var gem = {
name: 'Dodecahedron',
price: 2.95,
description: '・・・',
canPurchase: true,
soldOut: true
}
複数商品
app.controller('StoreController', function() {
this.products = gems;
});
var gems = [
{
name: 'Dodecahedron',
price: 2.95,
description: '・・・',
canPurchase: true
},
{
name: 'Pentagonal Gem',
price: 5.95,
description: '・・・',
canPurchase: false
}
];
配列として表示
- 要素番号を指定して表示
<body ng-controller="StoreController as store">
<div>
<h1> {{store.products[0].name}} </h1>
<h2> ${{store.products[0].price}} </h2>
<p> {{store.products[0].description}} </p>
<button ng-show="store.products[0].canPurchase"> Add to Cart </button>
</div>
<div>
<h1> {{store.products[1].name}} </h1>
<h2> ${{store.products[1].price}} </h2>
<p> {{store.products[1].description}} </p>
<button ng-show="store.products[1].canPurchase"> Add to Cart </button>
</div>
<script src="angular.min.js"></script>
<script src="app.js"></script>
</body>
- ng-repeatディレクティブを使用して表示
<body ng-controller="StoreController as store">
<div ng-repeat="product in store.products">
<h1> {{product.name}} </h1>
<h2> ${{product.price}} </h2>
<p> {{product.description}} </p>
<button ng-show="product.canPurchase"> Add to Cart </button>
</div>
<script src="angular.min.js"></script>
<script src="app.js"></script>
</body>
Level1で学んだこと
ディレクティブ - JavaScriptの動作を制御するHTMLタグ
モジュール - アプリケーションの動く場所
コントローラー - アプリケーションの振る舞いを追加する場所
式(Expressions)- ページ内での値の取得法
以上になります。
Level1のみをやってみた感想:
「Javascript書かなくても全然動的なサイト作れるじゃん!」です笑
それでは(^_^)/~
Google Web APIでちょいと遊んでみた
どうもこんばんは。
tomigungunです。
本日はGoogle Web APIを使って、グーグル検索して遊んでみました。
自分で何かWebアプリ作ろうかな〜と思っていたので、とりあえず手始めに天下のGoogleさん的なね。笑
基本的にGoogleのリファレンスを読んだりして、とりあえず検索のAPIを試してみました。
GETを投げるエンドポイントのBase URLはこちら↓
そして基本となるクエリパラメータは以下のとおりです。
| クエリkey | 例 | 説明 |
|---|---|---|
| q | q=blog%20sample | 検索文字列 |
| v | v=1.0 | プロトコルのバージョン番号。現在は1.0のみ? |
| userip? | userip=192.168.0.1 | リクエスト元のIP。実際にはよくわかってません汗 |
| rsz? | rsz=4 | 受け取りたい検索結果の数。1~8の間で指定する。 |
| hl? | hl=fr | アプリ元の言語 |
| start? | start=4 | 最初の検索インデックスの位置。例の場合だと、start要素が0, 4, 8, ・・・となる。 |
| callback? | callback=foo | レスポンスの際に呼ばれるコールバック関数? |
| context? | context=bar | なんかよくわかんないけど、callbackと一緒に指定されるとcontextがノーマルレスポンスになる? |
クエリパラメータに関してはこんな感じです。
すみませんが実際に僕が使っていない後半の奴らは、使い方がよくわかっていません。。。
お次はレスポンスのフォーマットについて
JSONで返ってくるみたいです。
基本的な構造は以下のとおりです。
{
"responseData" : {
"results" : [],
"cursor" : {}
},
"responseDetails" : null
"responseStatus" : 200
}
GETリクエストを送るために、jerseyクライアントAPIを使ってHTTPクライアントを作成しました。
ソースコードは以下の通りです。
public static void main(String[] args) {
Client client = Client.create();
String query = "blog sample";
query = URLEncoder.encode(query);
WebResource resource = client.resource("https://ajax.googleapis.com/ajax/services/search/web?v=1.0&"
+ "q=" + query + "&rsz=2");
String response = resource.get(String.class);
System.out.println(response);
}
こちらのサンプルコードを実行すると、次のような結果が返ってきます。
{"responseData": {"results":[{"GsearchResultClass":"GwebSearch","unescapedUrl":"http://ranking.ameba.jp/gr_3ple","url":"http://ranking.ameba.jp/gr_3ple","visibleUrl":"ranking.ameba.jp","cacheUrl":"http://www.google.com/search?q\u003dcache:cPgBJDJmxf4J:ranking.ameba.jp","title":"\u003cb\u003eサンプル\u003c/b\u003e・モニター | Ameba(アメーバ)人気\u003cb\u003eブログ\u003c/b\u003eランキング","titleNoFormatting":"サンプル・モニター | Ameba(アメーバ)人気ブログランキング","content":"\u003cb\u003eサンプル\u003c/b\u003e・モニターの\u003cb\u003eブログ\u003c/b\u003eランキングです。商品\u003cb\u003eサンプル\u003c/b\u003eなどのおトクな情報をキャッチ\n!"},{"GsearchResultClass":"GwebSearch","unescapedUrl":"http://blog.goo.ne.jp/portal/template_list","url":"http://blog.goo.ne.jp/portal/template_list","visibleUrl":"blog.goo.ne.jp","cacheUrl":"http://www.google.com/search?q\u003dcache:J043rRLL4BQJ:blog.goo.ne.jp","title":"\u003cb\u003eブログ\u003c/b\u003eテンプレート - goo\u003cb\u003eブログ ブログ\u003c/b\u003eのデザイン一覧です。","titleNoFormatting":"ブログテンプレート - gooブログ ブログのデザイン一覧です。","content":"goo\u003cb\u003eブログ\u003c/b\u003e。\u003cb\u003eブログ\u003c/b\u003eテンプレート・デザイン一覧。 シンプル、クール、ポップ、かわいい\nイラストものから、春、夏、秋、冬、季節に合わせたテンプレートまで、 デザイン\nテンプレートが豊富です。あなたのお気に入りの\u003cb\u003eブログ\u003c/b\u003eデザインがきっと見つかるはず。"}],"cursor":{"resultCount":"296,000","pages":[{"start":"0","label":1},{"start":"2","label":2},{"start":"4","label":3},{"start":"6","label":4},{"start":"8","label":5},{"start":"10","label":6},{"start":"12","label":7},{"start":"14","label":8}],"estimatedResultCount":"296000","currentPageIndex":0,"moreResultsUrl":"http://www.google.com/search?oe\u003dutf8\u0026ie\u003dutf8\u0026source\u003duds\u0026start\u003d0\u0026hl\u003den\u0026q\u003d%E3%83%96%E3%83%AD%E3%82%B0%E3%80%80%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB","searchResultTime":"0.08"}}, "responseDetails": null, "responseStatus": 200}
ちゃんと仕様通りですね。
このResultJSONについては、リファレンスに何も書かれていなかったのですが、key名を見たらなんとなく意味がわかるようになっています。
てな感じで今回はGoogle Web APIで検索をちょろっと試してしてみました。
Googleさんは検索広告で利益をあげているので、APIでのコールはいくつか制限があるみたいですがこんなにも簡単にGETリクエストを送信することができるのですね!
Webアプリケーションを作る第一歩になった、気がします・・・笑
それでは(^_^)/~
Webに関する全般的な知識 〜Webアプリケーションを開発する上で必要なこと〜
どうもこんばんは。
tomigungunです。
〜本日の業務にて〜
CTO:今○○のアプリってどうやって作ってる?
CTO:それはアカンな
てな会話が繰り広げられたわけですよ。
そこでCTOが別の部署からあるデキる方を連れてきてくださって、レクチャーしていただけることになりました笑
そこでレクチャーしていただいた内容を忘備録として、書いていきたいと思います。
Webアプリケーション開発における前提知識
プロジェクト規模が大きくなるとjQueryは使わないほうが良い?
jQueryとは
- Selectorが使える
- Manipulationが便利
怖い部分
- DOMがたくさんできてしまう
- 後からの修正が大変
- 単体テストできない
MVCモデルの歴史
JSFとは
- Controllerいらないよね?
- じゃあコントローラーとView一緒にしちゃえ!
- MVになる(Controllerがいらなくなる)
しかしはやらず・・・
原因はセッションに色んな情報を詰めており、サーバーでの処理が遅くなるから。
しかしModelの部分は不変!!
サーバーサイドはRESTでしょ。データプロバイダとしての機能のみになる。
クライアント時代
JSでサーバーからデータ取ってきたり、jQuery使いまくってたらViewが大きくなってきた・・・
JSとModelを切り離す、フレームワークを利用
- AngularJS、BackBoneなどなど
HTTPの仕様を知る
HTTPとは・・・『Hyper Text Transfer Protocol』
Base64を使いbyteを64文字列で送る
バイナリも送れますよ〜
だってテキストにしてるもん。
Protocolの話
URIとは・・・
『UniformedResourceIdentifier』IDの付け方が重要!
直感的にわかるIDを付ける必要がある
RPC(Remote Procedure Call)が一時期流行った(いわゆるSOAP)
SOAPはPOSTで送るという仕様になっている
更新をかけるのは基本的にPOST
SPDY Googleが作りこんだHTTP2.0の仕様(ドラフト)
Responseの話
StatusCode これを見たらだいたいのことがわからなくてはいけない
2✕✕:成功
- 200:OK
- 201:Created→Location: URI
- 204:NoContent
3✕✕:リダイレクト(他)
- 301:Move Parmanently
- 302:Found
- 303:See Other
- 304:Note Modified
- 307:Move Temporary
4✕✕:クライアントエラー
- 401:Not Authorized
- 403:Forbidden 権限による
- 404:Not Found
- 405:Method Not Allowed
- 406:Not Acceptable
- 409:Conflict 同時リクエストによる矛盾
- 410:Gone 昔あったページ
- 412:Precondition Field
5✕✕:サーバーエラー
- 500:Internal ServerError
- 504:Gateway Timeout
Headerにデータの型を入れる
- request
- Accept
- request側でやる
- Accept
- response
- Content-Type
- Location
などなど・・・
HTTPキャッシュ
ブラウザが勝手にやってくれる!
- 期限モデル
データの保持期限を渡して、それに応じてリクエストを送らない。Date、Expiresをresponseに付与。
- 検証モデル
リクエストを送るが、データの状況に応じてデータを返すかどうか決める。この時にかえるのがStatusCode:304。どちらもサーバー側で実装が必要
responseにEtag・DateをEntityにつめてクライアントに返す。その後はrequestにEtagを付けて送信。
RequestにIf-None-Match:Etagを付与。
Cookie
Headerの一部
こいつはJSESSIONIDをパラメータで指定することができる。しかしCookieが優先されるので殆どの場合、必要ない。
SessionStrageとLocalStrageに保存する方法もある
Secure、Httpsonlyはtrueにすべき
レスポンスヘッダーのサーバー名やURLは隠すべき
ざっとこんな感じです!
いや〜ほんとにデキる方って素敵。教え方もわかりやすくて本当に勉強になりました!
うちの部署に来てほしいよ全く。。。
てなわけで本日レクチャーしていただいた内容を踏まえて、今までJSP/サーブレットで作っていたものをRESTに作り変えるそうです!明日から・・・笑
JAX-RS(Jersey)を使ってゴリゴリ作って行くみたいなのですが、楽しみでもあり、ちょいと不安もあります。。
今日はここまで。
それでは(^_^)/~
Gitでのバージョン管理
どうもこんばんは。
tomigungunです。
本日はGitの使い方に関する、素晴らしいslideshareを見つけたので共有したいと思います。
ノンプログラマでも今日から使える「Git」でバージョン管理ということで、Gitを初めて使う人向けに作られたスライドでした。
私は普段業務でGitを使っているのですが、初めて触った時はすごい苦戦した記憶があります汗
それまでSVNなどのいわゆる集中型のバージョン管理システムすら使ったことがなく、いきなり業務でGitを使うことになり、バージョン管理って?分散型って?indexって?などたくさんの疑問にぶち当たりましたね。
今ではブランチをきったり、たまにrebaseしたりとなかなか使いこなしている方だと思うのですが、改めてこのslideshareを読んでより理解が深まりました。
説明の仕方や図がとてもわかりやすいので、これからGit使うぜ!って人やイマイチGitの使い方わからん!って人に是非読んでもらいたいですね(^^)
それでは(^_^)/~
ベンチャー志向プログラマ
昨日行ってきた夏サミの最後のセッション、EnterpriseTEDで興味深いお話をされていたKAIZEN Platform Inc.の伊藤さんについて調べてみたところ、こんな動画を発見しました!
ベンチャー指向プログラマ - 伊藤直也さん ‐ ニコニコ動画:GINZA
『ベンチャー志向プログラマ』というテーマで話されていて、自分のプログラマとしての生き方を改めて考えさせてくれる動画でした。
大半が伊藤さん自身についての話だったのですが、後半のプログラマとしての生き方を聞いて、自分は全然リスクとってないなと。
プログラミングは業務でそこそこやっていて、Javaなら難なく書くことができるのですが、そんなんでは全然ダメだと。。
やはり職業プログラマーではなく、自ら進んでプログラミングの機会を増やすべきだと感じました。
動画で伊藤さんがおっしゃっていた車輪の再開発しようかしら。。。
この動画はプログラマの方には是非見てもらいたいですね
てことで今日はこんなところで(^_^)/~