銀行員からのRailsエンジニア

銀行員からのRailsエンジニア

銀行員から転身したサービス作りが大好きなRailsエンジニアのブログです。個人で開発したサービスをいくつか運営しており、今も新しいサービスを開発しています。転職して日々感じていること、個人開発サービス運営のことなどを等身大で書いていきます。

当ブログではアフィリエイト広告を利用しています

【Rubyによるデザインパターンまとめ3】オブザーバーパターン

コードの品質向上のため、Rubyデザインパターンを解説した名著である Rubyによるデザインパターン で紹介されているデザインパターンを1つずつまとめており、今回が第3弾です。(毎週1つが目標です!)

前回の記事(ストラテジーパターンのまとめ)はこちらです。
ysk-pro.hatenablog.com

この本で紹介されているサンプルコードをそのまま使うのは面白くないので、オリジナルのコードで説明しています。

今回はObserverパターンについてまとめました。
f:id:ysk_pro:20191110123459p:plain

Observerパターンとは

あるオブジェクトの状態が変化した時に、そのオブジェクトが変化したことを知る必要があるオブジェクトに通知をすデザインパターンです。

Rubyによるデザインパターン では次のように説明されていました。

GoFは「何らかのオブジェクトが変化した」というニュースの発信者と消費者の間に綺麗なインターフェイスを作るアイデアを、Observerパターンと呼んでいます。

GoFとは、ギャング オブ フォーの略でデザインパターンを広めた「オブジェクト指向における再利用のためのデザインパターン」の4人の著者のことです)

自らが変化したことを通知するオブジェクトのことを「Subject」(話題になっている事柄)と呼び、Subjectの通知を受け取るオブジェクトのことを「Observer」(観察者)と呼ぶことから、Observerパターンと名付けられました。

言葉での説明よりも実際のコードを見た方が分かりやすいと思うので、以下のサンプルコードをご覧ください。

サンプルコード

商品価格が変更された時に、様々な処理を行う必要があるプログラムを考えてみます。(ECサイトなどで実際によくあるケースだと思います)

まずは、商品価格が変わった時に、ユーザへの通知のみを行うプログラムを、Observerパターンを使わずに実装してみます。

class Item
  attr_reader :name, :price, :notification

  def initialize(name, price, notification)
    @name = name
    @price = price
    @notification = notification
  end

  def price=(new_price)
    @price = new_price
    notification.update(self) # 通知の処理は、Notificationクラスに委譲している
  end
end

class Notification
  def update(changed_item)
    puts "#{changed_item.name}の値段が#{changed_item.price}円になったよ!"
  end
end

商品価格が変わった時に呼ばれる price= メソッドの中で、Notificationクラスのupdateメソッドに通知処理を委譲しています。

次のように実行します。
Itemクラスのインスタンスを作る際に、Notificationクラスのインスタンスを渡す必要があります。

item = Item.new('ダンベル', 3000, Notification.new)
item.price = 2500

実行結果は、次のようになります。

ダンベルの値段が2500円になったよ!

ここで、価格変更をした時に、ユーザへの通知のみではなく、配送方法を変える処理も必要になった場合を考えてみましょう。

先ほどのコードに追加で、Itemクラスのインスタンス作成時に配送方法を変える処理を行うクラスのインスタンスを渡し、price= メソッド内で新しく作ったクラスに配送方法変更の処理を委譲することで実現できると思います。

しかしこのやり方だと、ItemクラスはNotificationクラスや新しく追加したクラスのことを知る必要があり(それぞれのクラスのどのメソッドを呼び出す必要があるかなど)、価格変更した後に行う処理を追加する度に、Itemクラスを修正する必要が出てきてしまいます。

商品の価格変更をした後に行うというだけで、直接商品とは関係ない処理を追加するにも関わらず Itemクラスの修正が必要になってしまうのは保守性の観点で良くないと言えるでしょう。(商品の価格変更した後の処理を追加する際に、Itemクラスを壊してしまうおそれがあります)

このコードを、Observerパターンを使って書き換えてみます。

class Item
  attr_reader :name, :price, :observers

  def initialize(name, price)
    @name = name
    @price = price
    @observers = []
  end

  def price=(new_price)
    @price = new_price
    notify_observers
  end

  def notify_observers
    observers.each do |observer|
      observer.update(self) # Observerそれぞれに処理を委譲している
    end
  end

  def add_observer(observer)
    observers << observer
  end
end

class Notification
  def update(changed_item)
    puts "#{changed_item.name}の値段が#{changed_item.price}円になったよ!"
  end
end

class DeliveryMethod
  def update(changed_item)
    puts "#{changed_item.name}の値段によって配送方法を分ける処理を書くよ"
  end
end

Itemクラスが自らに変化があったことを通知するSubjectクラスで、Notificationクラス・DeliveryMethodクラスが通知を受け取るObserverクラスになっています。

