These rules are easier to understand in languages where variables are
typed. Example in Java:
class OrderProcessor {
private VisaPaymentService paymentService;
public OrderProcessor() {
this.paymentService = new VisaPaymentService();
}
public processOrder() {
paymentService.charge(amount);
}
}
In this example, the OrderProcessor depends on a VisaPaymentService.
This means that it depends on a low level module, or an implementation
detail. It would be much better to have OrderProcessor depend on an
abstraction, for example a generic PaymentService (receiving it from
the outside):
class OrderProcessor {
private PaymentService paymentService;
public OrderProcessor(PaymentService paymentService) {
this.paymentService = paymentService;
}
public processOrder() {
paymentService.charge(amount);
}
}
PaymentService could be an interface with several implementations like
VisaPaymentService, PaypalPaymentService, etc. Now, OrderProcessor
depends on an abstraction and so it's easier to change.
When you apply this to Ruby, where there's no need to predefine
interfaces but we rely on duck-typing, this example is just easily
solved:
class OrderProcessor
def initialize payment_service
@payment_service = payment_service
end
def process_order
@payment_service.charge amount
end
end
The not-solid (liquid? :)) example in Ruby would be:
class OrderProcessor
def initialize
@payment_service = VisaPaymentService.new
end
def process_order
@payment_service.charge amount
end
end
As the blog article explains, don't confuse DIP with Dependency
Injection, which is a technique to implement DIP. As you see here, we
remove the construction of the VisaPaymentService from inside the
OrderProcessor class, and receive the object from the outside: the
outside injects the dependency into the OrderProcessor.
In Java, you could have dependency injection and not achieve DIP, if
you expected a VisaPaymentProcessor inside the class. In Ruby, as the
instance variable is not typed, DI pretty much achieves DIP.
Jesus.
···
On Tue, Feb 24, 2015 at 11:03 AM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:
Hi,
Can any body help me to understand, how one can use DIP from S.O.L.I.D
in Ruby. I didn't find a Ruby implementation for this.
A. High-level modules should not depend on low-level modules. Both
should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on
abstractions.
I got one http://blog.siyelo.com/solid-principles-in-ruby/ .
From this blog example -
(1) Which one is High and Low level module I didn't get.
(2) Point B from wikipedia really nothing I got there.
Please someone help me to understand how this principal works, or in
Ruby how far this principal is truly implementable.