マッスル・メモリー

筋肉エンジニアのブログ

【js】ES6 var, let, constの違い

ES6からconst, letが登場しvarは使われなくなりました。

  • var, const, letの違いは何か?
  • なぜvarは使わないのか?

について説明していきます。

var, const, letの違いは何か?

以下の表に違いをまとめました。

再宣言 再代入 ブロックレベルのスコープ 変数の巻き上げ
var できる できる 存在しない 起こる
let できない できる 存在する 起こるが、、
const できない できない 存在する -

それぞれについて説明していきます!

再宣言

var varVariable;
var varVariable;

let letVariable;
let letVariable; // Uncaught SyntaxError: Identifier 'letVariable' has already been declared

上記のコードでは変数をそれぞれ2回宣言しています。

var varVariable;は2回目でもエラーは起こりませんが、

let letVariable;は2回目ではSyntaxErrorが発生しています。

letでは再宣言はできないのです。

また、constの場合、

const constVariable; // Uncaught SyntaxError: Missing initializer in const declaration

そもそも、constで変数を宣言する場合は、値を指定しなければいけません。

それもそうです、後述しますが、constは再代入できない(値を変更できない)ので宣言だけでは使い所がないのです。

再代入

var varVariable = 'var';
varVariable = 'var2';

let letVariable = 'let';
letVariable = 'let2';

const constVariable = 'const';
constVariable = 'const2'; // Uncaught TypeError: Assignment to constant variable.

それぞれ、一度宣言しその後、再代入(値を変更)しています。

var, letでは再代入はできますが、constではできません。 constは他の言語でいう定数のようなものなのです。

ブロックレベルのスコープ

ブロックとは{}で囲まれたコードのことです。 スコープとは、変数の有効範囲のことで、プログラムのどの場所から参照できるかを決める概念のことです。

つまり、ブロックレベルのスコープとは{}で囲まれた範囲でのみ変数を参照できるということです。

if (true) {
    var varVariable = 'var';
}
console.log(varVariable); // var

if (true) {
    let letVariable = 'let';
}
console.log(letVariable); // Uncaught ReferenceError: letVariable is not defined

if (true) {
    const constVariable = 'const';
}
console.log(constVariable); // Uncaught ReferenceError: constVariable is not defined

どれもif節の条件はtrueなので必ず、ブロックの中を通りますが、var以外は未定義と言われます。

つまり、let, constでの変数は参照できる範囲が限定されているのです。

変数の巻き上げ

変数の巻き上げとは、スコープ内で宣言された変数は、実際に宣言された場所に関係なく、 スコープの先頭で宣言されたことになる というものです。

よくわからないと思うので、実際にコードを見てみましょう。

console.log(varVariable); // undefined
var varVariable = 0;

console.log(letVariable); // Uncaught ReferenceError: Cannot access 'letVariable' before initialization
let letVariable = 0;

console.log(constVariable); // Uncaught ReferenceError: Cannot access 'constVariable' before initialization
const constVariable = 0;

どれもconsole.log()を実行した時点では、変数が宣言されていません。

なので、letVariable,constVariableはエラーが発生します。

しかし、varVariableの場合は、undefinedになっています。

何故でしょうか?

これは変数の巻き上げが起きるために以下のコードと同じ処理になっているからなのです。

var varVariable; // スコープの先頭で宣言
console.log(varVariable); // undefined
var varVariable = 0;

このように、var varVariable;がスコープの先頭で宣言されていることになるのです。

では、letやconstは変数の巻き上げは起こらないのでしょうか?

そうではありません。実は、 巻き上げを行うが参照することは出来ない のです。

以下のコードを見てください。

let variable = 'This is global.';

var myFunc = function(){
    console.log(variable);
};

var myFunc2 = function(){
    console.log(variable);
    var variable = 'This is local.';
    console.log(variable);
};

var myFunc3 = function(){
    console.log(variable);
    let variable = 'This is local.';
    console.log(variable);
};

myFunc();
// This is global.

myFunc2();
// undefined
// This is local.

myFunc3();
// ReferenceError: variable is not defined

myFunc()ではスコープチェーンが行われます。 ※スコープチェーンとは、JavaScriptで関数内で宣言された変数は、その関数内でしか見ることが出来ない。 関数内に変数が見つからなかった場合、外側のスコープに変数を探しにいく仕組みのことです。

myFunc2()ではvarによる変数の巻き上げが行われています。

問題はmyFunc3()ですが、変数の巻き上げが行われなかった場合は、This is global.が表示されすはずです。 ですが、実際には参照エラーになっています。

つまり、巻き上げ自体は起こっていますが、それを参照しようとするとエラーになっているのです。

ES6では、letは変数をブロックの先頭へ引き上げます。

しかし、その変数を宣言より前で参照することは、ReferenceErrorを引き起こします。

ブロックの始めから変数宣言が実行されるまで、変数は "temporal dead zone" の中にいるのです。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/let

varを使わない理由

改めてvar, let, constの違いを表にまとめるとこのようになります。

再宣言 再代入 ブロックレベルのスコープ 変数の巻き上げ
var できる できる 存在しない 起こる
let できない できる 存在する 起こるが、参照エラー
const できない できない 存在する -