Itemクラスに @observers というインスタンス変数を作り、その中に価格変更後に通知を受け取るObserverクラスのインスタンスを格納することで、Itemクラスは @observers に価格変更があったことを通知することだけを知っていればよく、Notification, DeliveryMethod クラスについて知る必要がなくなりました。

次のように実行します。
add_observer メソッドで、observer を追加しています。

item = Item.new('ダンベル', 3000)
item.add_observer(Notification.new)
item.add_observer(DeliveryMethod.new)
item.price = 2500

実行結果は、次のようになります。

ダンベルの値段が2500円になったよ!
ダンベルの値段によって配送方法を分ける処理を書くよ

価格変更時に新たな処理を加えたい場合は、observerを追加するだけでよく、Itemクラスを修正する必要がなくなりました。

また、Rubyの標準ライブラリには、Observerパターンを実装するためのObservableモジュールがあり、このモジュールをSubjectクラスにincludeすることで、Observerパターンをシンプルに実装することができます。

先ほどのコードを、Observableモジュールを使って書き換えると次のようになります。

require 'observer'

class Item
  include Observable

  attr_reader :name, :price, :observers

  def initialize(name, price)
    @name = name
    @price = price
  end

  def price=(new_price)
    @price = new_price
    changed # changedメソッドを呼ぶことで、オブジェクトに変更があることを伝えている
    notify_observers(self)
  end
end

class Notification
  def update(changed_item)
    puts "#{changed_item.name}の値段が#{changed_item.price}になったよ!"
  end
end

class DeliveryMethod
  def update(changed_item)
    puts "#{changed_item.name}の値段によって配送方法を分ける処理を書くよ"
  end
end

先ほどと同じ呼び出し方で、同じ実行結果になります。

おわりに

ここまで読んでいただきありがとうございます。

前回書いたStrategyパターンの記事を読んでいただいた方は気づいたかもしれませんが、ObserverパターンはStrategyパターンと少し似ている気がするなぁと思っていたら、Rubyにおけるデザインパターンに次の記載がありました。

ObserverパターンとStrategyパターンは少し似ています。どちらも、あるオブジェクトが、他のオブジェクトを呼び出すという特徴があります。ほとんどの場合、違いは目的という一点だけです。Observerパターンの場合、発信側のオブジェクトで発生しているイベントを他のオブジェクトに伝えています。Strategyパターンの場合、何かの処理を行うためにオブジェクトを取得します。

TemplateメソッドパターンとStrategyパターンも同じ目的のために、違う手段で実装していましたが、デザインパターン同士で似ているところなどの関連があって面白いですね。
違いを認識しておくことで、それぞれのデザインパターンへの理解がより深まりそうです。

Rubyによるデザインパターン の中では、従業員の給与が変わった時に、経理部門や税務署員に通知するというサンプルコードを用いて説明がされていて非常に分かりやすかったので、ご興味ある方は是非合わせてご覧ください。

Rubyによるデザインパターン

Rubyによるデザインパターン

次回は、Compositeパターンをまとめます。どんなパターンか楽しみです。

来週も頑張ります!

(追記)
Compositeパターンについてまとめました!
是非合わせてご覧ください。
ysk-pro.hatenablog.com

【Rubyによるデザインパターンまとめ2】ストラテジーパターン

コードの品質向上のため、Rubyデザインパターンを解説した名著である Rubyによるデザインパターン で紹介されているデザインパターンを1つずつまとめています。(毎週1つが目標です!)

前回の記事(テンプレートメソッドパターンのまとめ)はこちらです。
ysk-pro.hatenablog.com

この本で紹介されているサンプルコードをそのまま使うのは面白くないので、オリジナルのコードで説明しています。

今回はStrategyパターンについてまとめました。
f:id:ysk_pro:20191103103437p:plain

Strategyパターンとは

アルゴリズムの変化する部分をクラスに閉じ込めて、アルゴリズムを実行する際はそのクラスに処理を委譲するパターンです。

アルゴリズムに多様性を持たせたい場合に利用するのはTemplateメソッドパターンと同じですが、Strategyパターンは継承を使わずに実現することができます。(Templateメソッドパターンは継承を使っており、継承にはサブクラスがスーパークラスに依存してしまうというデメリットがあります)

Strategyパターンの「Strategy(戦略)」は、アルゴリズムのことです。Strategyパターンという名前は、変化するアルゴリズム(=Strategy)を、クラスに閉じ込めてそのアルゴリズムを使うオブジェクトに引き渡すことから付けられました。

文章の説明よりも実際のコードを見た方が分かりやすいと思うので、以下のサンプルコードをご覧ください。

サンプルコード

今回はスポーツネタでいってみます。

様々なスポーツの練習内容を出力するプログラムを考えてみます。(プログラム中にあるようにゴルフとバドミントンが好きでよくやっています)

Strategyパターンを用いて書いた例がこちらです。

class Sport
  attr_accessor :sport, :before_practice

  def initialize(sport)
    @sport = sport # Golfクラス・Badmintonクラスのインスタンスが入る
    @before_practice = 'ストレッチをする'
  end

  def practice
    sport.practice(self) # 詳細を知っている別のクラス(Golf,Badminton)のメソッドに処理を委譲している
  end
