空飛ぶたまごエンジニア

韓国進出を夢見るエンジニアのブログ

10月13日の日記

今日の学び

わからなかった単語

ポインタ

変数の一種で、あるオブジェクトの論理的位置情報を格納する変数のこと

参考にしたサイト

リンク

ある構造体のメンバに別のメンバの構造体にアクセスするためのポイントを格納することで、構造体をつなぐことを リンク という。

参考にしたサイト

コレクション

データやオブジェクトなどをまとめて格納するためのデータ構造やクラスなどの総称

配列やハッシュ、スタック、キューもコレクションの例である

参考にしたサイト

10月9日の日記

今日の学び

私の苦手なもの「読解・要約」

今日の学びというと嘘になってしまいますが、週末(10月7・8日)に自分を振り返り、今の私には「読解力・要約力」が足りないと感じました。

相手の伝えたいことをしっかりと理解することが小学生の頃から苦手で、今に至るまで逃げて生きてきました。(今思えば国語の点数はずーーっと悪いままでした)

文字を読むのも苦手ですし、人の話を聞いて「つまり、〜〜〜ということ」と要約するのが苦手です。いつも途中で何について書いているのか、話しているのかわからなくなります。

それが原因で学びの効率も悪くなっている ような気がします。なぜなら、文章を読んで理解するのは苦手だったり、人の話を聞いてまとめることが苦手だったりするからです。

まずは文字アレルギーの克服から!

私は文字と向き合うことから、ほとんど逃げてきました。本も指で数えるほどしか読んだことがありません。(ちょっといいすぎかもw)

しかし、このままでは学べるものも学べず、成長スピードが遅いままです。まずは「文字アレルギー」を克服し、「読解力・要約力」を伸ばして、成長スピードを向上させようと思います!

そこで、先週末に6つの小説を購入しました。いきなり純文学など難しそうな本に挑戦すると、あっという間に挫折しそうだったので、まずはライトな小説から挑戦しようと思いました。

ちなみに私が購入した小説はこちらです。

また、同じ夢を見ていた (双葉文庫)

また、同じ夢を見ていた (双葉文庫)

コンビニ人間 (文春文庫)

コンビニ人間 (文春文庫)

七つの会議 (集英社文庫)

七つの会議 (集英社文庫)

10月6日の日記

今日の学び

リファクタリング: Rubyエディション

Self Encapsulate Field

フィールドとの密結合により、フィールドへの直接アクセスが不都合になっているとき、アクセサを使って関節アクセスするようにする

# リファクタリング前
def salary
  @base_salary * @bonus_rate
end

# リファクタリング後
attr_reader :base_salary, :bonus_rate

def salary
  base_salary * bonus_rate
end

スーパークラスはフィールドに直接アクセスしているが、サブクラスでは計算した値を返すためにフィールドへのアクセスをオーバーライドしたくなったときが絶好のタイミング

class Employee
  attr_accessor :base_salary, :bonus_rate

  def initialize(base_salary, bonus_rate)
    @base_salary = base_salary
    @bonus_rate  = bonus_rate
  end

  def salary
    base_salary * (1 + bonus_rate)
  end
end

class Manager < Employee
  attr_reader :position_allowance

  def initialize(base_salary, bonus_rate, position_allowance)
    super(base_salary, bonus_rate)
    @position_allowance = position_allowance
  end

  def total
    super + position_allowance
  end
end

大事なのは、リファクタリングによって直接変数アクセスも関節変数アクセスにも切り替えることができること。

Change Value to Reference

同値のインスタンスをいくつも生成するクラスがあり、それらのオブジェクトを同じものと判断したいとき、そのオブジェクトを参照オブジェクトに変更する

# リファクタリング前
class Guest
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

guest1 = Guest.new("Bob")
guest2 = Guest.new("Ken")
guest1 == guest2 # => false

# リファクタリング後
class Guest
  attr_reader :name

  def initialize(name)
    @name = name
  end

  Instances ={}

  def self.load_guests
    new("Bob").store
  end

  def store
    Instances[name] = self
  end

  def self.create(name)
    Instances[name]
  end
end

Guest.load_guests
guest1 = Guest.create("Bob")
guest2 = Guest.create("Bob")
guest1 == guest2 # => true

