May the result of pcr test be negative!

東京〜フランス間のフライトがトランジット含めて31時間かかることに発狂している7月末です。

「Clean Architecture」「Clean Code」「独習UML」を借りました。これを読んで8月は開発者としてのプロ意識を高めていきたいです。

もっぱら小説に対する欲が薄れていて、開発に関する書籍を読みたい欲に変わってしまいました。いいのか悪いのか。。

そしたら今週の振り返りをつらつらと。。

 

 

高凝集 低結合

凝集度 結合度とは

ソフトウェアの品質を表す指標を指す。

クリーンなソフトウェアを構築していくためには、「ソフト」なアプリ、つまり柔軟なアプリを作成することを心がける必要がある。

柔軟なアプリとは、仕様変更に柔軟に対応できるアプリ、つまり運用保守性の高いアプリを指している。

そのために、過去の賢人達が様々なデザインパターン(効率的にソフトウェアを作り上げる手段)を考案されている。

そこで出てきた重要な単語が凝集度 結合度だった。

凝集度

下記のような特徴がある。凝集度は高い方が良い。

  • クラスの責務、クラスのメソッドとデータ(機能要素と情報要素間)の関連性の強さ

クラスの責務が単一であればあるほど良い。

なぜなら、クラスを修正した時の影響範囲を追いやすくなり運用保守性が高まるから。

  • クラスの責務とは、「そのクラスが何をするクラスなのか?」に対する答え

クラスを設計するときは、一体これは何をするべきクラスなのか?と問いながら作成するといい。

結合度

モジュール間の依存度を示す指標で、こちらは低い方がいい(疎結合、低結合)

なぜなら、依存度が高いということは、依存先の修正の影響を受けやすいと言っていると同義だから。

凝集度を低くしないためには下記二つを意識するといいみたい。

  • そのクラスが何をしているのかを明確に答えられるようにする。(クラスの責務を明確にする)
  • クラス内のデータと関係のないメソッドをなくす

オブジェクト指向は1回忘れよう。10分でわかる設計のツボ 「高凝集/低結合」

git restore

リモートにプッシュしてしまったコミットを無しにしてくれる

開発を進めている中で、いらないファイルをコミットしてしまった場合に下記のコマンドが使える。

-sはsoftの略で、ファイルの変更内容は残しながら、コミットは無かったことにすることができるコマンド。

git restore -s HEAD^ foo.txt

Git初心者なら必ず覚えるべきgit restoreコマンド

initialize

クラスのインスタンス作成時に自動で読み込まれる

ここに変数を記述しておくことで、他のメソッド内において属性をハンドリングすることができるようになる。

  • attr_readerと同じ処理
  #@nameを外部から参照するためのメソッド
  def name
    @name
  end
  • attr_writerと同じ処理
   #@nameを外部から変更するためのメソッド
  def name=(value)
    @name = value
  end

全てまとめたクラス

class User
  def initialize(name)
    @name = name
  end
  
  #@nameを外部から参照するためのメソッド
  def name
    @name
  end

   #@nameを外部から変更するためのメソッド
  def name=(value)
    @name = value
  end
end

上記のクラスからインスタンスを生成する時に、その親クラスから継承してきた属性に入れる値を決める。

User.new('Subaru')

これを外部から参照するときは、

User.new('Subaru').name
#もしくは
user = User.new('Subaru')
user.name
#=> Subaru

これを上書きするときは、

user.name = 'Nakano'

name=(value)メソッドが呼び出されて、インスタンスの中身が上書きされる。

Block Proc

Block

ブロックとは、mapやeachの後によく見られる、do ~ end, {}で囲われた引数となる部分をさす。

メソッドに引数として渡される塊。

def yield_block_contents
  yield
end

#
yield_block_contents do
  p "Hello, block!"
end

#=> "Hello, block!"

引数にブロックが渡されることを明示する。

#メソッド定義
def yield_block_contents( &block )
  block.call
end

#実行
yield_block_contents do
  p "Hello, block!"
end
=> "Hello, block!"

引数のblockの前にある&でblockをProcオブジェクトに変換している。

(&:to_s)

to_s(何でもいい)メソッドを呼び出すオブジェクトにto_procが定義されている場合、(&:to_s)のような書き方ができる。

Array.map(&:to_s)

SymbolオブジェクトをProcオブジェクトに変換して新しい配列を返す書き方。

Symbolオブジェクトがto_procを組み込みで持っている為、(&:to_s)のように、

シンボルに対してBlockに渡すことができている。

to_procメソッドを作成してeachにFooインスタンスを渡してみる。

class Foo
  def to_proc
    Proc.new {|v| p v}
  end
end

#Fooのto_procが呼び出されてProcに渡されている。
[1,2,3].each(&Foo.new)

=> 1
   2
   3

Proc

先ほど学んだ、Blockをオブジェクト化させたもの。

ブロックはそのままでは存在できない。その為、Procオブジェクトとして保管して置く必要がある。

使用するときは、Procオブジェクトから作成したインスタンスをレシーバとしてcallメソッドを呼び出す。

procedureの略。

下記のような方法がある。

[1, 2, 3].map do |n|
  :to_s.to_proc.call(n)
end
# => ["1", "2", "3"]
# Proc オブジェクトを直接呼び出す場合は call メソッドを用いる

[1, 2, 3].map(&:to_s.to_proc)
# => ["1", "2", "3"]
# 明示的にto_proc して Proc オブジェクトをブロックの代わりに渡している

[1, 2, 3].map(&:to_s)
# => ["1", "2", "3"]
# to_proc を持つオブジェクトとして :to_s を渡している。

Ruby block/proc/lambdaの使いどころ - Qiita

Ruby のブロックをちゃんと理解する