では、なぜvarを使わないのでしょうか。

それは影響範囲を狭くするため!です!

varはlet, constと違いブロックレベルのスコープが存在しません。

一般的なプログラミングのルールでは「スコープはできる限り限定すべき」というものがあります。 変更される可能性が狭い方が修正をしやすいのです。

例えば、1000行と10行のコードそれぞれからバグの原因を見つけるのではどちらが楽でしょうか?

間違いなく後者だと思います。

このような理由から、varよりもlet, constを使うべきなのです。

(↓以前にオブジェクト指向について書いた記事で、グローバル変数の欠点について書いてあります。)
オブジェクト指向でなぜつくるのか?いや、、そもそもオブジェクト指向って? - バグですか?仕様ですか?筋肉です💪

let, constの使い分けは中身の値が変わる可能性があるかどうかで使い分けましょう。

2021/05/03追記: constで定義したオブジェクト、配列はプロパティの変更が可能

const object1 = {
  name: 'hogehoge',
  age: 20
}
console.log(object1);
object1.age = 21
console.log(object1);

// {name: "hogehoge", age: 20}
// {name: "hogehoge", age: 21}
const array = ['dog', 'cat']
console.log(array);
array[0] = 'bird';
array.push('monkey');
console.log(array);

// (2) ["dog", "cat"]
// (3) ["bird", "cat", "monkey"]

まとめ

再宣言 再代入 ブロックレベルのスコープ 変数の巻き上げ
var できる できる 存在しない 起こる
let できない できる 存在する 起こるが、参照エラー
const できない できない 存在する -

スコープを限定するために、varではなくlet, constを使うべき。

let, constの使い分けは中身の値が変わる可能性があるかどうかで使い分けをする。

10倍速く文章を書く方法

Slackなどのチャットツールが広まり、短い文は書くけど「文章」を書く機会は以前より減ってしまいました。

いざ、ちゃんとした文章を書く機会に出くわすと、

「長い文章書きたくない、、、チャットでいいじゃん」
「何から書けばいいかわからん、、、」
「読み返したら意味不明、また書き直さなきゃ、、、」

などと文章を書くことが苦痛で仕方ない人がいらっしゃると思います。

また、苦痛ではなくても「より短い時間」「わかりやすい」文章を書きたいと誰もが思うのではないでしょうか?

今回は、そんな人のために、「10倍速く書ける超スピード文章術」という本を紹介したいと思います。

「わかりやすくて」「役に立つ」文章を「速く」書くにはどうすればよいかまとめていきます!!

10倍速く書ける 超スピード文章術

なぜ書くのに時間がかかってしまうのか

そもそもなぜ書くのに時間がかかってしまうのでしょうか。

読者が知りたいのは必要な情報で、それが伝われば良いのです。

しかし、言い回しはどうしたらいいかなどと表現に凝ってしまい上手く書こうとするから迷い、時間がかかってしまいます。

また、本来伝えたい内容も相手に伝わらずにわかりにくい文章になってしまいます。

文章を速く書くたった一つの秘訣は「素材」を意識すること

素材とは

  • 独自の事実
  • エピソード
  • 数字

といった読み手に伝えたい内容そのものです。

伝えたい内容がわかっている、つまり素材が準備できていれば速く書くことができます。

例えば、
自分で家を建てる場合、土台を作るときにセメントを用意する。
柱を建てるときに木材を調達する。材料を切るときにノコギリを持ってくる、、、、

といった具合にその時々に準備すると途方もなく時間がかかると思います。

速く家を建てたいのなら、まず必要な材料(素材)を準備して作業に取りかかる方が早いです。

これは文章でも同じで、まず素材を準備することで文章を速く書くことができます。

文章を書くことが決まった瞬間から、常にアンテナを立てる。そしてどんどん素材を集める。 そうすれば、素材が揃い、迷わずに速く書ことができます。

大切なのは文章の表現ではなく、文章の中身、つまり「素材」です。

「どう書くのか?」ではなく「何を書くか?」に集中することが文章を速く書く秘訣です!!

素材を使って速く書く具体的な方法

では、具体的に素材を使って速く書くにはどうすれば良いかというと、以下の手順で行っていきます。

  1. 書く目的と読者を定める
  2. 素材を集める
  3. 素材を組み立てる
  4. 一気に書き切る
  5. 見直す

1. 書く目的と読者を定める

文章の目的を定める

まず文章の目的(何のためにその文章を書くのか)をはっきりさせます。

書く前からすでにわかっている文章の目的を「表面上の目的」、そこから「真の目的」(その文章を読んだ読者に何を感じてもらいたいか)まで掘り下げます。

例えば、
表面上の目的:ブログを書く
真の目的:読者に役に立ったと言われたい 自分はこういうこともやっていると知ってもらいたい

真の目的まで掘り下げる作業は1人でできる場合もあれば、誰かに質問しないと行けない場合があります。

その場合は、依頼者に真の目的を確認しましょう。

素材を集める前に、「真の目的」を確認することを習慣にしましょう。