オブジェクト導入時は、イミュータブルな値を持つ単純な値オブジェクトという位置付けだったけれども、後で変更可能なデータが追加したり、概念的に同じオブジェクトを参照する部分に変更による効果を与えたくなる場合がある。

そういった場合に上記のように、ファクトリメソッドを定義し、オブジェクトの作成処理を管理するようにして実装する必要がある。

つまりは、単純な値オブジェクトから参照オブジェクトに変更しなければならないということである。

Change Reference to Value

イミュータブルな参照オブジェクトの管理が面倒になってきたとき、オブジェクトを値オブジェクトに変更するテクニック

# リファクタリング前
class CurrencyRate
  attr_reader :code

  def initialize(code)
    @code = code
  end

  def self.get(code)
    ...レジストリから CurrencyRate インスタンスを返す
  end
end

jpy1 = CurrencyRate.get("JPY")
jpy2 = CurrencyRate.get("JPY")
jpy1 == jpy2

CurrencyRate.new("JPY") == CurrencyRate.new("JPY") # => false
CurrencyRate.new("JPY").eql?(CurrencyRate.new("JPY")) # => false

# リファクタリング後
class CurrencyRate
  attr_reader :code

  def initialize(code)
    @code = code
  end

  def self.get(code)
    ...レジストリから CurrencyRate インスタンスを返す
  end

  def eql?(other)
    self == (other)
  end

  def ==(other)
    other.equal?(self) ||
      (other.instance_of?(self.class) &&
       other.code == code)
  end
end

jpy1 = CurrencyRate.get("JPY")
jpy2 = CurrencyRate.get("JPY")
jpy1 == jpy2

CurrencyRate.new("JPY") == CurrencyRate.new("JPY") # => true
CurrencyRate.new("JPY").eql?(CurrencyRate.new("JPY")) # => true

Change Value to Reference とは全く逆のことをしている。

イミュータブルな参照オブジェクトの管理が面倒になってきた時に、オブジェクトを値オブジェクトに変更することで、管理コストを下げることができる。

しかし、そのためには eql? メソッドと == メソッドをオーバライドする必要があるので、注意が必要。

調べたこと

値オブジェクト

以下のような特徴を持ったオブジェクトを「値オブジェクト」という

  • インスタンス自体よりも、保持するデータ値が重要な意味をもつ。
  • インスタンスが異なっても、同じ値を保持していれば同じオブジェクトとみなす。
  • 必要に応じて自由にコピーを作ることができる。
  • 原則としてイミュータブルでなければならない。

参照オブジェクト

以下のような特徴を持ったオブジェクトを「参照オブジェクト」という

  • インスタンス自身が重要な意味をもつ。
  • 同じデータを持っていても、インスタンスが異なれば違うオブジェクトと見なす。
  • 通常コピーは作らない。
  • イミュータブルでなくてもよい。

10月3日の日記

今日の学び

リファクタリング: Rubyエディション

第7章は オブジェクト間でのメンバの移動 をテーマに、リファクタリングのテクニックがまとめられている。

全部で6つのテクニックが紹介されている。

  • Move Method
  • Move Field
  • Extract Class
  • Inline Class
  • Hide Delegate
  • Remove Middle Man

Move Field

要約

フィールドが、他クラスでよく使われていたら、最もよく使われているクラスにフィールドを移動する

# リファクタリング前
class Employee
  def initialize(bonus_rate)
    @bonus_rate = bonus_rate
  end

  def bonus
    @bonus_rate * base_salary
  end
end

# リファクタリング後
class Employee
  def initialize(employee_type)
    @employee_type = employee_type
  end

  def bonus(base_salary)
    @employee_type.bonus_rate * base_salary
  end
end

class EmployeeType
  attr_accessor :bonus_rate

  def initialize(bonus_rate)
    @bonus_rate = bonus_rate
  end
end

※ 注意: 上記サンプルは、 bonus_rate フィールドが Account クラスではなく AccountType クラスでよく使われるようになることが前提となっている

説明

  • フィールドは最もよく使われているクラスに定義する

備考

  • 以前までは正しかった実装が、今では誤った実装になりうる
    • 仕様が変われば、リファクタリングで実装し直せばいいだけ
    • 問題は誤った実装のまま、何も対策を打たないこと

所感

フィールドは最もよく使われているクラスに定義することで、コード量が減ることを実感。

