(2) 単一責任のクラスを設計する

TRUE 変更が簡単なコードに伴う性質

  • Transparent(見通しが良い) 変更するコードにおいても、そのコードに依存する別の場所のコードにおいても、変更がもたらす影響が明白
  • Reasonable(合理的) どんな変更があってもかかるコストは変更がもたらす利益にふさわしい
  • Usable(利用性が高い) 新しい環境、予期していなかった環境でも再利用できる
  • Exemplary(模範的) コードに変更を加える人が上記の品質を自然と保つようなコードになっている

TRUEなコードを書くためには、それぞれのクラスが明確に定義された単一の責任を持つように徹底する必要がある

クラスが単一責任かどうか見極める方法

  • あたかもそれに知覚があるかのように問いただすこと。

    クラスのメソッドを質問に置き換えた時に意味をなす質問になっているか。 : Gearさん、あなたの比(ratio)を教えてくれませんか? → OK Gearさん、あなたのgear_inchesを教えてくれませんか? → NG gear_inchesは自転車の情報なので、gearに聞くのは筋違いではないか。 Gearさん、あなたのタイヤのサイズを教えてくれませんか? → NG タイヤのサイズは自転車の問題なのではないか。 Gearさん、あなたのタイヤ(tire)はなんですか?→ OK タイヤがgearの属性になっているから

  • 一文でクラスを説明してみること

    考えつく限り短い説明に「それと」が含まれていれば、おそらくクラスは二つ以上の責任を負っている。「または」が含まれていれば、二つ以上責任があるわけではなく、互いにあまり関連もしない責任を負っている。

  • 凝縮度

    クラス内の全てがそのクラスの中心的な目的に関連していれば、このクラスは凝縮度が高い、もしくは単一責任であると言われる。単一責任の原則(RDD)はRDD(Responsibility Driven Design)という概念に由来。「クラスはその目的を果たすための複数の責任を持つ」

設計を決定するときを見極める方法

今日何もしないことの将来的なコストはどれだけだろうと考える。 とても小さなアプリケーション、未来は不確か、初期段階での知識量はプロジェクト全体でいえばもっとも少ない。最も費用対効果の高い行動は「より多くの情報を持つこと」。

何もしないことによる将来的なコストがいまと変わらないときは、決定は延期する。決定は必要なときにのみその時点で持っている情報を使ってする。

現時点での要件と未来の可能性の相互間のトレードオフをよく理解し、コストが最小になるように決断を下す。

変更を歓迎するコードを書く

振る舞いはメソッド内に捉えられていて、メッセージを送ることによって実行できる。 →単一責任のクラスをつくれば、どんな些細な振る舞いもそれぞれがただ一つに存在 = DRY

オブジェクトは、振る舞いに加えデータを持ち、インスタンス変数に保持される。

インスタンス変数の隠蔽

データへのアクセスは、インスタンス変数を直接参照するのか・隠蔽するのかの二つのうちどちらかで行われるが、インスタンス変数は常にアクセサメソッドで包み、直接参照しないようにする。

  • Module#attr_reader

    Creates instance variables and corresponding methods that return the value of each instance variable. Equivalent to calling “attr:name” on each name in turn. String arguments are converted to symbols.

# attr_reader :hoge
def hoge
  @hoge
end

cogメソッドはコード内で唯一cogが何を意味するのかをわかっている箇所。 コグは、データ(どこからでも参照される)から振る舞い(一箇所で定義される)へと変わる。

デメリット

  • 可視性、publicなcogメソッドを定義すると、クラス外のアプリケーション内の他のオブジェクトにも公開される。またprivateなcogメソッドの場合は、その振る舞いをアプリケーション全体に公開せずに済む。
  • データも普通のオブジェクトも一見区別ができなくなる。

データ構造の隠蔽