end

class Golf
  def practice(sport)
    puts sport.before_practice
    puts 'アイアンの練習'
    puts 'ドライバーの練習'
  end
end

class Badminton
  def practice(sport)
    puts sport.before_practice
    puts 'スマッシュの練習'
    puts 'ヘアピンの練習'
  end
end

Golfクラス・Badmintonクラスに、アルゴリズムの変化する部分を閉じ込めて、Sportクラスのpracticeメソッドの実行は、Golfクラス・Badmintonクラスに委譲しています。

こうすることによって、各スポーツの練習方法についての知識を、Sportクラスから分離することができます。

また、Sportクラスの情報(今回は スポーツ前にはストレッチをする という情報)をGolfクラス・Badmintonクラスに渡すために、practiceメソッドにSportクラス自身のインスタンスを引数として渡しています(before_practiceを引数として渡しても問題ありません)。

以下のように実行できます。
Sportクラスのインスタンス作成時の引数に、Golfクラス・Badmintonクラスのインスタンスを渡しています。

Sport.new(Golf.new).practice

Sport.new(Badminton.new).practice

実行結果は、それぞれこのようになります。

ストレッチをする
アイアンの練習
ドライバーの練習

ストレッチをする
スマッシュの練習
ヘアピンの練習


また、Procオブジェクトを利用すると、同じ内容を次のように書くこともできます。

class Sport
  attr_accessor :sport, :before_practice

  def initialize(&sport) # 引数としてブロックを受け取るので、&(アンパサンド)をつけている
    @sport = sport
    @before_practice = 'ストレッチをする'
  end

  def practice
    sport.call(self) # Procオブジェクトはcallメソッドで実行する
  end
end

こうすることで、アルゴリズムの変化する部分を閉じ込めるクラスを作る必要がなくなり(ブロックを疑似的なクラスとして扱っています)、よりシンプルにストラテジーパターンを利用することができるようになります。

次のように実行すると、先ほどと同じ実行結果となります。

Sport.new do |sport|
  puts sport.before_practice
  puts 'アイアンの練習'
  puts 'ドライバーの練習'
end.practice

Sport.new do |sport|
  puts sport.before_practice
  puts 'スマッシュの練習'
  puts 'ヘアピンの練習の練習'
end.practice

アルゴリズムの変化する部分が小さい場合は、Procクラスを使った方法の方がシンプルにStrategyパターンを実現できます。

おわりに

ここまで読んでいただきありがとうございます。

GoF(ギャング オブ フォーの略でデザインパターンを広めた「オブジェクト指向における再利用のためのデザインパターン」の4人の著者のこと)によれば、「継承よりも委譲の方がより柔軟で好ましい」とあるので、Templateメソッドを検討する際には、合わせてStrategyパターンも検討してみるのが良さそうです。

Rubyによるデザインパターン の中では、レポートをHTML形式やプレーンテキスト形式で出力するという実際にありそうなサンプルコードを用いて説明されていて非常に分かりやすかったので、ご興味ある方は是非合わせてご覧ください。

Rubyによるデザインパターン

Rubyによるデザインパターン

やっぱりブログを書くと、理解が深まっていいですね。先日僕が実務で書いたコードを、早速 Templateパターン or Strategyパターンを使ってリファクタリングしたくなりました。

次回は、オブザーバーパターンをまとめます。どんなパターンか楽しみです。

来週も頑張ります!

(追記)
オブザーバーパターンについてまとめました!
Strategyパターンと似たところもあり、合わせて読むことでそれぞれの理解が深まると思います。
是非合わせてご覧ください。
ysk-pro.hatenablog.com

【Rubyによるデザインパターンまとめ1】テンプレートメソッド / Template Method

「コードの品質向上」が現在の僕の課題で、マネージャーからデザインパターンを勉強してみては」とアドバイスをいただいたので、デザインパターンの勉強を始めることにしました。

具体的には、Rubyデザインパターンを解説した名著である Rubyによるデザインパターン で紹介されているデザインパターンを1つずつまとめていきます。(目標は毎週1つ)

この本で紹介されているサンプルコードをそのまま使うのは面白くないので、オリジナルのコードで説明していこうと思います。
f:id:ysk_pro:20191027110444p:plain

そもそもデザインパターンとは

 一言で言うと、ソフトウェア設計の一般的な問題とその解決策をまとめたものです。

1995年に出版された「オブジェクト指向における再利用のためのデザインパターン」(4人の著者のことをギャング オブ フォーと呼び、GoF本と呼ばれています)によって、デザインパターンが広まりました。

GoF本では23のパターンに名前を付け、解説がされました。

デザインパターンを理解することで、設計についての車輪の再発明を防ぐとともに、エンジニア同士の共通言語となり、設計についてのディスカッションがスムーズに進めることができるようにもなります。

[デザインパターン①] Template Method パターンとは