コード量が少なくなれば、それだけ人間が読むコードの量も減るし、結果的に効率的な開発に繋がるのだろうと思った。

調べたところ

ここでいうフィールドとは?

クラス内のインスタンス変数のことを差すようだった

アクセサ

クラス内にインスタンス変数を定義するだけでは、そのクラスのインスタンスから定義したインスタンス変数にアクセスできない

class Person
  def initialize(name)
    @name = name
  end
end

person = Person.new("Bob")
person.name
# => NoMethodError: undefined method `name' for #<Person:0x00007fd0faaf99e8 @name="Bob">

上記のインスタンス変数にアクセスするためには、以下のようなゲッターとセッターを実装する必要がある

class Person
  def initialize(name)
    @name = name
  end

  # ↓ これがゲッター
  def name
    @name
  end

  # ↓ これがセッター
  def name=(val)
    @name = val
  end
end

person = Person.new("Bob")
person.name
# => "Bob"

person.name = "John"
person.name
# => "John"

Ruby には attr_readerattr_writerattr_accessor といったアクセスメソッドが用意されていて、ゲッターとセッターを簡単に実装できる

定義式 機能
attr_reader: 変数名 参照が可能
attr_writer :変数名 更新が可能
attr_accessor :変数名 参照と更新が可能
class Person
  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

person = Person.new("Bob")
person.name
# => "Bob"

person.name = "John"
person.name
# => "John"

10月1日の日記

今日の学び

リファクタリング: Rubyエディション

第7章は オブジェクト間でのメンバの移動 をテーマに、リファクタリングのテクニックがまとめられている。

全部で6つのテクニックが紹介されている。

  • Move Method
  • Move Field
  • Extract Class
  • Inline Class
  • Hide Delegate
  • Remove Middle Man

Move Method

要約

メソッドが、他クラスの機能を多く使っていたり、他クラスに何度も利用されたりしていたら、最もよく使われているクラスにメソッドを移動する

# リファクタリング前
class Employee
  def base_salary
    if @employee_type.manager?
      return 200000
    else
      return 100000
    end
  end
end

# リファクタリング後
class EmployeeType
  def base_salary
    if manager?
      return 200000
    else
      return 100000
    end
  end
end

説明

  • メソッドは最もよく使われているクラスに定義する
    • 他クラスを参照しなくて済むので、コードが少なくなる
    • 他クラスの実装を見に行かなくてよくなる

備考

  • リファクタリングをしたら、必ずテストを実行する
    • メソッドを移動したときにテストを実行
    • 上記に伴うメソッド呼び出し箇所の書き換えでもテストを実行
    • Rubyコンパイラ言語ではないので、テストが命綱になる

所感

メソッドは、最もよく使われているクラスに定義するということを、恥かしながら最近知った。

しっかり考えればわかることではあるが、他クラスのオブジェクトを参照しなくてもよくなるし、他クラスの実装も見に行ったりしなくてよくなる。結果的に効率よくコードがかけるようになるなと実感した。

また Rubyインタープリタ言語であり、リファクタリング後にコンパイルによってミスをキャッチできない。だからこそ、テストが重要であるということに深く納得した。

タスクを効率よく進めるために改めようと思った3つの考え方

背景

私はタスクの進捗が遅いことに課題を感じていて、それを解決するために我流でどうにかしようとしていました。

しかし、それだと効率も悪く、なかなか根本的な解決に繋がらないことを実感していたので、他の方の知恵を借りようと本を読むことにしました。

テーマが似た本を3冊を読んだところ、仕事が遅い人の特徴で共通して挙げられているものがいくつかありました。

私自身思い当たる節があったので、今の私の考え方で改めるべきだと感じたものついてまとめてみました。

読んだ本

今回参考にさせていただいた本は以下の3冊です。

「仕事が速い人」と「仕事が遅い人」の習慣 (アスカビジネス)

「仕事が速い人」と「仕事が遅い人」の習慣 (アスカビジネス)

「すぐやる人」と「やれない人」の習慣 (アスカビジネス)

「すぐやる人」と「やれない人」の習慣 (アスカビジネス)

図解 2割に集中して結果を出す習慣術 ハンディ版

図解 2割に集中して結果を出す習慣術 ハンディ版

ひとつのことに集中する

課題となる考え方

1つ目は、 複数のことを一度にこなそうという考え方 です。