最もやってはいけないことは目的が定まらないまま文章を書くことです。 目的を決めずに書くと「文章を書く」という行為自体が目的になってしまうからです。

大事なのは上手い文章を書くことではなく「真の目的」を達成することです。

読者を定める

次に読者を決めましょう。

なぜ読者を決めるかというと相手によって素材が変わってしまうからです。

例えば、
技術の話をする場合に、非エンジニアに対して専門的な言葉を使ってしまうと相手はちんぷんかんぷんです。
逆にエンジニアに専門的な言葉を使わずに話すと、この人はあまりわかっていないんだなと思われるかもしれません。

書き手として意識することは読者の役に立つものになっているか、素材がわかりやすく伝わるかです。

また、自分にとって面白いことが、必ずしも読者にとって面白いわけではありません。

読者の知識レベルや興味関心に応じて何が面白いかを考えることで、適切な素材をピックアップできます。

では、不特定多数の読者がいた場合はどうすれば良いでしょうか?
例えばブログなど。

その場合でも特定の読者を決めることが必要です。

年齢、属性で特定の層をイメージします。時には読者の悩みに踏み込んでイメージすることもあります。

例えば、
20代男性エンジニア 書いた文章が相手に伝わらないことに悩んでいる

あなたの文章を読む人は個性を持った1人の個人なので、みんなに伝わる文章を書こうとすると結果的に誰にも伝わらない可能性があります。

2. 素材を集める

次に、素材を集めましょう。

書き始めてから素材を集めようとすると時間的にも精神的にも大きな負荷がかかります。
素材は早めにたくさん集めてあとで削ると良いです。

集め方としては、単純にメモをとりましょう。
人間の記憶はあてにならないので、その場で見たもの聞いたこと感じたこと全てメモしましょう。(私の場合は、本を読み進める中で本文に線を引いて素材を集めていました。)

素材を書き出す際には使えないとか考えずに思いついた順に書き出しましょう。

f:id:takuma521:20200209130630p:plain
実際に素材を書き出したもの

特に自分の見た情報、体験した情報もメモを取り、文章に盛り込むことで読者に臨場感を伝えられます。
書き手が体験したことは文章の中にインパクトを与え、他の人には出せないその書き手だけの説得力が生まれます。

3. 素材を組み立てる

次に集めた素材を組み立てましょう。

最初にやることは集めた素材を全て見えるようにしましょう。テキストファイルに全て書き出すなど。

面倒臭がって素材を書き出す手間を省くと素材が足りなくなって拾い集めに戻るという手間が生まれます。
それが書き上げるスピードを落とす原因になるのです。

次に実際に組み立てていきます。 スラスラ理解できる文章を書くには、読者が目の前にいて、その人に話すつもりで素材の順番を考えていきましょう

会話では相手に伝わらなかった場合には、

「ちょっと何言ってるかわからない」

など相手からすぐ反応があり、言い直せますが文章ではそれができません。

ロジカルシンキングや文章の型にはめなくていいので、目の前の相手に伝わるように素材を組み立てるとその人にもっとも伝わりやすい論理が生まれます

文章のはじめ

そもそも、誰も積極的に文章を読みたがっていません

なので、書き出しがつまらない文章が最後まで読まれる可能性は低いです。

代表例は「私は」から文章です。私が書いているのだから書かなくてもわかります。
このような不要なものは書かないようにしましょう。

書き出しの役割はその先を読みたいと思ってもらうことです。

文章のはじめは、もっとも共感できる素材、印象深い素材、気になる素材を配置すること。

そうだよね、ふむふむ、へえ、お!、えっ?、なんだそれ?、しゅごい!!!!

と思えるような内容を書き出しにぶつけましょう!!

文章の終わり

オチにこだわらずにまとめを書くと読後感が良いです。

文章の目的とは、読者にどんな読後感を持ってもらうかでなので文章の最後には結論やまとめを書けば良いです。

そうすれば、読者にこの文章が伝えたかったことが改めて伝わります。

4. 一気に書き切る

素材が集まったらさっさと書きましょう!!

速く書く最大のメリットは

  • 確実に締め切りを守ることができる
  • 追い詰められるとストレスがなくなる です。

最初から完璧を目指そうとするとスピードが落ちるので、推敲して整えることを前提に、まずは文章を書き終えましょう。

書きながら途中でなんども止まっていたら一気に読める文章になりません。

誤字も表現も書いている途中に悩まずに書きましょう。

読みやすい文章を書くポイント

  • 一文を短く
    →60字くらい

  • スラスラ読めるリズムを作る
    →ですます調の中にである超の文章を適度に織り交ぜる 似た意味のフレーズを少しバリエーションを変えて繰り返す

  • 「」の強調使用

  • だから、また、さらになどの順接の接続詞を使わない
    →冗長な印象を与えてしまう

  • 逆説の接続詞で展開を生む
    →逆説された部分が強調されリズムも生まれる

  • 難しい日本語を翻訳する

基本方針は多く書いてあとで削るなので、書いているときに全体の分量を気にしないようにしましょう。

あと、読者と目的を目に見える場所に置いておくことで途中見失わないようにできます。

