Hollywood Principle
Pawel Pierzchala
@zwrozka
DRUG 20.05.2013
- intro
- krug/sckrk/railsgirls
- Hollywood Principle -> Dependency Injection
- dependor
- maly railsowy projekt bez DI
People
class PeopleController
def create
person_repository.add(params)
end
private
def person_repository
PersonRepository.new(current_trip)
end
end
- izolacja od bazy
- repozytoria tworzone manualnie w kontrolerze
Rooms
yet another resource
Room reservations
class RoomAssignmentsController
def create
room_assignments.add(params)
end
private
def room_assignments
RoomAssignments.new(person_repository, room_repository)
end
end
- na tyle wazna abstrakcja, ze zasluguje na wlasne repo
- zalezy od person i room repo
- decyzja o wszyskiwaniu przez konstruktor = HP
Hollywood Principle
don't call us, we'll call you
- kod oczekuje zaleznosci, a nie je tworzy
- metafora IoC
Inversion of Control
Dependency Injection
- mozna odwrocic kontrole nad zaleznosciami i kontrola w programi
- nad zaleznosciami = DI
Benefits
- replacabilty
- testability
- isolated tests
- niczego nie zamienialismy
- poprawia testowanie, ale nie az tak w jak w Javie/C#
- stabilnosc testow w izolacji
- to bylo reczne DI
Dependency Injection
def person_repository(current_trip)
PersonRepository.new(current_trip)
end
def room_assignments
RoomAssignments.new(person_repository, room_repository)
end
# noop
- do tego momentu tworzylismy wszystkie zaleznosci recznie
- ten kod jest dosyc powtarzalny
- chcialbym zeby go nie bylo
- odrobina meta programowania
- convention over configuration
almost noop
class Injector
include Dependor::AutoInject
attr_reader :current_trip
def initalize(current_trip)
@current_trip = current_trip
end
end
- jedyny problem to glebokie zaleznosci
- wlasciwie Injector jest rozwiazaniem tego problemu
- zmienilismy sposob tworzenia, musi zmienic sie kontroler
Entry points
def room_assignments
RoomAssignments.new(person_repository, room_repository)
end
def room_assignments
Injector.new(current_trip).room_assignments
end
inject :room_assignments
- nie mamy pelnej wladzy na kontrolerem
- nie mozemy wstrzykiwac przez kontroler -> definiujemy metode ktora tworzy Injector
- znow powtarzamy sie
a little bit of config
class ApplicationController
extend Dependor::Injectable
def injector
Injector.new(current_trip)
end
end
- nalezy podac zaleznosci ktore nie sa tworzone automatycznie
Constructors
class RoomAssignments
def initalize(person_repository, rooms_repository)
@person_repository = person_repository
@room_repository = room_repository
end
private
attr_reader :person_repository, :room_repository
end
class RoomAssignments
takes :person_repository, :room_repository
end
- duuuzo kodu na 2 zaleznosci
- skraca i sprawia, ze zaleznosci sa widoczne
- warto wspomniec o tym, ze usuwa zaleznosc od kolejnosci
Summary
- dependor on github
- makes dependecies visible
- loose coupling always helps with testing
- helps with deep dependencies
- emphasies composability