Inżynieria oprogramowania

Odwrócenie sterowania

Odwrócenie sterowania (ang. Inversion of Control -IoC) jest sposobem budowania architektury w systemach obiektowych. Czasami uznawane jest za paradygmat albo wzorzec projektowy i utożsamiane ze wstrzykiwaniem zależności.



Zasada Hollywood


Najprostszą metodą opisu IoC jest odwołanie się do tzw. "Zasady Hollywood", która brzmi:

Nie dzwoń do nas. My oddzwonimy do ciebie


Oznacza ona, że każdy z modułów aplikacji nie interesuje się tym skąd przychodzą żądania i dokąd kierowane są odpowiedzi. Wykonuje tylko postawione przed nim zadanie.

Porównanie z modelem tradycyjnym


W tradycyjnie pisanym programie można odnaleźć centralny punkt zajmujący się sterowaniem przepływem. Uruchamia on kolejne fragmenty kodu sztywno przestrzegając kolejności oraz zasad przepływu sterowania.
Program napisany  z wykorzystaniem IoC składać będzie się ze zbioru niezależnych modułów - klas porozumiewających się poprzez interfejsy lecz niezależnych od konkretnej implementacji. Zarządzanie przepływem jest zdecentralizowane, a każdy z elementów oczekuje na wywołanie jego metod. Przykładowy program1 zrealizowany w tradycyjnym modelu (ruby):
  #ruby
  puts 'What is your name?'
  name = gets
  process_name(name)
  puts 'What is your quest?'
  quest = gets
  process_quest(quest)

Oraz z wykorzystaniem zasady IoC:
  require 'tk'
  root = TkRoot.new()
  name_label = TkLabel.new() {text "What is Your Name?"}
  name_label.pack
  name = TkEntry.new(root).pack
  name.bind("FocusOut") {process_name(name)}
  quest_label = TkLabel.new() {text "What is Your Quest?"}
  quest_label.pack
  quest = TkEntry.new(root).pack
  quest.bind("FocusOut") {process_quest(quest)}
  Tk.mainloop()

Doskonale widać tu różnicę w obu podejściach. W pierwszym przypadku przepływ jest wymuszony i kontrolowany przez "program centralny"(tu skrypt ruby). W drugim po stworzeniu modułów sterowanie jest oddawane na zewnątrz (tu do Tk.mainloop.

IoC, a wstrzykiwanie zależności


Mówiąc w duchu IoC powinniśmy mówić, że nie tyle IoC ma się do wstrzykiwania zależności, co wstrzykiwanie zależności jest specyficzną implementacją IoC. Wstrzykiwanie zależności zostało z czasem utożsamione z IoC i obecnie jest najpopularniejszą implementacją IoC.

Wady i zalety


IoC ma kilka wad, które powinny być brane przed skorzystaniem z tego modelu.

  • kod zaczyna być rozproszony co może prowadzić do jego znacznego rozdrobnienia.
  • tracimy kontrolę nad wywoływanymi metodami - wywołujemy interfejsy. Może to doprowadzić do nieprzewidzianych sytuacji gdy chcemy np. rzutować obiekt (a korzystamy z obiektu Proxy).
  • wszystkie wady związane ze wstrzykiwaniem zależności.

IoC  ma też kilka niezaprzeczalnych zalet.

  • Wymusza organizację kodu w małe klasy o dobrze określonych zadaniach.
  • Ułatwia tworzenie luźno powiązanego kodu.
  • Ułatwia tworzenie kodu łatwego w testowaniu. Promuje metodyki zwinne oparte o TDD.

Podejmując decyzję o zastosowaniu IoC należy wziąć pod uwagę nie tylko opłacalność wykorzystania tego modelu, ale też m.n. to czy nasz projekt poprowadzony w oparciu o ten model nie będzie zbyt skomplikowany.

[1] przykład zaczerpnięty z artykułu Martina Fowlera InversionOfControl - http://martinfowler.com/bliki/InversionOfControl.html