5. 見直す

速く書くメリットは、文章を寝かせることができることです。

少し時間をおくことで書き手は客観的な視点を得ることができ、初めて読む人の視点で冷静に文章を修正することができます。

文章を推敲する目的は

  • 読みやすくする
  • わかりやすくする

です。

速く推敲を終えるために大きいところから取り掛かり、その後細かい箇所を見ましょう。

最初の遂行

  • 論理が正しいか
  • 説得力に欠けていないか
  • 文脈に沿った素材か
  • 一気に読めるか
  • 重複している点はないか

初見の見直しが一番読者に近い視点です。何度も見直してしまうと、その視点が薄れてしまいます。

最初は修正を加えずにピックアップするだけです。

次にようやく細かくチェックしていきます。

  • 意味不明な箇所はないか
  • 説明不足な箇所はないか
  • 読者、文章の登場人物に失礼な言い回しがないか
  • 読者に嫌悪感を与えないか

素材が的確に伝わっているかどうか以外に読者に不快感を与えないかも重要です。

ボリューム調整は終盤にやります。

そして最後に誤字脱字を修正していきましょう。

わかりやすさを確認する方法

  • 何も知らない人を前提にしているかどうか
    →専門用語が出てくると読む気が失せる人がいるから、専門用語は必ず噛み砕く

  • 意味不明な形容詞を素材に置き換える
    →形容詞だけを書いても何に感動したかが伝わらない、本来書くべきは何が面白かったか楽しかったかの理由。つまり素材 例)すごく寒い(どのくらい寒いの??)→マイナス5度(読者に想像できる寒さ)

まとめ

表現に凝ってしまから文章を書くのに時間がかかってしまう。

素材が準備できていれば速く書くことができる

手順

  1. 書く真の目的と特定の読者を定める
  2. 体験したことをメモに取り素材を集める
  3. 読者に喋って伝えるつもりで素材を組み立てる
  4. 完璧を目指さず一気に書き切る
  5. 大きい箇所から細かい箇所に向かって見直す

最後に

実際にこのやり方でこのブログを書きました。

本に線を引きながら読んだ後、素材を書き出すからブログを公開するまでには3、4時間ほどかかりました。

以前同じように本の紹介を書いた記事は2倍かかっていました。内容が難しかったというのもありますが、、、

実際に試してみて良かったことは、

  • 素材を最初に集めたことで、文章が組み立てやすかった。
  • 文章を組み立てた後は一気に書き切れた。

ただ、うまくいかないこともありました。

  • 組み立てる際に素材の繋がりがわからなくて素材集めに戻ってしまうことが何度かあった。

です。

今後も、このやり方をブログや文章を書く時には活用したいと思います! 皆さんもぜひ試してみてください!!

今回書けなかったこともあるので、ぜひ本も読んでみてください!!

10倍速く書ける 超スピード文章術

10倍速く書ける 超スピード文章術

エンジニアリング組織論への招待まとめ

はじめに

今回は、「エンジニアリング組織論への招待」という本のまとめを書いていこうと思います。

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

エンジニアは仕事を進めていく上でコードを書く以外に様々な問題に直面します。

  • 上司、プロジェクトメンバーとのミスコミュニケーション
  • 経営者とエンジニアとの認識の食い違い
  • スケジュール通りに終わらない

これらの根源は「わからない」ことへの不安です。
この本はその不安、つまり不確実性とどう向き合っていくかについて書かれています。

今回は、1章の思考のリファクタリングについてまとめていきます!

この記事を読んでわかること

  • エンジニアリングとはなにか
  • 不確実性とはなにか
  • 不確実性を下げるには

エンジニアリングとは

エンジニアリングとは、何か役に立つものを実現していくこと(曖昧さを減らし、具体性、明確さを増やすこと)です。

エンジニアリングする上で重要なのは、どうしたら効率よく不確実性を減らしていけるかです。

不確実性とは

不確実性とは、わからないことから生まれます。人間にとってわからないことは2つ

  • 未来
  • 他人

未来は、それがやってくるまでどうなるかわかりません。
頭でいくら考えていてもわからないものなので、実際に行動し、実験して観察することで少しずつ確実になっていきます。

他人も、わかりません。

私たちは1人1人別の自意識を持っていて全ての情報を一致させることは不可能です。 これもいくら考えていても決してわかるものではないので、コミュニケーションを通じて不確実性を削減するしかありません。

この2つの不確実性を減らしていくことが唯一物事を実現させる手段です。
しかし、私たちはわからないものに向き合うことを避けてしまうという習性があります。

それが不安です。

私たちは不安なものには、攻撃か逃避を選択してしまいます。なので人は自分がわかっているものを優先して実行してしまう癖があります。

不確実性が減っていかない限り不安は減りませんし、向き合おうとするとそれ自体が最大の不安を生み出してしまいます。

不確実性を下げるには

ではどうすれば良いのか。

不確実性を下げるには、情報を生み出すことが必要です。

いかにして、多くの情報を生み出すことができるのか、そのために何をすべきなのかというのがこの本の一貫したテーマであり、エンジニアリング活動の本質の1つです。