基底クラスに骨格となる抽象的な処理を書き、サブクラスに具体的な処理を定義するパターンです。

アルゴリズムに多様性を持たせたい場合に便利なパターンで、不変となる部分は基底クラスに書き、変わる部分はサブクラスのメソッドに定義します。

Javaなどでサポートされている抽象メソッドや抽象クラスはRubyではサポートされていないので、呼び出した時に例外を投げるようにして擬似的に抽象メソッドを実装します。

文章で説明するよりも実際のコードで見た方が分かりやすいと思うので、以下のサンプルコードをご覧ください。

サンプルコード

僕は筋トレが好きなので、筋トレネタで書いてみます。

普通筋トレは、1日に全ての部位のトレーニングを行わず「胸の日」「肩の日」のようにその日鍛える部位を決めて、部位毎に集中してトレーニングを行います。

そこで、それぞれの部位の日に行うトレーニングを出力するプログラムを考えてみます。(便利)

まずは、Template Method パターンを使わずに書いてみます。

class MuscleTraning
  def execute(body_parts)
    case body_parts
    when 'chest'
      puts 'ベンチプレス!'
      puts 'チェストプレス!'
    when 'shoulder'
      puts 'ショルダープレス!'
      puts 'サイドレイズ!'
    else
      raise "#{body_parts}という部位のトレーニングはまだ知らないよ"
    end
    puts 'プロテイン摂取'
  end
end

このように実行できます。

MuscleTraning.new.execute('chest')

MuscleTraning.new.execute('shoulder')

実行結果は、それぞれこのようになります。

ベンチプレス!
チェストプレス!
プロテイン摂取

ショルダープレス!
サイドレイズ!
プロテイン摂取

やっていることがシンプルなので、このコードで分かりやすいのでは?と思ってしまうのですが、ここからさらに「腕の日」や「脚の日」が追加される場合や、腕の日にはプロテイン摂取を行わないという条件が追加された場合を考えてみましょう。

case 文の条件分岐が長くなり、可読性が下がり、修正時に既存のコードが壊れてしまうおそれなどが出てきてしまいます。

次に Template Method パターンを使って書き換えてみるとこのようにできます。

class MuscleTraning
  def execute
    main_training
    drink_protein
  end

  def main_training
    raise '抽象メソッド(main_training)が呼び出されてるよ'
  end

  def drink_protein
    puts 'プロテイン摂取' # デフォルトではプロテインを摂取するので、基底クラスに書いています
  end
end

class ChestTraining < MuscleTraning
  def main_training
    puts 'ベンチプレス!'
    puts 'チェストプレス!'
  end
end

class ShoulderTraining < MuscleTraning
  def main_training
    puts 'ショルダープレス!'
    puts 'サイドレイズ!'
  end
end

このように実行すると、先ほどと同じ実行結果となります。

ChestTraining.new.execute

ShoulderTraining.new.execute

先ほどと同様に、新しい部位が追加された場合や、特定の場合にプロテイン摂取をしないという変更が入った場合を考えてみましょう。

新たにサブクラスを作ったり、サブクラスで drink_protein メソッドを継承することで、既存の実装に影響を与えることなくシンプルに変更に対応できることが分かると思います。

さらに、1つ1つのメソッドが簡潔で可読性も高いと思います。

これが Template Method パターンです。

モジュールの extend を使ったパターン(2020/5追記)

上記の例では、継承を使って Template Method パターンを実現していましたが、モジュールの extend を使っても同じことが実現できると知ったので紹介します。

先ほどと同じ内容を、モジュールの extend を使って書き換えたコードはこちらです。

class MuscleTraning
  def execute
    stretch
    main_training
    protein
  end

  def stretch
    puts '全身のストレッチ'
  end

  def main_training
    raise '抽象メソッド(main_training)が呼び出されてるよ'
  end

  def protein
    puts 'プロテイン摂取'
  end
end

module ChestTraining
  def stretch
    puts '胸のストレッチ'
  end

  def main_training
    puts 'ベンチプレス!'
    puts 'チェストプレス!'
  end
end

module ShoulderTraining
  def main_training
    puts 'ショルダープレス!'
    puts 'サイドレイズ!'
  end
end

次のように実行すると、結果は先ほどと同じになります。

MuscleTraning.new.extend(ChestTraining).execute
MuscleTraning.new.extend(ShoulderTraining).execute

extend メソッド は引数で渡されたモジュールのインスタンスメソッドを、レシーバ(今回の例だと MuscleTraning.new)のメソッドとして追加します。また、戻り値はレシーバを返すので、この例のように execute を繋げて実行することができます。

あとはやっていることは先ほどと同じです。

Ruby は直接継承できるクラスが1つだけなので、複数のモジュールを extend したい場合にこちら方法が特に有効となります。

おわりに

ここまで読んでいただきありがとうございます。

ただの継承では と思われるかもしれませんが、これもデザインパターンの1つなのですね。「デザインパターン」というのはもっと複雑なものをイメージしていましたが、シンプルで非常に分かりやすかったです。