インスタンス変数に結びついていることがよくないのであれば、複雑なデータ構造への依存はさらによくない。データ構造に関する複雑な情報は隔離されるべき。

  • obscuring_references.rb dataメソッドは単に配列を返すだけ。dataメッセージの送り手それぞれが何のデータが配列のどのインデックスにあるかを完全に知っていなければならない。 またdiametersメソッドが知っているのは、直径を計算する方法だけではなく、リムとタイヤのがどこにあるかも知っている。→配列の構造に依存しているため、配列にデータを持つとすぐにあちこちで配列の構造に参照するようになる

  • revealing_references.rb diametersメソッドは配列の内部構造について何も知らない。 渡されてくる配列の構造に関する知識はすべてwheelifyメソッド内に隔離。wheelifyメソッドは、arrayの配列をStructの配列に変換。

Struct
[明示的にクラスを書くことなく、いくつもの属性を1ヶ所に束ねるための便利な方法。](http://ruby-doc.org/core-2.4.1/Struct.html)

メソッドから余計な責任を抽出する

メソッドもクラスのように単一の責任を持つべき

def diameters
  wheels.collect {|wheel|
    wheel.rim + (wheel.tire * 2)
  }
end

wheelの繰り返し処理と、wheelの直径の計算、二つ責任を持っている。

def diameters
  wheels.collect {|wheel| diameter(wheel)}
end

def diameter(wheel)
  wheel.rim + (wheel.tire * 2)
end

それぞれの要素に対し実行される処理から、繰り返しを分離することはよくある

def gear_inches
  ratio * (rim + (tire * 2))
end

車輪の直径の計算とgear_inchesの計算の二つ責任を持っている。

def gear_inches
  ratio * diameter
end

def diameter
  rim + (tire * 2)
end

最終的な設計がわかっていない段階でもするべき

単一責任のメソッドがもたらす恩恵

  • 隠蔽されていた性質を明らかにする
    • クラスをリファクタリングし、全てのメソッドが単一の責任を持つようにするとクラスが明確になる
  • コメントをする必要がない
    • そのメソッド内のコードにコメントが必要なくらいなら、そのコードを別のメソッドに抽出する
  • 再利用を促進する
  • 他のクラスの移動が簡単

クラス内の余計な責任を隔離する

Gearクラスにはいくつか車輪(wheel)のような振る舞いがある ではこのアプリケーションにWheelクラスは必要なのだろうか?

いろいろな場合が選択肢にある。

でも目的は、設計に手を加える数を可能な限り最小にしつつ、Gearを単一責任に保つこと

変更可能なコードを書いているので、どうしてもしなければならないときまで決断を先延ばす。

WheelをGearに組み込むことは長期的な設計目標でないことは明らか Gearをきれいにしながらもwheelに関する決定は遅らせている。

その後、自転車の車輪の円周もほしいと言われる。=WheelクラスをGearから独立させて使いたいという明確なニーズ Wheelの振る舞いをGearクラス内に隔離しておいたおかげでこの変更は難しくない。Wheel Structを独立したWheelクラスに変えて円周を計算するcircumstancesメソッドを追加するだけ

まとめ

ひとつのことに専念するクラス(単一責任のクラス)はその一つのことをアプリケーションの他の部位から隔離することで、悪影響を及ぼすことのない変更と重複のない再利用が可能になる

単一責任のクラスにするためにはそれぞれのメソッドも単一責任である必要がある

単一責任のクラスかどうか見極める方法

  • [ ] あたかもそれに知覚があるかのように問いただすこと。
  • [ ] 一文でクラスを説明してみること

設計を決定するときは、現時点での要件と未来の可能性の相互間のトレードオフをよく理解し、コストが最小になるように決断を下す。

また変更を歓迎するコードを書くためには以下が必要

メソッドからも余計な責任を抽出する(それぞれの要素に対し実行される処理から、繰り返しを分離する)

クラス内の余計な責任を隔離する

決定は必要になったときにのみ、その時点で持っている情報を使ってする。

参考リンク

(1) オブジェクト指向設計 from オブジェクト指向設計実践ガイド

システムを、あらかじめ決められた手続きの集まりではなく、オブジェクト間で受け渡されるメッセージの連続としてモデル化

部品が相互に作用しあい、全体の振る舞いが生まれる 部品がオブジェクト、相互作用はオブジェクト間で受け渡されるメッセージ メッセージの送り手は受け手を知っている必要がある→依存関係を作る

オブジェクト指向設計とは、依存関係を管理すること

オブジェクト設計とは、変更が簡単になるようにどんなコード構成にするか

5つの原則 SOLID

  • Single responsibility 単一責任
  • Open-closed オープン・クローズド
  • Liskow Substitution リスコフの置き換え
  • Interface Segregation インターフェース分離
  • Dependency Inversion 依存性逆転

DRY

Don’t Repeat Yourself

LoD

Law of Demeter デメテルの法則

BUFD(Big Up Front Design)

提案されたアプリケーションのすべての機能の、想定される未来の内部動作をすべて特定し、完全に文書化すること

参考リンク

学校の課題でhtml/css/js縛りでなんか作るっていうのがあったので、shell scriptを書いてみた

要件

  • 紙芝居、ページは画像と文字列、ボタン(次のページへ)で構成されており、たまにある入力の値の条件分岐によってページの遷移先を変える
  • その入力値はページ間で保持する必要がある(縛りがあるのでDBとかは使えない。JSだけというか)

実装したこと

  • ほとんどのHTMLが同じ構成なので、コマンドで引数でもたせて40枚近い HTMLを作るshell scriptを書いた。(なお一発コマンドでできるわけではなくて、内容に合わせて枚数文コマンドを打つ必要がある)

https://github.com/tenshotanaka/Shakure-Cinderella/blob/master/html-build.sh

  • userの選択をcookieに保存し、その値によってページの遷移先を変えるようにした。なおライブラリは以下を使った。

https://github.com/js-cookie/js-cookie/releases/tag/v2.1.4

所感、感想

急いで書いたので、動くだけのクソコードになってしまった。jsとか絶対抽象化できるし、es6じゃないし。エンジニアとしてこのままにしてしまうのは恥ずかしいので一応issueにまとめた。でもこの機会でshell scriptに触れることができたのでよかった。やっぱりコード書くの楽しい。linux実践みたいな本読む時、復習したい。

参考リンク

www.shellscript.sh GitHub - tenshotanaka/Shakure-Cinderella: 情報基礎最終課題

先輩のtweetを見て危機感を感じてrmのaliasを設定した

qiita.com

qiita.com

最近twitterの有用性に気づいた。

あと学習について、思ったことがあって、エンジニアって一生勉強だから、ある課題にあたった時にそれを今そのタイミングで掘るか、ペンディングして休日にやるか、一週間後くらいにやるかいろいろ考えなきゃならない。だから学習もただ掘ればいいというわけではなくて、優先順位が大事だと感じた。

指示の本質を理解する

少し短い記事になってしまうのですが、あるタスクで指示を受けたときにその本質を理解する必要があると感じたこと。ゴールを明確にするとかと共通している部分があるとは思うけど。

たとえばstaging環境にnofollowが付いていないため、SEOランキングが下がる問題を解決するみたいなタスク内容だったとして、重要なのはSEOランキングが下がる問題を解決するであって、nofollowをつけることではない。そこらへんをちゃんとわからないと、ただ具体的に指示された内容をこなすだけになってしまう。だから深く本質を理解することが重要だと感じた。

エンジニアの勉強について

まず勉強には二種類あると思っている。それでこれら二つってお互いにすごく関連している気がする。たとえばあの基礎が抑えられてないから、これが理解できなくて、調べ方の指針もたたないみたいなことがたまにある。

  1. 仕事に必要な知識を得るための勉強、勉強というより調べ物に近いのかな 例)terraformでこういうリソースを追加したいのだがそのコードはどう書けば良いか
  2. 長期で見たときに必要になってくる知識を得るための勉強、技術書中心、公式のリファレンスとか 例)オブジェクト指向設計実践ガイドを読む (3. それらの仕事の仕方、仕事の効率化、)

