【js】ES6 分割代入
ES6から分割代入というものが導入されました。 分割代入とは、配列/オブジェクトを分解し、配下の要素/プロパティの値を個々の変数に分解するための構文です。
今回は、分割代入の使われ方について説明します!
オブジェクト
let person = { name: 'ラム', birthDate: '2月2日', };
このpersonオブジェクトのプロパティname, birthDateをそれぞれ変数に代入したい場合。
ES6以前では、
let name = person.name; let birthDate = person.birthDate; console.log(name); // ラム console.log(birthDate); // 2月2日
でしたが、ES6からは
let { name, birthDate } = person; console.log(name); // ラム console.log(birthDate); // 2月2日
1行にまとめて書くことができます!!
プロパティとは異なる変数名に変えたい時は、
let { name, birthDate: birthday, hairColor = '赤' } = person; console.log(birthday); // 2月2日 console.log(hairColor); // 赤
変数名:別名
として指定してあげることもできます。
またhairColorのようにデフォルト値を設定することもできます。
※オブジェクトのプロパティに存在しない、かつ、デフォルト値を設定しない場合は、undefined
となります。
配列
次は配列です!
const quartetto = [ 'このすば', 'リゼロ', '幼女戦記', 'オバロ' ];
配列からそれぞれの値を変数に入れたい場合、
const [ title1, title2, title3, title4, title5 ] = quartetto; console.log(title1); // このすば console.log(title2); // リゼロ console.log(title3); // 幼女戦記 console.log(title4); // オバロ console.log(title5); // undefined
これもまた1行にまとめることができます!
今回は配列でしたが、配列はlength
というプロパティを持っているので、
const { length } = quartetto; console.log(length); // 4
オブジェクトの分割代入のやり方で取り出すことができます。
違いは、
- {}はオブジェクトのプロパティ
- []は配列の要素抽出
です!
また、...
演算子を使うことで、個々の変数に分解されなかった残りの要素をまとめて配列として切り出すことも可能です。
const [ title1, title2, ...otherTitle ] = quartetto; console.log(title1); // このすば console.log(title2); // リゼロ console.log(otherTitle); // ["幼女戦記", "オバロ"]
otherTitleに残りのタイトルが入っていることがわかります!
オブジェクトと配列の組み合わせ
オブジェクトの配列
オブジェクトと配列を組み合わせるとどうなるでしょうか?
まずは、配列の中にオブジェクトがある場合を見ていきましょう。
const quartetto = [ { title: 'このすば', mainCharacter: 'カズマ' }, { title: 'リゼロ', mainCharacter: 'スバル' }, { title: '幼女戦記', mainCharacter: 'ターニャ ' }, { title: 'オバロ', mainCharacter: 'アインズ' } ];
今までの書き方では、
const mainCharacter1 = quartetto[0].mainCharacter; console.log(mainCharacter1); // カズマ
冗長になってしまいますが、ES6からはシンプルに書けます!
const [{ mainCharacter }] = quartetto; console.log(mainCharacter); // カズマ
[]
だけだと、
const [mainCharacter] = quartetto; console.log(mainCharacter); // {title: "このすば", mainCharacter: "カズマ"}
こうなります!
この中のmainCharacter
を取り出したいので、
const [{ mainCharacter }] = quartetto;
このように書きます!
配列のオブジェクト
今度は逆にオブジェクトの中に配列があるパターンを見てみます!
const rezero = { character: ['ram', 'lem', 'emilia', 'subaru'] }; const { character: [first] } = rezero; console.log(first); // ram
シンプルになります!
関数
分割代入を利用し名前付き引数をシンプルにする
次は関数です!
名前付き引数をとる場合に以前は、
function signup(username, password, email, birthday) { // サインアップする処理 console.log(`ユーザー${username}がサインアップしました。`); }; signup('lem', 'subarukun', 'lem-subarukun@hoge.com', '2月2日'); // ユーザーlemがサインアップしました。
これだと、引数が多くてどんな引数が必要だったかとか間違いの元になってしまいます。
ES6では、
function signup({ password, email, birthday, username }, defaultValue = 'default' ) { // 引数の順番を気にしなくてよい!! // サインアップする処理 console.log(`ユーザー${username}がサインアップしました。`); }; const user = { username: 'lem', password: 'subarukun', email: 'lem-subarukun@hoge.com', birthday: '2月2日' } signup(user); // ユーザーlemがサインアップしました。
オブジェクトを引数に渡すことができます!
この書き方は、関数を呼び出す際にシンプルに書けるのもメリットですが、関数を宣言する際に引数の順番を気にしなくてもよくなります!
複数の戻り値を個別の変数に代入する
最後に複数の戻り値を別々の変数に代入したい場合を見ていきます!
function getMaxMin(...nums) { return [Math.max(...nums), Math.min(...nums)]; }
受け取った引数の中から最大値と最小値を配列として返す関数があります。
let result = getMaxMin(10, 78, -4, 12, 90); console.log(result); // [90, -4]
配列のままですが、分割代入を使うと、
let [max, min] = getMaxMin(10, 78, -4, 12, 90); console.log(max); // 90 console.log(min); // -4
1行で代入できます!
また、最小値だけしか必要ない時は、
let [, min] = getMaxMin(10, 78, -4, 12, 90); console.log(min); // -4
のように書くことができます!
まとめ
// オブジェクト let { name, birthDate: birthday, hairColor = '赤' } = person; // 配列 const [ title1, title2, ...otherTitle ] = quartetto; // オブジェクトの配列 const [{ mainCharacter }] = quartetto; // 配列のオブジェクト const { character: [first] } = rezero; // 名前付き引数を持つ関数 function signup({ password, email, birthday, username }, defaultValue = 'default' ) { // 引数の順番を気にしなくてよい!! // ユーザーを作成してDBに保存する処理 console.log(`ユーザー${username}がサインアップしました。`); }; // 複数の値を返す関数 let [max, min] = getMaxMin(10, 78, -4, 12, 90);
【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倍速く書ける超スピード文章術」という本を紹介したいと思います。
「わかりやすくて」「役に立つ」文章を「速く」書くにはどうすればよいかまとめていきます!!
- なぜ書くのに時間がかかってしまうのか
- 文章を速く書くたった一つの秘訣は「素材」を意識すること
- 素材を使って速く書く具体的な方法
- 1. 書く目的と読者を定める
- 2. 素材を集める
- 3. 素材を組み立てる
- 4. 一気に書き切る
- 5. 見直す
- まとめ
- 最後に
なぜ書くのに時間がかかってしまうのか
そもそもなぜ書くのに時間がかかってしまうのでしょうか。
読者が知りたいのは必要な情報で、それが伝われば良いのです。
しかし、言い回しはどうしたらいいかなどと表現に凝ってしまい上手く書こうとするから迷い、時間がかかってしまいます。
また、本来伝えたい内容も相手に伝わらずにわかりにくい文章になってしまいます。
文章を速く書くたった一つの秘訣は「素材」を意識すること
素材とは
- 独自の事実
- エピソード
- 数字
といった読み手に伝えたい内容そのものです。
伝えたい内容がわかっている、つまり素材が準備できていれば速く書くことができます。
例えば、
自分で家を建てる場合、土台を作るときにセメントを用意する。
柱を建てるときに木材を調達する。材料を切るときにノコギリを持ってくる、、、、
といった具合にその時々に準備すると途方もなく時間がかかると思います。
速く家を建てたいのなら、まず必要な材料(素材)を準備して作業に取りかかる方が早いです。
これは文章でも同じで、まず素材を準備することで文章を速く書くことができます。
文章を書くことが決まった瞬間から、常にアンテナを立てる。そしてどんどん素材を集める。 そうすれば、素材が揃い、迷わずに速く書ことができます。
大切なのは文章の表現ではなく、文章の中身、つまり「素材」です。
「どう書くのか?」ではなく「何を書くか?」に集中することが文章を速く書く秘訣です!!
素材を使って速く書く具体的な方法
では、具体的に素材を使って速く書くにはどうすれば良いかというと、以下の手順で行っていきます。
- 書く目的と読者を定める
- 素材を集める
- 素材を組み立てる
- 一気に書き切る
- 見直す
1. 書く目的と読者を定める
文章の目的を定める
まず文章の目的(何のためにその文章を書くのか)をはっきりさせます。
書く前からすでにわかっている文章の目的を「表面上の目的」、そこから「真の目的」(その文章を読んだ読者に何を感じてもらいたいか)まで掘り下げます。
例えば、
表面上の目的:ブログを書く
真の目的:読者に役に立ったと言われたい 自分はこういうこともやっていると知ってもらいたい
真の目的まで掘り下げる作業は1人でできる場合もあれば、誰かに質問しないと行けない場合があります。
その場合は、依頼者に真の目的を確認しましょう。
素材を集める前に、「真の目的」を確認することを習慣にしましょう。
最もやってはいけないことは目的が定まらないまま文章を書くことです。 目的を決めずに書くと「文章を書く」という行為自体が目的になってしまうからです。
大事なのは上手い文章を書くことではなく「真の目的」を達成することです。
読者を定める
次に読者を決めましょう。
なぜ読者を決めるかというと相手によって素材が変わってしまうからです。
例えば、
技術の話をする場合に、非エンジニアに対して専門的な言葉を使ってしまうと相手はちんぷんかんぷんです。
逆にエンジニアに専門的な言葉を使わずに話すと、この人はあまりわかっていないんだなと思われるかもしれません。
書き手として意識することは読者の役に立つものになっているか、素材がわかりやすく伝わるかです。
また、自分にとって面白いことが、必ずしも読者にとって面白いわけではありません。
読者の知識レベルや興味関心に応じて何が面白いかを考えることで、適切な素材をピックアップできます。
では、不特定多数の読者がいた場合はどうすれば良いでしょうか?
例えばブログなど。
その場合でも特定の読者を決めることが必要です。
年齢、属性で特定の層をイメージします。時には読者の悩みに踏み込んでイメージすることもあります。
例えば、
20代男性エンジニア 書いた文章が相手に伝わらないことに悩んでいる
あなたの文章を読む人は個性を持った1人の個人なので、みんなに伝わる文章を書こうとすると結果的に誰にも伝わらない可能性があります。
2. 素材を集める
次に、素材を集めましょう。
書き始めてから素材を集めようとすると時間的にも精神的にも大きな負荷がかかります。
素材は早めにたくさん集めてあとで削ると良いです。
集め方としては、単純にメモをとりましょう。
人間の記憶はあてにならないので、その場で見たもの聞いたこと感じたこと全てメモしましょう。(私の場合は、本を読み進める中で本文に線を引いて素材を集めていました。)
素材を書き出す際には使えないとか考えずに思いついた順に書き出しましょう。
特に自分の見た情報、体験した情報もメモを取り、文章に盛り込むことで読者に臨場感を伝えられます。
書き手が体験したことは文章の中にインパクトを与え、他の人には出せないその書き手だけの説得力が生まれます。
3. 素材を組み立てる
次に集めた素材を組み立てましょう。
最初にやることは集めた素材を全て見えるようにしましょう。テキストファイルに全て書き出すなど。
面倒臭がって素材を書き出す手間を省くと素材が足りなくなって拾い集めに戻るという手間が生まれます。
それが書き上げるスピードを落とす原因になるのです。
次に実際に組み立てていきます。 スラスラ理解できる文章を書くには、読者が目の前にいて、その人に話すつもりで素材の順番を考えていきましょう。
会話では相手に伝わらなかった場合には、
「ちょっと何言ってるかわからない」
など相手からすぐ反応があり、言い直せますが文章ではそれができません。
ロジカルシンキングや文章の型にはめなくていいので、目の前の相手に伝わるように素材を組み立てるとその人にもっとも伝わりやすい論理が生まれます。
文章のはじめ
そもそも、誰も積極的に文章を読みたがっていません。
なので、書き出しがつまらない文章が最後まで読まれる可能性は低いです。
代表例は「私は」から文章です。私が書いているのだから書かなくてもわかります。
このような不要なものは書かないようにしましょう。
書き出しの役割はその先を読みたいと思ってもらうことです。
文章のはじめは、もっとも共感できる素材、印象深い素材、気になる素材を配置すること。
そうだよね、ふむふむ、へえ、お!、えっ?、なんだそれ?、しゅごい!!!!
と思えるような内容を書き出しにぶつけましょう!!
文章の終わり
オチにこだわらずにまとめを書くと読後感が良いです。
文章の目的とは、読者にどんな読後感を持ってもらうかでなので文章の最後には結論やまとめを書けば良いです。
そうすれば、読者にこの文章が伝えたかったことが改めて伝わります。
4. 一気に書き切る
素材が集まったらさっさと書きましょう!!
速く書く最大のメリットは
- 確実に締め切りを守ることができる
- 追い詰められるとストレスがなくなる です。
最初から完璧を目指そうとするとスピードが落ちるので、推敲して整えることを前提に、まずは文章を書き終えましょう。
書きながら途中でなんども止まっていたら一気に読める文章になりません。
誤字も表現も書いている途中に悩まずに書きましょう。
読みやすい文章を書くポイント
一文を短く
→60字くらいスラスラ読めるリズムを作る
→ですます調の中にである超の文章を適度に織り交ぜる 似た意味のフレーズを少しバリエーションを変えて繰り返す「」の強調使用
だから、また、さらになどの順接の接続詞を使わない
→冗長な印象を与えてしまう逆説の接続詞で展開を生む
→逆説された部分が強調されリズムも生まれる難しい日本語を翻訳する
基本方針は多く書いてあとで削るなので、書いているときに全体の分量を気にしないようにしましょう。
あと、読者と目的を目に見える場所に置いておくことで途中見失わないようにできます。
5. 見直す
速く書くメリットは、文章を寝かせることができることです。
少し時間をおくことで書き手は客観的な視点を得ることができ、初めて読む人の視点で冷静に文章を修正することができます。
文章を推敲する目的は
- 読みやすくする
- わかりやすくする
です。
速く推敲を終えるために大きいところから取り掛かり、その後細かい箇所を見ましょう。
最初の遂行
- 論理が正しいか
- 説得力に欠けていないか
- 文脈に沿った素材か
- 一気に読めるか
- 重複している点はないか
初見の見直しが一番読者に近い視点です。何度も見直してしまうと、その視点が薄れてしまいます。
最初は修正を加えずにピックアップするだけです。
次にようやく細かくチェックしていきます。
- 意味不明な箇所はないか
- 説明不足な箇所はないか
- 読者、文章の登場人物に失礼な言い回しがないか
- 読者に嫌悪感を与えないか
素材が的確に伝わっているかどうか以外に読者に不快感を与えないかも重要です。
ボリューム調整は終盤にやります。
そして最後に誤字脱字を修正していきましょう。
わかりやすさを確認する方法
何も知らない人を前提にしているかどうか
→専門用語が出てくると読む気が失せる人がいるから、専門用語は必ず噛み砕く意味不明な形容詞を素材に置き換える
→形容詞だけを書いても何に感動したかが伝わらない、本来書くべきは何が面白かったか楽しかったかの理由。つまり素材 例)すごく寒い(どのくらい寒いの??)→マイナス5度(読者に想像できる寒さ)
まとめ
表現に凝ってしまから文章を書くのに時間がかかってしまう。
素材が準備できていれば速く書くことができる。
手順
- 書く真の目的と特定の読者を定める
- 体験したことをメモに取り素材を集める
- 読者に喋って伝えるつもりで素材を組み立てる
- 完璧を目指さず一気に書き切る
- 大きい箇所から細かい箇所に向かって見直す
最後に
実際にこのやり方でこのブログを書きました。
本に線を引きながら読んだ後、素材を書き出すからブログを公開するまでには3、4時間ほどかかりました。
以前同じように本の紹介を書いた記事は2倍かかっていました。内容が難しかったというのもありますが、、、
実際に試してみて良かったことは、
- 素材を最初に集めたことで、文章が組み立てやすかった。
- 文章を組み立てた後は一気に書き切れた。
ただ、うまくいかないこともありました。
- 組み立てる際に素材の繋がりがわからなくて素材集めに戻ってしまうことが何度かあった。
です。
今後も、このやり方をブログや文章を書く時には活用したいと思います! 皆さんもぜひ試してみてください!!
今回書けなかったこともあるので、ぜひ本も読んでみてください!!
エンジニアリング組織論への招待まとめ
はじめに
今回は、「エンジニアリング組織論への招待」という本のまとめを書いていこうと思います。
エンジニアは仕事を進めていく上でコードを書く以外に様々な問題に直面します。
- 上司、プロジェクトメンバーとのミスコミュニケーション
- 経営者とエンジニアとの認識の食い違い
- スケジュール通りに終わらない
これらの根源は「わからない」ことへの不安です。
この本はその不安、つまり不確実性とどう向き合っていくかについて書かれています。
今回は、1章の思考のリファクタリングについてまとめていきます!
この記事を読んでわかること
- エンジニアリングとはなにか
- 不確実性とはなにか
- 不確実性を下げるには
エンジニアリングとは
エンジニアリングとは、何か役に立つものを実現していくこと(曖昧さを減らし、具体性、明確さを増やすこと)です。
エンジニアリングする上で重要なのは、どうしたら効率よく不確実性を減らしていけるかです。
不確実性とは
不確実性とは、わからないことから生まれます。人間にとってわからないことは2つ
- 未来
- 他人
未来は、それがやってくるまでどうなるかわかりません。
頭でいくら考えていてもわからないものなので、実際に行動し、実験して観察することで少しずつ確実になっていきます。
他人も、わかりません。
私たちは1人1人別の自意識を持っていて全ての情報を一致させることは不可能です。 これもいくら考えていても決してわかるものではないので、コミュニケーションを通じて不確実性を削減するしかありません。
この2つの不確実性を減らしていくことが唯一物事を実現させる手段です。
しかし、私たちはわからないものに向き合うことを避けてしまうという習性があります。
それが不安です。
私たちは不安なものには、攻撃か逃避を選択してしまいます。なので人は自分がわかっているものを優先して実行してしまう癖があります。
不確実性が減っていかない限り不安は減りませんし、向き合おうとするとそれ自体が最大の不安を生み出してしまいます。
不確実性を下げるには
ではどうすれば良いのか。
不確実性を下げるには、情報を生み出すことが必要です。
いかにして、多くの情報を生み出すことができるのか、そのために何をすべきなのかというのがこの本の一貫したテーマであり、エンジニアリング活動の本質の1つです。
情報を生み出すには思考を前に進める必要があります。
ここでは3つの考え方を用いて思考を前に進めていきます。
- 論理的思考の盲点を知る
- 経験主義と仮説思考
- システム思考
それぞれみていきましょう。
論理的思考の盲点を知る
思考を前に進めるには論理的思考が不可欠です。
論理的思考で正しい結論を導くには、
- 事実を正しく認知できること。
- 正しく演繹できること。
が、必要です。
(演繹は「Aである」という前提から、「Bである」という結論を導くことです。
A:人間はいつか死ぬ。B:私はいつか死ぬ)
しかし、人は論理的な思考を常に正しく使えるわけではありません。
特に他人が関わってくる問題に対しては感情的になりやすいです。
私はあなたではないという単純なことが、忘れられてしまい、自分の事情は全て相手に伝わっているのだという勘違いも発生します。
どんなに自分が正論だと思っていることも、その人自身の世界の中で認識できる範囲の中での正論にすぎず正解ではないのです。
どんな時に自分は論理的で無くなるのかを知った上で問題解決に臨む、それが論理的思考を進める上で重要なことです。
自分は論理的に考えることができると思いこむことこそが非論理的な思考を生みます。
それを踏まえた上で自分がどのようなときに認知が歪むのかを知り、自分の歪んだ認知を正すための行動を促す考え方が論理的思考の盲点を知るということです。
- 自分がいつ非論理的になるかを知ること。
- 自分は間違っているかもしれないが、それに早く気付く方が良いと思考のパターンを変える必要がある。
経験主義と仮説思考
情報を生み出す際に有効なのがこの経験主義と仮説思考です。
経験主義
情報を入手するために行動を起こして、その結果を観察し、そこから問題解決を行う考え方を経験主義と言います。
私たちが、何か問題に出くわした時にできることとは、
- コントロールできるものを操作する
- 観測できるものの結果をみる
だけです。
コントロールできるものとは、例えば、自分の行動です。例えば毎週ブログを書くとかです。これは自分の行動次第でコントロールできます。
逆に、例えば、コントロールできないものはブログの読者を増やすことです。しかし、これは観測できることなので実際に自分がブログの書く内容を変えてみたことで結果読者が増えた減ったなどの結果を見ることができます。
経験主義は、やってみなければわからないだけの論理ではなく、上記の方法でしか前に進むことができないということを意味しています。
仮説思考
仮説思考とは、情報がわずかであってもそれを説明可能とする大胆な思考展開を行い、それを検証するための行動につなげる考え方です。
この考え方は、常に正しいわけではありませんが、今あるデータからは、演繹的に導くことのできない跳躍を生み出してくれます。
経験主義と仮説思考によって、どのような問題なのかをはっきりさせることで、同じところをぐるぐる回る不毛な思考を避けることができます。
(不毛な思考は、仕事で解決できない問題にハマってしまった時に、考えているようで考えていないような状態に近いですね笑)
- 今直ぐに解くことのできない問題であれば、それはおそらくどのような問題かはっきりしていない。
- 問題をはっきりさせる仮説を立てて、検証していくというプロセス思考に思考を切り替えることが大切。
システム思考
人は問題を個人の責任にしたり、全体像を見失った局所最適解な思考をしてしまいます。
それが全体像ではないかもれない、問題は関係性にあるのではないかという視点をもつことがこのシステム思考の考え方です。
私たちはつい自分から見える世界の中に閉じこもって、正しさや合理性を判断しています。
しかし、人間が認知している範囲というのは、全体のごく一部にすぎません。
問題は複雑に絡み合っている場合があります。
そのため、合理的に見える解決策が別の問題を引き起こしたり、想定していない悪化をもたらすことがあります。
このように全体像を把握できない状態で、問題解決を進めて行こうとすると思いもよらない結果を生むことがあります。
そうならないためには、
- 対立に見える問題を対立にならない全体像をあぶりだすこと。
- その解決を個人の問題にせず、関係性の問題に変換して本当の問題を発見すること。
が必要になってきます。
人間の不完全さを受け入れる
問題が難しく感じられているときには、まだ問題が十分に変換されていません。
この章のタイトルである思考のリファクタリングとはこの3つの考え方を用いて、複雑な問題を簡単に変換していき思考を前に進めていくということです。
自分の認知の歪みをパターンとして記憶することで過ちに気が付きやすくするという習慣を持つことができます。そうすれば少しずつ改善していきます。
コミュニケーションの不確実性
コミュニケーションの不確実性は3つの不確実性からきます。
- 人は、他人や事象を完全に理解できない。
- 相手に全てが正しく伝わるとは限らない。
- また、正しく伝わったからといって、他人が思ったように行動するとも限らない。
これらの不確実性によって、さらに以下の問題が引き起こされます。
- 自分は知っているけど他人は知らないといった情報の非対称性
→自分の抱えている状態を他人は把握しているはずだと勘違い、あるいは把握してほしいという願望に基づいて行動してしまいます。
- 人は限られた範囲でしか合理的な行動が取れない非合理性
→複数人の共同作業では、個々人が最適だと思う行動でも、全体として不合理な行動になってしまいます。
通常エンジニアリングは複数人で何かを実現しますが、上記のために、1人ではなかなか起こらないはずの不合理な行動が、組織では発生してしまいます。
このような情報の非対称性や非合理性を起こさないためには、
意思決定とそれに関わる情報が組織内に正しく整合性をもって伝達されるように継続して努力し、何かわからない決定があったとしても直接聞いてみようという関係性を作ること
が必要です。
まとめ
エンジニアリングは何かを実現していくことで、重要なのは不確実性を効率よく削減することです。
不確実性は、わからないことで
- 未来
- 他人
から生まれます。
これらを解消するには情報を生み出すことが必要です。
つまり思考を前に進めること。
それには3つの考え方があります。
- 論理的思考の盲点を知る
- 経験主義と仮説思考
- システム思考
これらの考え方を使い、自分自身の認知の歪みをパターンとして記憶することで、過ちに気が付きやすくなる習慣を持つようにします。
そうすれば、少しずつ改善でき思考が前に進むようになります。
そして、エンジニアリングは組織で複数人で行うので、 それらを行いながら同じ目的で働いているはずの人々との間にあるコミュニケーションの不確実性を減らしていく必要があります。
最後に
この本を読んで確かになぁと思うことがいくつもありました。
例えば、他人と少し言い争いになる時って、正論をぶつけているつもりですが、それって結局自分の中の正論だったり常識なんですよね。
相手もそういうものを持っていて、結局何も良くならずにお互いにストレスを溜めてしまうだけみたいな。
そういう時に、非論理的思考の盲点を思い出してこれはただ自分の正論に過ぎないんだとか、システム思考的にこのまま言い争って言い負かしても意味ないな、どうしたら本来の目的を達成できるかなと考えた方が有益です。
経験主義と仮説思考もエンジニアの仕事をする上で、大切です。
本文にも書きましたが、ずっと考えてわからないものはわかりません。
そこで、考え続ける(実際にはあんまり頭は動いていない)よりは、どんな情報があれば解決できるだろうかとか、誰に聞けばわかるだろうかとだけ考えて直ぐに行動し、その結果からまた思考をする方が問題解決にとって効率的だなと思いました。
webを支える技術 REST
去年読み始めたwebを支える技術でしたが、途中で放置していました。
今年は違うぞということで、ここ2週間くらいで改めて最初から最後まで読み通しましたので、そのアウトプットとして今回記事を書こうと思います!
今回はRESTについてです!!
この記事を読んでわかること
- RESTとはなんであるか。RESTを構成するアーキテクスチャスタイルについて。
REST
RESTは複数のアーキテクチャスタイルを組み合わせた複合アーキテクチャスタイル。
アーキテクチャスタイルと言う言葉がいまいちピンとかなかったけど、調べてたら設計思想
というのがなんとなくしっくりきました。
リソース
リソースについては過去の記事で書いてありますので、そちらを!
RESTを構成するアーキテクチャスタイル
クライアント/サーバ
クライアント側とサーバ側で分けることでつまり、ユーザーインターフェースと処理を分けることです。
これによりwebにpc以外でアクセスすることができます。また、複数のサーバを組み合わせることで可用性(システムが継続して稼働できる能力)を上げられます。
ステートレスサーバ
クライアントのアプリケーションの状態をサーバ側で管理しないことです。そうすることでサーバの実装を簡略化できます。ただcookieはステートフルなものです。 ↓過去に例を交えながら説明しています!
キャッシュ
一度取得したリソースをクライアント側で使い回すことです。
何度も通信をしないで済むが、古いキャッシュにより情報が間違っているかもしれないので注意です。
統一インターフェース
URIで指し示したリソースに対する操作を統一したインタフェースで行うことです。
分かりづらいので例を上げるとHTTPは8つのメソッドだけしかありません。少なすぎて使い勝手が悪いように思われるかもしれませんが、これにより対応しなくてはいけないものが少なくなり、結果としてシンプルにすることができます。
階層化システム
サーバとクライアントの間に負荷を分散してくれるロードバランサを置いたり、アクセスを制限してくれるプロキシを置いたりすることです。
これは統一インターフェース(インターフェースをHTTPで統一)のおかげです。
コードオンデマンド
プログラムをクライアントにダウンロードして実行することです。例えばJavaScriptなどがあげられます。
最後に
以上、今回はRESTについてまとめてみました! RESTってよく聞くけど、それってどういうものなの?っていうのが今まで曖昧でしたが、改めて理解することができました。
私は、業務で主にRuby、rails扱っています。railsは便利なので、webのことを理解していなくてもなんとなく書けてしまうのですが、このwebを支える技術を読んで、URIやHTTPを理解してから、このリソースを更新したいからここにリクエストをしないといけないんだなとか、ルーティングはこう書かないとなとかがわかるようになりました。
本を読むだとか、アウトプットをするということを続けるのは大変ですが、仕事に直結しますし自分をより良くすること、(つまり筋トレと同じ)なので今後も続けて行きたいと思います!!(^∀^)ᕗ
クールなURIとは
前回と引き続き
Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)
- 作者: 山本陽平
- 出版社/メーカー: 技術評論社
- 発売日: 2010/04/08
- メディア: 単行本(ソフトカバー)
- 購入: 143人 クリック: 4,320回
- この商品を含むブログ (183件) を見る
の本から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上のありとあらゆる情報」のことです。
なので、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)
- 作者: 山本陽平
- 出版社/メーカー: 技術評論社
- 発売日: 2010/04/08
- メディア: 単行本(ソフトカバー)
- 購入: 143人 クリック: 4,320回
- この商品を含むブログ (183件) を見る