情報を生み出すには思考を前に進める必要があります。
ここでは3つの考え方を用いて思考を前に進めていきます。

  • 論理的思考の盲点を知る
  • 経験主義と仮説思考
  • システム思考

それぞれみていきましょう。

論理的思考の盲点を知る

思考を前に進めるには論理的思考が不可欠です。

論理的思考で正しい結論を導くには、

  • 事実を正しく認知できること。
  • 正しく演繹できること。

が、必要です。

(演繹は「Aである」という前提から、「Bである」という結論を導くことです。
A:人間はいつか死ぬ。B:私はいつか死ぬ)

しかし、人は論理的な思考を常に正しく使えるわけではありません。

特に他人が関わってくる問題に対しては感情的になりやすいです。

私はあなたではないという単純なことが、忘れられてしまい、自分の事情は全て相手に伝わっているのだという勘違いも発生します。

どんなに自分が正論だと思っていることも、その人自身の世界の中で認識できる範囲の中での正論にすぎず正解ではないのです。

どんな時に自分は論理的で無くなるのかを知った上で問題解決に臨む、それが論理的思考を進める上で重要なことです。

自分は論理的に考えることができると思いこむことこそが非論理的な思考を生みます。

それを踏まえた上で自分がどのようなときに認知が歪むのかを知り、自分の歪んだ認知を正すための行動を促す考え方が論理的思考の盲点を知るということです。

  • 自分がいつ非論理的になるかを知ること。
  • 自分は間違っているかもしれないが、それに早く気付く方が良いと思考のパターンを変える必要がある。

経験主義と仮説思考

情報を生み出す際に有効なのがこの経験主義仮説思考です。

経験主義

情報を入手するために行動を起こして、その結果を観察し、そこから問題解決を行う考え方を経験主義と言います。

私たちが、何か問題に出くわした時にできることとは、

  1. コントロールできるものを操作する
  2. 観測できるものの結果をみる

だけです。

コントロールできるものとは、例えば、自分の行動です。例えば毎週ブログを書くとかです。これは自分の行動次第でコントロールできます。

逆に、例えば、コントロールできないものはブログの読者を増やすことです。しかし、これは観測できることなので実際に自分がブログの書く内容を変えてみたことで結果読者が増えた減ったなどの結果を見ることができます。

経験主義は、やってみなければわからないだけの論理ではなく、上記の方法でしか前に進むことができないということを意味しています。

仮説思考

仮説思考とは、情報がわずかであってもそれを説明可能とする大胆な思考展開を行い、それを検証するための行動につなげる考え方です。

この考え方は、常に正しいわけではありませんが、今あるデータからは、演繹的に導くことのできない跳躍を生み出してくれます。

経験主義と仮説思考によって、どのような問題なのかをはっきりさせることで、同じところをぐるぐる回る不毛な思考を避けることができます。

(不毛な思考は、仕事で解決できない問題にハマってしまった時に、考えているようで考えていないような状態に近いですね笑)

  • 今直ぐに解くことのできない問題であれば、それはおそらくどのような問題かはっきりしていない。
  • 問題をはっきりさせる仮説を立てて、検証していくというプロセス思考に思考を切り替えることが大切。

システム思考

人は問題を個人の責任にしたり、全体像を見失った局所最適解な思考をしてしまいます。

それが全体像ではないかもれない、問題は関係性にあるのではないかという視点をもつことがこのシステム思考の考え方です。

私たちはつい自分から見える世界の中に閉じこもって、正しさや合理性を判断しています。
しかし、人間が認知している範囲というのは、全体のごく一部にすぎません。

問題は複雑に絡み合っている場合があります。

そのため、合理的に見える解決策が別の問題を引き起こしたり、想定していない悪化をもたらすことがあります。

このように全体像を把握できない状態で、問題解決を進めて行こうとすると思いもよらない結果を生むことがあります。

そうならないためには、

  • 対立に見える問題を対立にならない全体像をあぶりだすこと。
  • その解決を個人の問題にせず、関係性の問題に変換して本当の問題を発見すること。

が必要になってきます。

人間の不完全さを受け入れる

問題が難しく感じられているときには、まだ問題が十分に変換されていません。

この章のタイトルである思考のリファクタリングとはこの3つの考え方を用いて、複雑な問題を簡単に変換していき思考を前に進めていくということです。

自分の認知の歪みをパターンとして記憶することで過ちに気が付きやすくするという習慣を持つことができます。そうすれば少しずつ改善していきます。

コミュニケーションの不確実性

コミュニケーションの不確実性は3つの不確実性からきます。

  • 人は、他人や事象を完全に理解できない。
  • 相手に全てが正しく伝わるとは限らない。
  • また、正しく伝わったからといって、他人が思ったように行動するとも限らない。

これらの不確実性によって、さらに以下の問題が引き起こされます。

  • 自分は知っているけど他人は知らないといった情報の非対称性

→自分の抱えている状態を他人は把握しているはずだと勘違い、あるいは把握してほしいという願望に基づいて行動してしまいます。

  • 人は限られた範囲でしか合理的な行動が取れない非合理性