1は仕事の仕方、問題解決に通じていると思うのだが、そもそもゴールがあって、それを解決するために調べる感じ。 - やりたいことがそもそも公式で推奨されていることとして存在するかどうか公式ドキュメントを見て探す in English あったらそれ読んでやってみる。わからなかったら日本語で読んでみる

  • その上でわからないことがあったら、仕事に必要になると考えられる条件を決めて 調べる

2は何かそれを使ってやりたいときにすぐわからないことにアプローチするためにインデックスを貼るためにやる感じ。一時期は本の内容の70%をメモしていた感じだったけど、今はどこに何が書いてあるのか、またその書いてあることを理解するために最低限必要な知識を書くようにしている。

でも問題なのが自分の投下時間におけるこれらの比率で、2をやりすぎたら普段の仕事終わらないし、1だけだと長期で考えたときにあの基礎が抑えられてないから、これが理解できなくて、調べ方の指針もたたないみたいなこともたまにある。

だから自分の中で長期の勉強と目の前のことのための勉強で時間を分ける必要がある。あと仕事の時間って、基本的に調べる(勉強する)時間+作業時間(実際に動かしたり、レビューもらう時間)に分かれると思っててその比率はそのタスクの達成難易度(作業量×自分の能力)による。自分の能力がそのタスクに関して低いと調べる時間が多くなるし、やり方わかってて動かすだけならほぼ作業だけで済む。