私は目の前のタスクに、なかなか集中することができません。

なぜなら目の前のタスク以外のこと(調査や雑務など)もこなそうと、様々なことに気を取られてしまうからです。例えば、以下のようなことです。

  • Slack に調査が必要な要件が流れてくると気を取られてしまう
  • 社内で困っている内容の話を耳にすると一緒に解決しようとしてしまう
  • 自分より先輩のメンバーに雑務をさせまいと常に周りを見てしまっている

具体的な解決方法

シングルタスク

集中をするには、シングルタスクを行うとよいそうです。

シングルタスクとは、 一度にひとつの作業に集中すること を指し、生産性をあげることを目的としています。

複数のタスクを一度に進めようとすると、タスク・スイッチングで空白の時間が発生してしまい、一説によると生産性を 40% も下げてしまうとのことでした。

f:id:yamataku3831:20180908193351p:plain

シングルタスクに関する本も出ていたので、せひご覧ください。

SINGLE TASK 一点集中術――「シングルタスクの原則」ですべての成果が最大になる

SINGLE TASK 一点集中術――「シングルタスクの原則」ですべての成果が最大になる

誘惑を遮断する

もうひとつは、気を取られそうな誘惑を物理的に遮断することです。

誘惑と戦おうとするとそれだけでパワーを使いますし、戦った時点で目の前のタスクに100%集中できているとは言えません。

誘惑と戦うよりも誘惑から物理的に遮断する方が効率的です。例えば、

  • 目の前のタスクが終わるまで Slack を閉じる
  • 集中できる音楽を聞いて、雑音を遮断する
  • 他のメンバーの動きが目に入らない環境で仕事をする

といったことを習慣にすると良いかもしれないですね。

仕事の時間は有限であると意識する

課題となる考え方

2つ目は、 寝なければいくらでも時間はあるという考え方 です。

私はあまり寝なくても頑張って働ける体質(だと思っていた)なので、時間はいくらでもあると考えてしまっていました。

そのせいか明確な時間制限を設けずにタスクに取り組んでしまい、結果的にだらだらとタスクに取り組んでいました。

具体的な解決方法

制限時間を設けてタスクに取り組む

時間制限を設けてタスクに取り組むことで、半ば強制的に集中を余儀なくされます。

時間の強制力をうまく活用して、瞬発力を引き出すことが大切です。

プライベートを充実させる

プライベートな時間にやりたいことがあれば、定時までに仕事を終わらせようという力がはたらきます。

プライベートが充実していればいるほど、その力も大きくなります。

まずは没頭できる趣味などを見つけることが良いのかもしれませんね!

体と脳のコンディションを意識する

課題となる考え方

3つ目は、 体や脳のコンディションが悪くても、気合いと体力でカバーするという考え方 です。

睡眠時間が少ないと、頭の中に霧が張っているような感覚になって集中ができないとわかっているのに、それは甘えだと長時間労働でカバーしていました。

これだといつまでたっても、タスクを効率よくこなせないですよね。負のスパイラルです。

具体的な解決方法

脳の性質に合わせて取り組むタスクを変える

人間は朝起きてから2, 3時間あたりでもっとも効率的に脳が動くようなので、その時間帯に合わせて重要な課題やクリエイティブな仕事に取り組むと良いそうです。

逆に夜は脳も体も疲れ切っているので、単純作業をするのに適しているとのことでした。

脳の性質に合わせて取り組むタスクを変えると効率的に仕事が進められそうですね。

戦略的に睡眠をとる

遅く起床してしまい、もっとも効率的に脳が動くタイミングが、お昼ご飯の時間と重なってしまっては勿体無いですよね。

何時に就寝すれば良いかを逆算する必要があります。

また人間は基本的に睡眠時間が6時間未満になると、意志力が低下し、誘惑に負ける可能性を高めてしまうそうです。

つまり、効率よくタスクをこなすには、戦略的に睡眠をとるべきだということでした。

まとめ

上記の3つに共通するのは、 仕組みを作って頑張らずに課題を解決する というアプローチの仕方ではないでしょうか。

私はこれまでの人生、多くの課題を根性で乗り切ってきたので、根本的に考え方を変える良いきっかけになりました。

もし私と同じようなことで悩んでいる方がいましたら、今回紹介した3冊の本を読んでみてください。

