![見出し画像](https://assets.st-note.com/production/uploads/images/63916106/rectangle_large_type_2_c56dc54f6868cca4ce57f036d0359b81.jpeg?width=800)
Photo by
ongoing_teriha
【94】【Rails】リファクタリングトレーニング_ファクトリーを使う
この記事を読むと問題のあるコードや改善の余地があるコードを学び、リファクタリングする能力を養うことができます。
改善の余地があるコード
問題があるコードというわけではありません。
しかし、まだ改善の余地があります。
どの点を改善すべきか説明できますか?
そして、どのようにリファクタリングしますか?
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
テスト
require_relative '5_2_1_before_refactoring'
RSpec.describe "Bicycleモデル" do
chain = Part.new(name: "chain",description: "10-speed")
mount_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)
mountain_bike_parts =
Parts.new([chain,mount_tire,rear_shock,front_shock])
bike =
Bicycle.new(
size: "L",
parts: mountain_bike_parts
)
spares = bike.spares.map do |part|
{"#{part.name}".to_sym =>"#{part.description}"}
end
it '#spares' do
expect(spares).to eq [{:chain=>"10-speed"}, {:tire_size=>"2.1"}, {:rear_shock=>"Foc"}]
end
end
改善したい点
テストを見ると改善点が見えてきますね。
chain = Part.new(name: "chain",description: "10-speed")
mount_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)
これら一連のPartインスタンスの作成をもっとdryにできないでしょうか?
リファクタリング
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
テスト
require_relative '5_2_2_refactoring'
RSpec.describe "Bicycleモデル" do
mountain_config =
[
["chain","10-speed"],
["tire_size","Manitou",false ],
["rear_shock","Fox"]
]
mountain_bike =
Bicycle.new(
size: "L",
parts: PartsFactory.build(mountain_config)
)
spares = mountain_bike.spares.map do |part|
{"#{part.name}".to_sym =>"#{part.description}"}
end
it '#spares' do
expect(spares).to eq [{:chain=>"10-speed"}, {:rear_shock=>"Fox"}]
end
end
ポイント
partを生成するモジュールを作りました。
このモジュールによって、
[
["chain","10-speed"],
["tire_size","Manitou",false ],
["rear_shock","Fox"]
]
という形で受け取ることができます。
このような、オブジェクトを作成するオブジェクトをファクトリーといいます。
注意点!
リファクタリング後のコードが完全な形になっていっているわけではありません。前よりかは良くなったと捉えてください。
関連する記事
参考文献
オブジェクト指向設計実践ガイド
~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
最後に
私がブログを書く目的は、素晴らしい本や、素晴らしい方々の技術記事を知って頂きたいからです。ぜひ、上記の参考文献を見て下さい。(noteなので広告とかは一切ありません。)
現在、株式会社grabssに行くために最後の悪あがきをしています!!
現在の進行状況
この記事は94件目の投稿。目標達成!!!!
目標再設定
20日までに100件目指す!!(94件目)
20日超えたが、寝るまでは20日営業日!!(まだ寝てない、ちょっと寝##峠を超え目が覚めた!)
気持ちは20日!
よろしければ、スキボタン及びサポートお願いします。勉強の励みになります。
この記事が気に入ったらサポートをしてみませんか?