あと何かをやるときはかならず二日以上かけるように予定を立てる、つまりこの日に全部やろうと思って10時間まとまった時間をつくるより、5時間×2とかでやったほうがいい。そうすると多少伸びても時間の融通がきく。

自分の時間分け

  • そうすると朝起きての2時間は長期の勉強にあてる→絶対この時間は長期の勉強をする。この時間に勉強しないと長期の勉強はできないと思え!!またその日のタスクの調べ物は絶対にしない。キリがなくなるから。
  • 仕事の際の調べ物はゴールを決めて調べて、最初から記事を書くつもりで読む。今までは一度読む→もう一度流し読みしながらまとめるみたいな感じだったので、最初から記事を書きながらみたいな感じでもいいから調べる。記事を書くこともそのタスクの一環として、調べたらすぐ記事を書く
  • あと早く自分の遊び場をつくる。

SEOまとめ

SEO検索エンジン

Webマーケティング

SEOとは、検索エンジンを利用するユーザーが入力するキーワードを導線としたキーワードマーケティング

  • キーワードとカテゴリーの設計 web担当者、マーチャンダイザー、インフォメーションアーキテクト
  • 内的施策 サイトのドメイン名やURL構成、HTML/CSSなどサイトの内側に施す対策 ←ここ
  • 外的施策 PageRank(価値やキーワードの関連性が高いページやドメイン、サイトからどのくらいのリンクを受け取っているか、被リンクがあるか)を上げるための対策 ex メディアサイトに取り上げてもらう、ブロガーにリンクを貼ってもらう。

検索エンジンの技術的な仕組み

  • 検索エンジンの種類
    • ディレクトリ型 人間が作ったリンク集。整理、審査されているため探しやすいが、ほとんどがサイト単位
    • ロボット型 ソフトウェアによる自動収集型。ページ単位にインデックスしているため、情報が膨大 クローラーがHTTPプロトコルでコンテンツを取得 →インデクサーが取得したコンテンツを解析し、分析結果とそのファイル自体をデータベースに保存。その際キーワードごとの検索結果も作成。 →クエリサーバーがユーザーからの検索クエリー(キーワード)の結果ページを返す

PageRank

「多くの良質なページからリンクされているページはやはり良質なページである」という再帰的な関係を元に全てのページの重要度を判定したもので、ランクされていないのPageRank 0 ~ 10までの全部で11段階の評価になっている。

  • 被リンク数(リンクされているリンクの数)
  • 評価の高いページからのリンクかどうか
  • リンク元ページでの放出リンク数(貼ってあるリンクの数)

検索エンジンのシェア googleとyahooが主 https://seopack.jp/seoblog/20160816-s-e-share/

SEOサイクルとクローラビリティー(webサイトをいかに巡回しやすいか)

SEOサイクル

  • 診断 アクセス解析・仮説
  • 設計 コンテンツ・SEO・カテゴリー・キーワード設計
  • 実行 HTML/CSS作成、開発、リリース
  • 外的施策 インバウンドリンク対策、メディア対策、プレスリリース