→複数人の共同作業では、個々人が最適だと思う行動でも、全体として不合理な行動になってしまいます。

通常エンジニアリングは複数人で何かを実現しますが、上記のために、1人ではなかなか起こらないはずの不合理な行動が、組織では発生してしまいます。

このような情報の非対称性や非合理性を起こさないためには、

意思決定とそれに関わる情報が組織内に正しく整合性をもって伝達されるように継続して努力し、何かわからない決定があったとしても直接聞いてみようという関係性を作ること

が必要です。

まとめ

エンジニアリングは何かを実現していくことで、重要なのは不確実性を効率よく削減することです。

不確実性は、わからないことで

  1. 未来
  2. 他人

から生まれます。

これらを解消するには情報を生み出すことが必要です。
つまり思考を前に進めること。

それには3つの考え方があります。

  • 論理的思考の盲点を知る
  • 経験主義と仮説思考
  • システム思考

これらの考え方を使い、自分自身の認知の歪みをパターンとして記憶することで、過ちに気が付きやすくなる習慣を持つようにします。

そうすれば、少しずつ改善でき思考が前に進むようになります。

そして、エンジニアリングは組織で複数人で行うので、 それらを行いながら同じ目的で働いているはずの人々との間にあるコミュニケーションの不確実性を減らしていく必要があります。

最後に

この本を読んで確かになぁと思うことがいくつもありました。

例えば、他人と少し言い争いになる時って、正論をぶつけているつもりですが、それって結局自分の中の正論だったり常識なんですよね。

相手もそういうものを持っていて、結局何も良くならずにお互いにストレスを溜めてしまうだけみたいな。

そういう時に、非論理的思考の盲点を思い出してこれはただ自分の正論に過ぎないんだとか、システム思考的にこのまま言い争って言い負かしても意味ないな、どうしたら本来の目的を達成できるかなと考えた方が有益です。

経験主義と仮説思考もエンジニアの仕事をする上で、大切です。

本文にも書きましたが、ずっと考えてわからないものはわかりません。

そこで、考え続ける(実際にはあんまり頭は動いていない)よりは、どんな情報があれば解決できるだろうかとか、誰に聞けばわかるだろうかとだけ考えて直ぐに行動し、その結果からまた思考をする方が問題解決にとって効率的だなと思いました。

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

webを支える技術 REST

去年読み始めたwebを支える技術でしたが、途中で放置していました。
今年は違うぞということで、ここ2週間くらいで改めて最初から最後まで読み通しましたので、そのアウトプットとして今回記事を書こうと思います!

今回はRESTについてです!!

この記事を読んでわかること

  • RESTとはなんであるか。RESTを構成するアーキテクスチャスタイルについて。

REST

RESTは複数のアーキテクチャスタイルを組み合わせた複合アーキテクチャスタイル。
アーキテクチャスタイルと言う言葉がいまいちピンとかなかったけど、調べてたら設計思想というのがなんとなくしっくりきました。

リソース

リソースについては過去の記事で書いてありますので、そちらを!

HTTPとは - バグですか?仕様ですか?筋肉です💪

RESTを構成するアーキテクチャスタイル

クライアント/サーバ

クライアント側とサーバ側で分けることでつまり、ユーザーインターフェースと処理を分けることです。
これによりwebにpc以外でアクセスすることができます。また、複数のサーバを組み合わせることで可用性(システムが継続して稼働できる能力)を上げられます。

ステートレスサーバ

クライアントのアプリケーションの状態をサーバ側で管理しないことです。そうすることでサーバの実装を簡略化できます。ただcookieはステートフルなものです。 ↓過去に例を交えながら説明しています!

HTTPとは - バグですか?仕様ですか?筋肉です💪

キャッシュ

一度取得したリソースをクライアント側で使い回すことです。
何度も通信をしないで済むが、古いキャッシュにより情報が間違っているかもしれないので注意です。

統一インターフェース

URIで指し示したリソースに対する操作を統一したインタフェースで行うことです。
分かりづらいので例を上げるとHTTPは8つのメソッドだけしかありません。少なすぎて使い勝手が悪いように思われるかもしれませんが、これにより対応しなくてはいけないものが少なくなり、結果としてシンプルにすることができます。

階層化システム

サーバとクライアントの間に負荷を分散してくれるロードバランサを置いたり、アクセスを制限してくれるプロキシを置いたりすることです。
これは統一インターフェース(インターフェースをHTTPで統一)のおかげです。

コードオンデマンド

プログラムをクライアントにダウンロードして実行することです。例えばJavaScriptなどがあげられます。

最後に

以上、今回はRESTについてまとめてみました! RESTってよく聞くけど、それってどういうものなの?っていうのが今まで曖昧でしたが、改めて理解することができました。

私は、業務で主にRubyrails扱っています。railsは便利なので、webのことを理解していなくてもなんとなく書けてしまうのですが、このwebを支える技術を読んで、URIやHTTPを理解してから、このリソースを更新したいからここにリクエストをしないといけないんだなとか、ルーティングはこう書かないとなとかがわかるようになりました。