Rubyによるデザインパターン では、レポートをHTML形式やプレーンテキスト形式で出力するという現実的なサンプルコードを用いて説明されており、非常に分かりやすかったので、ご興味ある方は是非合わせてご覧ください。

(ただしこの本は絶版で、定価よりも高い値段で中古本が販売されている状況です...高かった...)

Rubyによるデザインパターン

Rubyによるデザインパターン

次回は、ストラテジーパターンをまとめる予定です。

来週も頑張ります!

(追記)
ストラテジーパターンについてまとめました!
使い所はTemplateメソッドパターンと似ており、ストラテジーパターンは継承を用いずに実現しています。
是非合わせてご覧ください。
ysk-pro.hatenablog.com

AWSの資格(SAA-ソリューションアーキテクトアソシエイト)に合格するまでにやったこと・感想

こんにちは。

昨日、AWSの資格(SAA - ソリューションアーキテクト アソシエイト)に合格しました!嬉しい!

2週間前に1度落ちてからの合格と、それなりに苦労したので、合格するまでにやったことや、この資格を勉強した感想などを書いておきます。

f:id:ysk_pro:20190818074323p:plain

AWS SAA(ソリューションアーキテクトアソシエイト)資格とは

認定によって検証される能力

  • AWS のテクノロジーを使用して安全で堅牢なアプリケーションを構築およびデプロイするための知識を効果的に証明すること
  • 顧客の要件に基づき、アーキテクチャ設計原則に沿ってソリューションを定義できること
  • プロジェクトのライフサイクルを通して、ベストプラクティスに基づく実装ガイダンスを組織に提供できること

AWSの公式ページより抜粋)

AWSの資格は色々とあるのですが、SAAが一番幅広く学べそうな印象でした。

 

なぜ受けたのか

僕が勤めている会社のサービスでAWSを使っているのですが、仕事をしている中でSREチーム(インフラチーム) の話についていけず、まずいと思ったことがきっかけです...

SREチームの方に勉強方法を聞いたところ、このSAA資格のことを教えていただき、せっかくなので資格を取ることに決めました。

 

合格するまでにやったこと

参考書2冊

AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト

AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト

 

この2冊を使いました。

この2冊の選定理由としては、最近発売されたことAWSのサービスはどんどん変わるので、それに伴って試験問題も変わります)、模擬試験が含まれていること(この試験では過去問などが公開されていないので本番を想定した問題はかなり貴重です)です。

個人的には下の黄色い方がオススメです!(説明が分かりやすく、模試の問題数も多かった) 

 

Udemy

サービスを理解して使えるようにすることが真の目的だったので、実際に手を動かしながら学べるUdemyもやってみました。

主要なサービスについて、解説があった後に実際に触っていく形式です。

多くのサービスを実際に触るのでかなり時間はかかったものの、使用するイメージがつき、楽しく学べました。

僕が受講したのはこちらのコースです。

これだけでOK! AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座(初心者向け21時間完全コース)

Udemyで頻繁に行われているセール期間中には2,000円以下になるので、そこが狙い目です。

 

Amazon Black Belt セミナー資料

Black Belt というのはセミナーの名前で、AWSがネット上で公開している各サービスについての資料です。

これがかなり分かりやすく、AWS公式の説明資料なのでおすすめです。

ご参考として、EC2の資料を埋め込みます。

初心者向けにかなり丁寧に解説していることが分かると思います。

全てのサービスについての資料はこちらから見ることができます。 

上で紹介した黄色い方の参考書(この1冊で合格! AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集)には、試験におけるサービス毎の重要度が3段階で書かれているのですが、 ☆☆☆のサービスは3回、☆☆のサービスは2回、☆のサービスは1回以上こちらの資料を読むようにしました。

SAA資格は過去問が無く、AWSが公式で出している問題も少ないので、AWSが公式で出しているBlack Beltセミナー資料は必ず目を通しておくべきだと思います。

ちなみに、1度目に資格試験に落ちた際には、こちらの資料に目を通していなかったことも敗因の1つだった気がします...

 

資格を勉強した感想

かなり苦労しましたが、勉強して良かった!と思っています。

資格取得のきっかけになった、SREチームの方が話していた内容もだいぶ分かるようになり、会社で自分が開発しているサービスの構成も分かるようになり面白いです。

AWSに苦手意識のある方、一度体系立てて勉強したい方AWS SAAの資格取得はおすすめです。

【読書まとめ24】王道SEO対策 実践講座 

読書まとめの第24弾です。

今回は、成果を出し続けるための 王道SEO対策 実践講座 を読みました。

SEO対策の基本について解説している本で、会社のSEOに強い方に教えていただき読みました。

会社のサービスをはじめ、自分のサービスやブログにもすぐに実践できる内容だったので、忘れないように要点をまとめます。

すぐに読めると思うので、SEOの対策の基本について興味がある方は是非ご覧ください。

成果を出し続けるための 王道SEO対策 実践講座

成果を出し続けるための 王道SEO対策 実践講座

 