SEO対策の三つのポイント

  • クローラビリティ(クローラーのサイト回避のしやすさ)

    • ステータスコードを返す
    • URL永続化(一度公開して検索エンジンにインデックスされたコンテンツに対し、そのコンテンツが存在し続ける限り同一のURLを使用し続けること)
    • URL正規化(そのキーワードを表すURLはそのサイト内で一つのみ存在する、そのコンテンツはそのサイト内で一つのみの存在する)
    • URL静的化(http://hoge.com/dir/file.html?query=fuga < http://hoge.com/dir/file/query/fuga
    • クロールできるa要素とリンク構造
      • リンクを貼る際は内容的に関連するページに貼るリンクが効果的
      • 1ページから放出する(に貼られている)リンク数は最大でも100本を目安に設計
  • キーワード・キーフレーズ

  • アンサー度(ユーザのニーズを満たせているかどうか)

キーワード

  • キーワードとは
    • 言葉の一致
    • キーワードの守備範囲
    • キーワードの人気度の調査
    • キーワーードのグループ構成
  • キーワードの選定
    • 潜在顧客の検索行動の洗い出し
    • 人気度・コンバージョン・競合度の調査
    • キーワードのグループ分けと優先順位づけ
  • 形態素分析
  • カテゴリー
    • 複数のカテゴリー軸の組み合わせ

アンサー度

  • アンサー度とは
  • テーマの一致
  • 多様性
  • 検索語タイプ

HTMLの最適化(これからはじめるSEOの教科書)←ここ

1, title

2, meta description

3, mata keywords

4, h1

5, h2~h6

6, ul, ol

7, strong

8, center

9, imag

10, リンクの最適な使い方(どういうリンクを貼るべきか)

11, ドキュメント宣言

12, headタグ内で必要なものと不必要なものの仕分け

13, 重要キーワードが重要位置にあるか

14, ページ内が適正な文字数・文字比率になるようチェックしよう

15, HTML内の贅肉を落としスリム体質にしよう

16, 重要ではないタグやキーワードを下方に移動させよう

17, パンくずリストを作成しよう

18, サイトマップを作ろう

19, 内部リンクを張り巡らそう

20, ファイルサイズを縮小化しよう

21, 美しいソースコードに修正

22, URL正規化でバックリンク分散を回避しよう(複数存在のURLを一つに統一)

23, 足を引っ張り合うミラーサイトをなくそう

24, SEO対策が行われているかをチェック(http://ferret-plus.com

25, 上位表示に必要なURLの付け方

26, NGタグの撤廃・改善

27, スパムについて

アクセスログとインデックス状況の分析

アクセスログ

アクセス解析に使う狭義のアクセスログ=webサーバーの生ログ(webサーバーが生成するテキストファイル)

リファラー =あるwebページのリンクをクリックして別のページに移動した時のリンク元のページ。

  • Apache(Linux, UNIX系) Combined, Common ※リファラー情報がない、でも容量が多いから保管場所には注意
  • IIS(Windows系) W3C Extended(W3C拡張) 自由にフォーマットを変更できるヘッダー領域。

リファラーから検索キーワードがわかる。

インデックス数

クロールされているからといって、インデックスされているとは限らない。したがって定期的にインデックス数を確認する必要がある。

分析手法

  • コンバージョン分析
  • 被リンク数
  • PageRank
  • 検索順位
  • 視聴率

アクセス解析の導入

https://analytics.google.com/analytics/web/#report/defaultid/a49424310w110721923p115496641/

ビーコン型アクセス解析

ASP(Application Service Provider)側のサーバーに置かれているJSのタグを全ページに貼り付ける。ページがロードされるとJSのプログラムがCookieの有無を調べCookieが未発行だったり有効期限が過ぎていたりした場合は新規にCookieを発行したりすることで、情報を自動的にASP側に集約していく。JSを実行できないページ(リダイレクトページ、ファイルのダウンロード、ロボットのアクセス)は解析対象にできない。

このCookieには以下を使うASPがある

バケットキャプチャー型

データセンターにネットワーク上を流れるパケットを受信できる機材を用意して、パケットの中身を取り出して集計する。どんなトラフィックでも解析が可能。リダイレクトやファイルのダウンロードのようなものも対象にできる

生ログ型

生ログを解析する。JS, Cookie, ネットワーク機器に依存していないため、ほぼどんなシステムを利用していても分析が可能。携帯電話からのアクセスが携帯キャリアの設置するゲートウェイサーバーになっているため、ログにそのサーバのIPアドレスが記録されるため、複数の携帯電話からのアクセスが一つのセッションにまとまってしまう。

検索エンジンスパム

  • スパムとは、検索エンジンアルゴリズムを利用して、意図的に検索順位を上げようとする検索エンジンにとっての迷惑行為。あらかじめ自分のサイトにしかけをしておき、クローラーやインデクサーを騙してサイトの評価をあげ、自然検索結果の露出を高める行為。

ペナルティ

  • 一時的もしくは恒久的に意図的に検索順位を下げられる
  • 一番のキーワードで検索結果に出なくなる
  • そのドメインごと、検索結果に表示されなくなる

ソフトウェアでのチェック→目視でのチェック

スパム手法

  • HTML系

  • サーバ系

    • ドアウェイページ、リダイレクト
    • クローキング
    • 複製コンテンツ

DNSスパムはDNSワイルドカードを利用してサブドメインを大量作成し、検索エンジンに登録する行為

  • 外部リンク系
    • リンクファーム、有料リンク

検索エンジンの制御

robots.txt

クローラーにインデックスやクローリングの制御情報を渡すにはrobots.txtというファイルをやりとりする必要がある。 http://www.robotstxt.org/robotstxt.html https://support.google.com/webmasters/answer/6062608?hl=en https://moz.com/learn/seo/robotstxt

サイトのルートディレクトリに設置しておくことで、クローラーがHTTPプロトコルをGETして内容を読み取り、その内容にそったクローリングをしてくれる。

http://www.google.co.jp/robots.txt

  • どのロボットに対する指示か
  • アクセス拒否するディレクトリやファイルの列挙

  • noindex 検索結果に表示されない、表示する、pagerankはつく、キャッシュもされる。

  • nofollow このページから、クロールさせる、させないの指示をする

Sitemaps

https://www.sitemaps.org/index.html

googleが策定した規約で、URLの一覧をxmlファイルやテキストファイルで通知する方式 インデックスの促進が目的なので、検索順位に影響が出るわけではない。

縮退運転

クローラーが来ているタイミングでサイトを停止させないため

データベースモデリング

レスポンスが遅いのは検索エンジン側からするとよくない

  • 並び順 重要なものを上に表示する必要があるので、それを考える必要がある。 例 その季節のものを上に表示するようにする

  • エイリアス キーワードの別名を格納する

  • 事前計算 複雑なクロスカテゴリーなどの場合に、件数を計算しておき、0件の場合は表示しないようにするみたいな

  • マルチアサインとマスターカテゴリー 一つのカテゴリーが二つの親カテゴリーに紐づくことがある。構造上二つの上位カテゴリーに属していることにする必要があり、そうするとURLの正規性を保つことができる。

  • キーワードカテゴリー、ショートカットカテゴリー キーワードでの関連性で関連のあるリンクを作るようにする

  • ID体系とURLの関係 リレーション変更によってURLが変更されないようにDB設計する必要がある

ツール

サイト管理ツール  GoogleWebMasterTool

ソースコードエラーチェック http://validator.w3.org/

サイト診断 http://www.seotools.jp/ https://ferret-plus.com/ http://seocheki.net/ https://moz.com/researchtools/ose/

サイトマップ作成 https://www.xml-sitemaps.com/

SEOに関する情報収集 https://www.webmasterworld.com/

参考文献

https://d2eeipcrcdle6.cloudfront.net/seo-cheat-sheet.pdf support.google.com support.google.com

これからはじめる SEO内部対策の教科書

これからはじめる SEO内部対策の教科書

SEOを強化する技術 エンジニアが内側から支えるサイト設計・構築術

SEOを強化する技術 エンジニアが内側から支えるサイト設計・構築術