本を読むだとか、アウトプットをするということを続けるのは大変ですが、仕事に直結しますし自分をより良くすること、(つまり筋トレと同じ)なので今後も続けて行きたいと思います!!(^∀^)ᕗ

クールなURIとは

前回と引き続き

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

の本からURIについて書いていきます!!

この記事を読んでわかること

  • なぜ変わらないURIはクールなのか
  • 変わりにくいURIするには
  • URIを変えなくてはいけない時はどうするか

なぜ変わらないURIはクールなのか

変わらないURIがクールである

という言葉があります。なぜ変わらないURIがクールなのでしょうか?

Webはそれぞれのリソースに他のリソースが埋め込まれたハイパーメディアシステムのため、URIを変更しリンク切れを起こすと機能しなくなってしまいます。

通常ユーザは、ページにあるリンクをクリックすることで、見たいページに遷移します。 しかし、そのリンクのURIが変わってしまうとユーザはページ遷移ができなくなってしまうので、webとして機能しなくなってしまうのです。

つまり、URIは出来るだけ変わらないものが好ましい(クールである)のです。

本では主に3つ紹介されていましたので、ダメなURIを例にあげて説明していきたいと思います。

プログラミング言語に依存した拡張子やパスを含めない

http://example.jp/login.pl

例えばこのURIの場合、.plというPerlというプログラミング言語のソースに使われる拡張子が使われています。
もし仮に、PerlからRubyに言語を変えてアプリケーションを実装するとなると、URIを変更しなければなりません。 (.plでRubyスクリプトを動かすこともできますが、あまりよくはありませんよね。)

このように実装言語に依存した文字列をURIに含めてしまうと、言語を変更した際にそのURIは使えなくなってしまします。

メソッド名やセッションIDを含めない

http://eample.jp/Login.do?action=showPage

.doという拡張子も問題ですが、今回はshowPageが問題です。これはメソッドの名前なのですが、 もしリファクタリングを行なってメッソド名を変更してしまうとURIも変更になってしまいます。

セッションIDの場合、

http://example.jp/home.jsp?jsesionid=123456789

セッションIDをCookieではなくURIに埋め込むとログインのたびにセッションIDは変わるので、その度にURIも変更になってしまいます。

URIはリソースの名詞にする

http://example.jp/sample/people/show/1234

URIはリソースの名前です。なので本来名詞であるべきです。

あるリソースを取得するのか更新するのかは、URIで指定するのではなく、HTTPメソッドで決定されます。 つまりURIとHTTPメソッドは、名詞と動詞となるように設計されるべきで、showという動詞をURIに含めることはよくありません。

URIを変えないといけない時は?

変わらないURIがクールな理由と、具体的に変わりにくくするためにはどうするべきかについて書きました。

しかし、システムには変更はつきものであるように、URIも変更しなければいけない時があります。 その場合の対処法として、本では出来るだけリダイレクトをするようにと書かれていました。

リダイレクトとは、古いURIから新しいURIに転送するHTTPの仕組みで、リダイレクトしてあげればリンク切れでユーザが見たいページに遷移できなくなる心配も無くなります。

URI

この記事を読んでわかること

  • URIとは何か
  • URLやURNとの違いは何か
  • 実際のURLの構文はどのような構造になっているのか

URIとは

URI(Uniform Resource Identifier)とは、直訳すると「統一リソース識別子」です。

リソースは前回、説明しましたが、「web上のありとあらゆる情報」のことです。

HTTPとは - バグですか?仕様ですか?筋肉です💪

なので、URIとは「web上の情報を統一的に識別するID」のことであり、それを用いるとリソースを一意に識別することができます。

URIとURLとURN

URIと似た用語でURL(Uniform Resource Locator)やURN(Uniform Resource Name)という用語もありますが、違いは以下のようになります。

URLは、リソースの場所を指し示すもの

URNは、リソースの名前を示すもの

URIは、URLとURNを総称する名前でリソースを識別するもの

URIの構文

http://takuma:pass@blog.example.jp:8000/search?q=test&debug=true#10
※ダミーです

このURIは次のように分けられます。

  • URIスキーム:http
  • ユーザ情報:takuma:pass
  • ホスト名:blog.example.jp
  • ポート番号:8000
  • パス:/search
  • クエリパラメータ:q=test&debug=true
  • URIフラグメント:#n10

URIスキーム:http

URIスキームは、そのURIが利用するプロトコルを示すのが一般的です。
この場合は、リソースにHTTPでアクセスできることを示します。

ユーザ情報:takuma:pass

ユーザ情報は、このリソースにアクセスする際に利用するユーザ名とパスワードからなります。

ホスト名:blog.example.jp

ホスト名はDNS(Domain Name System)で名前が解決できるドメイン名かIPアドレスで、 インターネット上で必ず一意になります。

ポート番号:8000

ポート番号は、このホストにアクセスするときのプロトコルで用いるTCPのポート番号を示します。 同じコンピュータ内で動作する複数のソフトウェアのどれが通信するかを指定します。

パス:/search

ホストの中でリソースを一意に示します。 このように、ホスト名とパスを組み合わせることで、あるリソースのURIが世界中で重複せず一意になります。