SEO対策について考えている男性

SEO対策のポイント

  • Webサイトの更新頻度は、SEO対策において重要な要素の一つとなる
  • パンくずリストを利用することが、最適なリンク構成を実現するための最も単純で基本的な方法
  • ドメインやURLは、一度決定したら対象ページが存在している限り変更しない
  • alt属性は画像が表示されない場合にどのような画像を表示したかったかを利用者に伝える手段になるとともに、目の不自由な方が画像の内容を知るための手助けになるので、通常は見えなくても利用者にとって非常に重要な要素となる。適切に利用すればコンテンツの評価を上げる要素となる
  • オリジナリティがコンテンツの価値になる。テンプレートや画像を提供するECサイトは、画像や価格が異なる程度で、ほとんど内容が同じページが量産されてしまうことがある。こうしたページが重複コンテンツと判断されたり、テキストの要素が少ない価値の低いコンテンツと判断されたりして、ペナルティを課される可能性もある。そのため、画像を撮影した際のデータや商品の仕様などをできるだけ記載して情報を増やしたり、コメント機能で利用者のコメントを集めたりして、それぞれのページが異なる内容を提供できるようにするべき
  • アクションにつながるキーワードを含めるとその後の行動に結びつきやすい。具体的には、「SEO対策 相場」や「デジカメ 激安」などの購入したいという意思や、「デジカメ 修理」や「名刺 即日」などのすぐ必要という緊急性を含んでいるワードである

具体的な指針

  • titleについて
    • 全角30文字以内
    • 対象ページで狙うすべてのキーワードを入れる
    • キーワードの重複は避ける
    • 意味区切りは「|」「-」「:」のどれかで区切る
  • descriptionについて
    • 全角100文字以内
    • 対象ページで狙うすべてのキーワードを入れる
    • キーワードの重複は避ける
    • すべてのページでdescriptionが同じだとマイナス評価につながる
  • キーワードを乱用すると、ペナルティの対象となることがある。具体的な利用の目安は以下の通り
    • 見出し:h1から順に利用し、h1が利用できるのはまとまりにつき1つ
    • strong要素:利用は1ページにつき数回程度で、同じ語句には使わない
  • キーワードの出現率の参考値は以下の通り。無料ツールを使って調べることができる
    • 1番目に対策したいキーワード:適正出現率 5〜7%
    • 2番目:4〜5%
    • 3番目:3〜4%

ツール

  • Search Consoleは、Googleの検索結果でのWebサイトのパフォーマンスを監視、管理できるサービス。WebサイトがGoogleにどのように認識されているか確認できるので、検索結果でのパフォーマンスを最適化するのに役立つ
  • Webサイトの運営開始直後で、なかなかクローラが回って来ず、インデックス化までに時間がかかる場合は、Search ConsoleやBing WebマスターツールからURLを指定してクローラの巡回を催促することができる
  • Search ConsoleでXMLサイトマップを登録すると、より早くWebサイトの更新情報を検索エンジンに伝えられるので、クローラが回ってくるまでの時間が短くなるとともに、抜け漏れなく情報を収集してもらえるようになる
  • 内部リンクはWebサイト内に置ける相対的重要度の指標として利用されるので、強化したいページにリンクを集中させられていない場合は、設計通りの成果を出しづらい
  • Search Consoleの「HTMLの改善」を利用することで、HTMLの不足要素や重複を一度にチェックできる

おわりに

ここまで読んでいただきありがとうございます。

特に、具体的な指針の項目は今日から使えるものばかりだったので、すぐに実践していこうと思います。 

この記事で紹介しきれないくらい、多くのSEOについてのことが解説されていたので、SEO対策について網羅的に理解したい方におすすめです。

成果を出し続けるための 王道SEO対策 実践講座

成果を出し続けるための 王道SEO対策 実践講座

 

次はWebの速度改善についての本を読んでみようと思います。

AMP Conf 2019に行ってきました!印象に残ったセッションなどまとめ

4/17(水)、18(木)に、六本木ヒルズで行われたAMP Conf 2019に参加してきました!

参加する前は、AMPについてほとんど何も知らない状態だったのですが、2日間でAMPすげー!となったので、印象に残ったセッションなどについて書いてみます。

AMPについて知らなかった方最近のAMPについて興味がある方の参考になれば嬉しいです。f:id:ysk_pro:20190421145044j:plain

AMPとは

AMP(Accelerated Mobile Pages)は、モバイルページを高速で表示させる技術で、2015/10にGoogleTwitterオープンソースプロジェクトとしてスタートしました。

スマホGoogle検索した時に、こちらの画像のようにカミナリマーク(⚡️)がついているのがAMP対応ページで、クリックしてみると爆速で表示されるのが分かります。ほんとにビックリするくらい爆速です。

f:id:ysk_pro:20190421131912p:plain

f:id:ysk_pro:20190423155212g:plain

(こちらは「ラクマ スマブラ」と検索した結果で、1ページ目に表示されていました)

