아래의 코드 기반으로 변경해 보면서 의존성을 이해해보자
# chainring(앞 톱니수), cog(뒷 톱니수), rim(바퀴테 지름), tire(타이어 높이)
# ratio(기어비)
class Gear
attr_reader :chainring, :cog, :rim, :tire
def initialize(chainring, cog, rim, tire)
@chainring = chainring
@cog = cog
@rim = rim
@tire = tire
end
def ratio
chainring / cog.to_f
end
def gear_inches
ratio * Wheel.new(rim, tire).diameter
end
end
class Wheel
attr_reader :rim, :tire
def initialize(rim, tire)
@rim = rim
@tire = tire
end
def diameter
rim + (tire * 2)
end
def circumference
diameter * Math::PI
end
end
puts Gear.new(52, 11, 26, 1.5).gear_inches
Gear class안에서 Wheel class를 선언하고 사용하기 때문에 Gear는 Wheel에 대해 모두 알아야 해서 결합도가 높다. Gear는 Wheel class의 diameter method만 필요하므로 Wheel class의 선언을 바깥에서 하고 Gear로 주입할 수 있도록 변경하면 Gear는 Wheel자체는 몰라도 되고 diameter만 알아도 되기 때문에 결합도를 낮춰 의존성을 줄일 수 있다.
# chainring(앞 톱니수), cog(뒷 톱니수), rim(바퀴테 지름), tire(타이어 높이)
# ratio(기어비)
class Gear
attr_reader :chainring, :cog, :rim, :tire
def initialize(chainring, cog, rim, tire)
@chainring = chainring
@cog = cog
@rim = rim
@tire = tire
end
def ratio
chainring / cog.to_f
end
def gear_inches
ratio * Wheel.new(rim, tire).diameter
end
end
class Wheel
attr_reader :rim, :tire
def initialize(rim, tire)
@rim = rim
@tire = tire
end
def diameter
rim + (tire * 2)
end
def circumference
diameter * Math::PI
end
end
# 인스턴스 생성을 격리 시키기
class Gear
attr_reader :chainring, :cog, :rim, :tire
def initialize(chainring, cog, rim, tire)
@chainring = chainring
@cog = cog
@rim = rim
@tire = tire
end
def gear_inches
ratio * wheel.diameter
end
...
# 정의된 wheel method를 통해 인스턴스 만들기
class Gear
attr_reader :chainring, :cog, :rim, :tire
def initialize(chainring, cog, rim, tire)
@chainring = chainring
@cog = cog
@wheel = Wheel.new(rim, tire)
end
def gear_inches
ratio * wheel.diameter
end
def wheel
@wheel ||= Wheel.new(rim, tire)
end
...
# 의존성을 클래스 내부의 메서드 속에 캡슐화시켜 놓기
def gear_inches
ratio * diameter
end
def diameter
wheel.diameter
end
해시를 통하여 인자를 넘긴다.
팩토리는 다른 객체를 만들기 위해 존재하는 객체이다. 팩토리는 다른 클래스의 인스턴스를 생성하기 위해서만 존재한다.
자기 자신보다 덜 변하는 것들에 의존하라