LoginSignup
0
0

More than 1 year has passed since last update.

モジュールを適切に使う オブジェクト指向設計実践ガイド

Last updated at Posted at 2021-06-15

はじめに

本題はここモジュールからです

読者対象

読者対象はプログラミング初学者です。
といっても全くの初学者ではなく、Railsチュートリアルを終えたレベルと定義します。

オブジェクト指向設計実践ガイド

オブエジェクト指向設計実践ガイドの記事は、他の方も書いてありますが、
一度に全部まとめたものが多かったです。
この記事は、オブエジェクト指向らしく、各章ごとに、単一責任に、シンプルさを意識して書きました。
余談ですが、とある弁護士が弁護士は六法全書を丸暗記してないが、各条文を見ただけで、関係ある条文、知識を思い出すそうです。
この記事は、オブジェクト指向設計実践ガイドってこんなこと書いてあったなーと思いだすための記事でもあります。
また、オブエジェクト指向設計実践ガイドを読んだことがなくても、こういうことが書いてあるとのかー、とさわりだけでも理解して頂けたら幸いです。

オブジェクト指向設計実践ガイドで得た3つのポイント

リファクタリング前のコードを読み、コードの危うさを察知できる。
リファクタリングするために、より抽象的なコードの書き方を学べる。
gemなどの抽象的なコードを読解できる。

一問一答

一問一答風の構成にしています。
リファクタリング前のコードを読み、コードの危うさ、嗅覚を養っていきましょう。
その後、リファクタリング前のコードの危うさを説明し、自分なりにリファクタリングしたコードを書いてみましょう。
最後に、もう一度、リファクタリング前のコードと、リファクタリング後のコードを読み比べ、
抽象的な思考、抽象的な書き方を共に学んでいきましょう。

モジュール

今回はモジュールについて説明します。
下記リファクタリング前のコードはコンポジションで作られ、十分に使えるコードです。
今回は、インスタンスの処理をモジュール使ってすっきりさせましょう。
オブエジェクト指向実践ガイドの第8章 「コンポジションでオブジェクトを組み合わせる」、
この章を一部理解していると言えるでしょう。(残りの知識は別記事に書きます)

リファクタリング前

class Bicycle
  attr_reader :size, :parts

  def initialize(args = {})
    @size = args[:size]
    @parts = args[:parts]
  end
  def spares
    parts.spares
  end
end

class Parts
  attr_reader :parts

  def initialize(parts)
    @parts = parts
  end

  def spares
    parts.select{|part| part.needs_spare}
  end
end

class Part
  attr_reader :name, :description, :needs_spare

  def initialize(args)
    @name = args[:name]
    @description = args[:description]
    @needs_spare = args.fetch(:needs_spare,true)
  end
end
chain = Part.new(name: "chain",description: "10-speed")
road_tire =
  Part.new(name: "tire_size",description: "23")
tape =
  Part.new(name: "tape",description: "red")
mountain_tire =
  Part.new(name: "tire_size",description: "2.1")
rear_shock =
  Part.new(name: "rear_shock",description: "Foc")
front_shock =
  Part.new(name: "front_shock",
           description: "Manitou",
           needs_spare: false)
road_bike_parts =
  Parts.new([chain,road_tire,tape])
road_bike =
  Bicycle.new(
    size: "L",
    parts: road_bike_parts
  )
road_bike.size
road_bike.spares
mountain_bike_parts =
  Parts.new([chain,mountain_tire,front_shock,rear_shock])
mountain_bike =
  Bicycle.new(
    size: "L",
    parts: mountain_bike_parts
  )
mountain_bike.size
mountain_bike.spares

モジュールを用いる

chain = Part.new(name: "chain",description: "10-speed")
road_tire =
  Part.new(name: "tire_size",description: "23")
tape =
  Part.new(name: "tape",description: "red")

上記の処理をすっきりさせたいですね。
モジュールを使ってリファクタリングしてみましょう。

リファクタリング後

class Bicycle
  attr_reader :size, :parts

  def initialize(args = {})
    @size = args[:size]
    @parts = args[:parts]
  end
  def spares
    parts.spares
  end
end

class Parts
  attr_reader :parts

  def initialize(parts)
    @parts = parts
  end

  def spares
    parts.select{|part| part.needs_spare}
  end
end

class Part
  attr_reader :name, :description, :needs_spare

  def initialize(args)
    @name = args[:name]
    @description = args[:description]
    @needs_spare = args.fetch(:needs_spare,true)
  end
end
module PartsFactory
  def self.build(config,part_class = Part,parts_class = Parts)
    parts_class.new(
      config.collect{ |part_config|
        part_class.new(
          name: part_config[0],
          description: part_config[1],
          needs_spare: part_config.fetch(2,true)
        )
      }
    )
  end
end
road_config = [
  ["chain","10-speed"],
  ["tire_size","23"],
  ["tape_color","Fox"]
]
mountain_config =
  [
    ["chain","10-speed"],
    ["tire_size","Manitou",false ],
    ["rear_shock","Fox"]
  ]

road_bike =
  Bicycle.new(
    size: 'L',
    parts: PartsFactory.build(road_config)
  )
road_bike.spares
mountain_bike =
  Bicycle.new(
    size: "L",
    parts: PartsFactory.build(mountain_config)
  )
mountain_bike.spares

モジュール

モジュールを新たに作り、インスタンスの処理がすっきりしました。

注意点!!

PartsFactoryモジュールはまだ改善の余地はあります。(後日、別記事で書きます)

参考文献

オブエジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0