読み込めるJavaScriptや、CSSの容量に制限を設けることで読み込みにかかる時間を減らし、さらにGoogleがコンテンツをキャッシュしていることなどによって、このスピードを実現しています。

こちらのAMP Confのオープニング動画(4分くらい)が分かりやすく、そして面白くAMPについての概要を解説してくれているので是非ご覧ください。

youtu.be

(よくありがちな、会場への道中で色々説明していって、最後に本当に会場に登場するやつです 笑)

 

AMP Confとは

年に一回開催される、開発者の開発者による開発者のための AMP の技術祭典を、今年は東京で行います。(公式ページより) 

公式ページはこちらです(もちろんAMP対応しています)

2018年はオランダのアムステルダム、2017年はニューヨークで開催されており、懇親会で話を聞くと、このイベントのためにブラジルやカナダから来た人もいるような世界的なイベントです。

 

印象に残ったセッション

全てのセッションYouTubeこちらに公開されています(YouTubeの自動翻訳が使えるので英語が分からなくても安心!)

amp.dev live!

2人のGoogleのエンジニアが、30分でAMPページをライブコーディングするセッションです。

作ったAMPページの画像は以下で、次の機能を備えています。

  • 下タブでコンテンツを切り替えられる機能
  • 下スクロールでナビゲーションバーが隠れて、上スクロールで表示される機能
  • ツイートを15秒ごとに自動で取得する機能
  • 無限スクロール機能

f:id:ysk_pro:20190421134222p:plain
AMPページは、用意されているコンポーネントを組み合わせて作ることが多いようです。このライブコーディングを通じて、実装のイメージが湧いたのでとても良かったです。

そしてGoogleのエンジニアかっこいいなぁ。

youtu.be

 

AMP Stories: The Story so far

AMPでこんな感じのストーリー機能が実装できます。おしゃれ!

f:id:ysk_pro:20190421143207p:plain

また、検索結果にAMPストーリーを表示する専用の箇所を作ることを検討しているようなので、今のうちにAMPストーリーを作っておくといいかも。

f:id:ysk_pro:20190421143300p:plain 

簡単に綺麗なストーリーが作れるようなので、是非作ってみたい...!

youtu.be

 

AMP for Email: pushing the boundaries of email with AMP

Emailは基本的に、テキストかシンプルなhtmlで構成されていると思います。

しかし、AMP for Emailを使えばこのようにインタラクティブなコンテンツを提供することができます。

f:id:ysk_pro:20190421144059p:plain

↓これが分かりやすいです(セッション動画を該当箇所から再生するようにしています)

Email上で申し込みや購入までできたりするの、とてもいいですよね。

現在はGmailのみが対応しているそうですが、今後他のメールクライアントでも対応予定だそうです。

このセクションの中では実際の実装方法も詳しく解説されており、通常のAMPページ同様にシンプルに実装できそうだったので、試してみようと思っています。

youtu.be

 

懇親会

1日目の夜にパーティーがあり、参加者やGoogleの方などとお話しすることができました。

DJがいて、ご飯も美味しくて楽しかったー。

f:id:ysk_pro:20190421145023j:plain

f:id:ysk_pro:20190421145034j:plain

寿司!! 

 

おわりに

AMPについてほとんど何も知らない状態で参加しましたが、2日間を通じてAMPのファンになりました。

業務扱いで参加させてもらったので自社プロダクトのAMPページを改修するのはもちろん、個人で作るサービスでも使ってみようと思いました。

最初にも書きましたが、全セッションはYouTubeで公開されているので、気になった方は是非ご覧くださいー!

【技術書まとめ23】リーダブルコード

毎週1冊技術書を読んでブログでアウトプットすることが目標で今回が第23弾です。

今回は、リーダブルコード  を読みました。

もはや説明不要の名著ですが、良いコードを書くための原則を分かりやすく、そして簡潔に解説している本です。

200ページ程度でサクッと読めましたが、気づきがとても多かったです。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

 

f:id:ysk_pro:20190401065701p:plain

1章 理解しやすいコード

  • コードは「他の人が最短時間で理解できるように」書く
 