クエリパラメータ:q=test&debug=true

検索サービスや検索キーワードを渡す時など、クライアントから動的にURIを生成する時に利用します。

URIフラグメント:#n10

その前までの文字列で表現するURIが指し示すリソース内部の、さらに細かい部分を指定する時に利用します。

最後に

今回も前回に引き続き、「webを支える技術」をまとめました。
少しずつでも今まで理解していなかったweb関連の用語をアウトプットしていき、使いこなせるように続けていきます💪

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

HTTPとは

この記事を読んでわかること

  • HTTPとは何か。
  • HTTPの特徴であるステートレス性とはどういうものか。

背景

Web業界に入ってから数ヶ月経ち、プログラミングのこともまだまだですが、そもそもwebの知識が乏しいと感じていたので、 今日は、HTTPについて簡単にまとめてみました。

参考:

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

HTTPとは

HTTP(Hyper Text Transfer Protocol)はweb上でやり取りするリソースの表現を、クライアントとサーバの間でやり取りするためのTCP/IPをベースとしたプロトコル

と言われても、なんのこっちゃわかりません。 こういうわからない用語を調べて、さらにわからない用語が出た時は、さらにその用語を調べていくしかありません。。。 ここで出てきたよくわからない言葉、

を先に説明します。

リソース

リソースとは、web上のありとあらゆる情報。

例えば、

など。

特に、あるリソースを他のリソースと区別して指し示すときに使う名前をURIと呼びます。

クライアントとサーバ

クライアント(webブラウザ)が、情報を提供するサーバ(webサーバ)に接続し、各種のリクエストを出して、レスポンスを受け取る。 サーバでの処理に時間がかかる場合でも、リクエストを出したクライアントはレスポンスが返るまで待機する。

プロトコル

プロトコルとは、通信をする上での約束事

TCP/IP

TCP/IPとは、TCP(Transmission Control Protocol)とIP(Internet Protocol)は、インターネットの基盤を構成する重要なネットワークプロトコル。 HTMLやXMLなどのハイパーテキストだけでなく、静止画、音声、動画、Javascriptプログラム、PDFや各種オフィスドキュメントなど、 コンピュータで扱えるデータであればなんでも転送できる。

IPは、インターネット層でデータを実際にやり取りする部分を担当している。 指定したIPアドレスを送り先として、パケット単位でデータをやり取りして通信する。しかし、多数のルータを経由して最終的な送り先まで届くかは保証しない。

TCPは、IPが保証しなかったデータの転送を保証するトランスポート層に相当する。

で、ここまでを踏まえて改めて先ほどの説明を言い換えると、

HTTP(Hyper Text Transfer Protocol)はweb上のありとあらゆる情報を、クライアントとサーバの間でやり取りするためのTCP/IPをベースとした通信の約束事。

(あまり変わってない笑)

HTTPのステートレス性

次にHTTPの特徴であるステートレス性ついて触れてみたいと思います。

ステートレス性とは、サーバがクライアントのアプリケーション状態を保存しない制約のことです。 ステートレスとは、逆にステートフルという言葉がありますが、両者の違いについて日常でよくあるやりとりを例に挙げて、説明します。

Aをクライアント、Bをサーバだと思ってください。

ステートフルなやりとり

A「筋トレを教えてください!!」

B「どうして筋トレを教えて欲しいの?」

A「筋肉を大きくしたいんです!!」

B「どこの筋肉を大きくしたいの??」

A「足の筋肉を大きくしたいんです!!」

B「じゃあスクワットやろうか(^∀^)ᕗ」

A「はい!!」

ステートレスなやりとり

A「筋トレを教えてください!!」

B「どうして筋トレを教えて欲しいの?」

A「筋肉を大きくしたいので、筋トレを教えてください!!」

B「どこの筋肉を大きくしたいの??」

A「足の筋肉を大きくしたいので、筋トレを教えてください!!」

B「じゃあスクワットやろうか(^∀^)ᕗ」

A「はい!!」

このように、ステートフルなやりとりはそれまでのやりとりをずっと覚えていることを前提に会話をしています。 逆にステートレスなやりとりは、記憶することができないので、都度「筋トレを教えてください!!」を言わないと教えてくれません笑笑

側から見たら、ステートフルなやりとりの方が簡潔で良いのではと思いますが、欠点があります。

それは、サーバがクライアントのアプリケーションの状態を覚えることは、クライアントの数が増えるにしたがい難しくなるからです。

不特定多数のクライアントを相手にする場合、サーバ間でデータを同期しなければいけませんが、それが100台となるととても負荷のかかることです。 なので、ステートフルでは、サーバの数を増やしづらいのです。

その点ステートレスは、アプリケーションの状態を覚える必要がないため、サーバ側のシステムは単純になり、拡張するときにはただサーバを増設するだけで済んでしまうのです。

このように、プロトコルをシンプルに保つことで、PCだけでなく様々なデバイス上でHTTPは使われています。

最後に

本の数10ページについてまとめましたが、まだまだ浅い記事しか書けないなと思いました。 ただ、続けることが大切なので自分のできる範囲でまずはやっていきたいと思います。