私と同様に今までの悩みや問題が解決できるきっかけになるかもしれません。

プログラミングの独学では学べなかった大切なこと

はじめに

私がプログラミングと出会ったのは、卒業して海外に渡った後でした。

自分が作ったプログラムが人の作業を楽にして、周りから感謝されるという体験からプログラミングにのめり込み、プログラマとして生きていくことを決意しました。

実際にプログラマとして働くようになって感じたことは、プログラマとして働く上で大切なことを独学で身につけるのは難しいということです。

今回は、私がプログラミングの独学をしても学べなかった大切なことについて書いていこうと思います。

独学では学べなかったこと

プログラマとして働く上で独学では学べなかったことに、以下のようなものです。

  • スケジュールを組む力
  • 可読性の高いコードを書くこと
  • 変更に柔軟な設計をすること

スケジュールを組む力

プログラミングの勉強は自分一人で行いますし、何かを期限までに作ったりしなくても良いわけです。何かを作るのにどれだけ時間をかけても人に迷惑をかけることはありません。

しかし、チームで開発するとなるとそうはいきません。自分が組んだスケジュールで開発全体が動いていきます。自分の作業が遅れてしまうと、開発全体に影響が及びかねません。

また私が働いているようなスタートアップでは、開発チームだけでなく他のチーム(企画開発・カスタマーサポートなど)にも迷惑をかけてしまうことに繋がります。

ですから、無理なスケジュールを組んでもよくないですし、かといって必要以上に余裕のあるスケジュールを組んで、開発全体のスピードが落ちてしまってもよくありません。またスケジュールが遅れてしまいそうになれば、逐次相談をして、タスクの一部を誰かに対応してもらうなどの調整も必要になってきます。

スケジュールを適切に組める力やスケジュール通りに進められなくなった時の調整力は、独学では学ぶ機会がなかったですが、とても重要な能力だと思います。

可読性の高いコードを書くこと

プログラミングはどんなに煩雑なコードを書いたとしても、動くものを作ることができてしまいます。

プログラミングの独学をしているときは、コードを他人と共有することもなく、作って終わりということが多かったので、可読性について考えたことは一切ありませんでした。

しかし、チームで開発するとなると他の人にとっても読みやすいコードでなければなりません。また日々成長していくようなサービスを作るときは、他人だけでなく自分でも読みやすいコードにしておかないと、開発スピードが落ちるだけでなく、不具合などを出してしまいやすくなってしまいます。

リファクタリング:Rubyエディション という本でも以下のような一文があります。

コンピュータが理解できるコードは誰でも書ける。優れたプログラマが書くのは、人間が理解できるコードだ。

リファクタリング:Rubyエディション

リファクタリング:Rubyエディション

今後の開発を見越したり、他人に配慮したりすることは独学ではあまり気にしなかったのですが、チームで働く上では非常に重要な考え方だと思います。

変更に柔軟な設計をすること

プログラミングを独学で勉強していたときは、作って終わりということが多かったので、先のことを考えずにコードを書いていました。作って終わりなので、先を考えることが重要と感じなかったからです。

しかし、自社サービスのように日々成長していくものを作るとなると、先を見越して仕様変更にも柔軟な設計をする必要があります。先のことを考えずに、その時点での仕様に最適化した実装をすると、修正や機能拡張がしづらくなってしまいます。

現に自分が実装した機能が、ある時点での仕様に最適化された設計になっており、シンプルな機能拡張を実装しようとしたときに、非常に苦労したことがあります。「こんなシンプルな要件を実装するのに、なぜこんなにややこしくなるんだろう」という苛立たしさを今でも覚えています。

未来に必ず何かしら仕様の変更があるということを前提に考え、その変更にも柔軟に対応できるような設計をするということは独学ではあまり気にしなかったですが、サービスを成長させていくという点でとても重要な考え方だと思います。

終わりに

以上が私がプログラミングの独学をしても学べなかった大切なことの一部です。もし過去の自分がこの記事を見たとしても、上記のようなことを独学で身につけるのは難しいだろうなと思いました。優秀な人に囲まれている環境で、日々フィードバックを受けることができるからこそ、身につけられることなのかなと思いました。

現在独学でプログラミングを学んでいる方は、ある程度コードが書けるようになったら、ぜひチームに加わって開発してみてはいかがでしょうか?