2章 名前に情報を詰め込む

  • tmpなどの汎用的な名前が単なる怠慢で使われていることも多い。いい名前が思いつかなかったらfooのような意味のない名前を使いたくなってしまうが、少しでも時間を使って名前を考える習慣をつけるようになればすぐに命名力は高まる
  • 抽象的な名前よりも具体的な名前を使う
  • 単位やセキュリティなどの重要な属性を名前に追加するのも有効(例 ミリ秒を表す変数名には、後ろに _ms をつけるなど
 

3章 誤解されない名前

  • 誤解される可能性がある名前をつけない。「他の意味と間違えられることはないだろうか」と自問自答する
  • 上下の限界値を決めるときは、max_ や min_ を前につけるとよい
  • ブール値に名前をつけるときは、それがブール値だとわかるように is や has などを使う
 

4章 美しさ

  • 複数のコードブロックで同じようなことをしていたら、ぱっと見て分かるようにシルエットも同じようなものにする
  • コードを縦に揃えて楽に読めるようにする
 

5章 コメントすべきことを知る

  • コメントの目的は、書き手の意図を読み手に伝えること
  • コードからすぐにわかることをコメントに書かない
  • コメントよりも自己文書化された適切な名前(関数名、変数名)をつけるべき
  • 優れたコメントは、コードを書いた考え(なぜコードが他のやり方ではなくこうなっているのかなど)を記録するためのもの
  • 定数を定義するときに、その定数が何をするのか、なぜその値を持っているかという背景をコメントするとわかりやすくなるケースが多い
  • 読み手の立場になって考え、質問されそうなこと、ハマりそうな罠についてコメントする
 

6章 コメントは正確で簡素に

  • 複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける
  • 入出力の実例をコメントに書いておくことは千の言葉に等しい
 

7章 制御フローを読みやすくする

  • ネストの深いコードは理解しにくい。ネストが深くなると、読み手は「精神的スタック」に条件をプッシュしなければならない
  • 「失敗ケース」をできるだけ早めに関数から返すことで、ネストを削除できることが多い
  • 比較を書くときには、変化する値を左に、より安定した値を右に配置する
  • If/elseのブロックは適切に並び替える。一般的には、肯定系・単純・目立つものを先に処理する
 

8章 巨大な式を分割する

  • 人間は一度に3〜4つの「もの」しか考えられないので、コードの式が大きくなれば、それだけ理解が難しくなる
  • 大きな式の値を保持する説明変数を導入すれば、巨大な式を分割でき、コードを文書化することができる
 

9章 変数と読みやすさ

  • 変数のスコープを縮めると読みやすくなる
  • 変数が絶えず変更され続けると現在値の判断が難しくなりコードが理解しにくくなるので、変数は一度だけ書き込むようにするとよい
 

10章 無関係の下位問題を抽出する

  • 以下のステップで無関係の下位問題を見つけて抽出する
    • 関数やコードブロックを見て「このコードの高レベルの問題は何か?」を自問する
    • コードの各行に対して「高レベルの目標に直接的に効果があるのか?あるいは、無関係の下位問題を解決しているのか?」を自問する
    • 無関係の下位問題を解決しているコードが相当量あるば、それらを抽出して別の関数にする
  • 関数は、小さく独立したものになっていれば、機能追加・エッジケースの処理などが楽にでき、読みやすくなる
  • プロジェクト固有のコードから汎用コードを分離する。ほとんどのコードは汎用化できる
 

11章 一度に1つのことを

  • 一度に1つのタスクをするためには、まずコードが行なっているタスクを全て列挙し、タスクをできるだけ異なる関数に分割するとよい
  • 最も大切なのは、プログラムが行なっていることを正確に説明すること
 

12章 コードに思いを込める

  • 誰かに複雑な考えを伝えるときには、細かいことまで話しすぎると相手を混乱させてしまう。自分よりも知識が少ない人が理解できるような「簡単な言葉」で説明する能力が大切。これには、自分の考えを凝縮して、最も大切な概念にすることが必要となる。これは誰かに理解してもらうだけでなく、自分の考えをより明確にすることにもなる
  • コードというのは、プログラムの動作を説明する最も大切な手段である。つまり、コードも簡単な言葉で書くべき。問題や設計をうまく説明できないのであれば、何かを見落としているか、詳細が明確になっていないということ。プログラム(あるいは自分の考え)を言葉にすることで明確な形になる
  • 以下のステップでコードを明確にすることができる
    • コードの動作を簡単な言葉で同僚にもわかるように説明する
    • その説明の中で使っているキーワードやフレーズに注目する
    • その説明に合わせてコードを書く
 

13章 短いコードを書く

  • 自分で書いたコードであれば、全ての行をテストして保守しなければいけない。ライブラリの利用や機能の削除をすることで、時間の節約をしたり、コードを簡潔に維持したりできる
  • プロジェクトが成長しても、コードをできるだけ小さく軽量に維持するために、以下のことをすべき
    • 汎用的なユーティリティコードを作って、重複コードを削除する
    • 未使用のコードや無用の機能を削除する
    • プロジェクトをサブプロジェクトに分割する
 

14章 テストと読みやすさ

  • 他のプログラマが安心してテストの追加や変更ができるように、テストコードは読みやすくするべき
  • 一般的な設計原則として、大切ではない詳細はユーザから隠し、大切な詳細は目立つようにする
  • テストの本質は「こういう状況と入力から、こういう振る舞いと出力を期待する」というレベルまで要約できる。そして、これらは1行でまとめられることが多い
  • テストの入力値は、コードを完全にテストする最も単純な組み合わせを選択する

 

おわりに

ここまで読んでいただきありがとうございます。 

本書の中では、イラスト・実際のコードを使って解説しており、とても分かりやすくて読んでいて楽しい本だったのでオススメです。 

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

 

早いもので、もう4月ですね。

次は何を読もうかなー。

来週も頑張ります!