Confusion between Inversion of Control and Hollywood Principle
Asked Answered
A

5

9

I am reading Head First Design pattern and just stuck on the Hollywood Principle. Earlier I read about Inversion of Control and what I understood was, it's a design principle (some also call it pattern) through which conventional flow of program changes from "Higher level module calling Lower level module" to "Lower level module calling Higher level module" (generally through abstractions), so we can have very low dependency on specific low-level module and changing low-level modules does not have any impact on our higher level or near to business modules.

But I got confused when the author said the following line regarding the Hollywood principle:-

On page 296

With the Hollywood Principle, we allow low-level components to hook themselves into a system, but the high-level components determine when they are needed, and how. In other words, the high-level components give the low-level components a “don’t call us, we’ll call you” treatment.

In the last line, it is said that The high-level components give the low-level components a “don’t call us, we’ll call you” treatment. This means our high-level components are actually calling low-level components and hence this seems to break the Inversion of control principle and also Dependency Inversion principle.

Please clarify on this.

Archy answered 4/5, 2017 at 14:50 Comment(3)
Why do you think the Inversion of Control is used here in the first place? The only way you could say it is is that the lowlevelcomponent (llc) is allowed to register with the hlc. Other than that all activity (ie full control) remains with the hlc.Superstructure
@Superstructure You are restricting Inversion of Control to Event based programming (Observer pattern), But we can also achieve it through, say, Dependency Injection.Archy
@Taw When you are writing an application and using say Windows framework for getting an event through UI and according to your comment " the lowlevelcomponent (llc) is allowed to register with the hlc." According to your definition as our application is registering with windows framework it is lowlevelcomponent(llc) and windows framework is hlc which is completely wrong and should be in opposite order (our application is hlc here).Archy
J
3

The seeming contradiction is cleared up if we focus on a different part of the Dependency Inversion Principle:

A. High level modules should not depend on low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.

That adds some context that clears up the potential confusion created by this statement:

The high-level components give the low-level components a “don’t call us, we’ll call you” treatment.

The high-level components don't directly deal with the low-level components at all. They deal with abstractions that represent the purpose or function of the low-level components.

So it doesn't "break" the Dependency Inversion Principle. Rather, it just needs to be understood in harmony with that principle. They are two different principles, so we could apply one and break the other. But if components communicate with each other as represented by abstractions then we can apply both.

They could have added that clarification into the sentence in question, but it would have made it wordier and more confusing.


FWIW I often find the terms "high level" and "low level" confusing because we don't tend to use them except when discussing the Dependency Inversion Principle. Whether a component is "high level" or "low level" the recommendation is to depend on abstractions. In other words, depend on abstractions. We can apply the principle without classifying components as high level or low level.

Judgment answered 3/6, 2019 at 17:29 Comment(0)
S
1

When we design software we implement two things API and Framework.

An API publish some endpoint so that caller uses those endpoints to get some useful information, so the caller doesn't have any action point to take, only endpoints and outputs.

The framework takes the strategy or business implementation from the caller and calls it when required.

In Hollywood Principle, we can feed our strategy or business implementation, denoting the framework implementation, which calls the fed strategy when required.

Inversion of control and Dependency Injection is to remove dependencies of an application. This makes the system more decoupled and maintainable.

If you go back to old computer programming days, program flow used to run in its own control.

if you analyze the program flow closely, it’s sequential. The program is in control of himself. Inversion of the control means the program delegates control to someone else who will drive the flow.

Superiority answered 20/2, 2019 at 6:28 Comment(0)
W
1
class Customer {
   
   public function getCustomers() {
      $conn = new MySQLConnection();
      return $conn->getCustomers();
   }
   
   public function iocCustomers(MySQLConnection $conn) {
      return $conn->getCustomers();
   }
}

In the case of getCustomers(), we are creating the Database object inside Customer classes function - deeply coupled. Whenever the Customer object is created, the MySQLConnection object also will be created, which is not required.

If you consider the iocCustomers(), when we call the function we are passing the Database object as well. Here the Customer class is not concerned about the database till it need the data, it will use it when it required. Like, you no need to be in Hollywood to get a chance, when you needed they will call you, like, MySQLConnection object is injected to the function where it required by the class Customer.

Here two things are happening.

  1. Customer class no need to worry/know about who provides the data. In other words, the client/calling class Customer doesn't have control over the data. [SRP in SOLID principles]

  2. The connection object gets the control over the data and it can decide from which database(MySQL or SQLite) it need to provide data. If we create the object MySQLConnection in the getCustomers(), it will not get the flexibility to switch. This is called Inversion of Control. Taking the control from the caller to the class who generates the data.

Note: In the case of second function there are some advantages.

We can pass an interface called DBConnectionContract to iocCustomers() instead of MySQLConnection. So that we can pass any database object(MySQL, Sqlite, Postgres) which implements DBConnectionContract interface. This will help us to switch the database to one another with minimum modifications.

Modifications can be like below:

interface DBConnectionContract {}
class MySQLConnection implements DBConnectionContract {}
class SQLiteConnection implements DBConnectionContract {}
class Customer {
   public function iocCustomers(DBConnectionContract $conn) {}
}

Another advantage is related to Unit testing. To the iocCustomers() we can pass mock database object while unit testing. Because to do the unit test of a function we need to make the environment needed for that function to execute.

Waterlog answered 12/9, 2021 at 7:24 Comment(0)
D
0

The Hollywood Principle is not at odds with the Inversion of Control, although it can be programmed ignoring it.

In the book the Coffee example (I guess one page later, I have another edition) sub-classes two methods that get called via the Hollywood Principle. If the sub-classes just overwrites some abstract methods from the base class it does not really uses the Inversion of Control.

However since the called sub-class can adjust members of the base class it can take control that way. In the Q and A in my book one page earlier it explains a bit in the question: What are hooks really supposed to be used for. I will try to explain.

Say if you have a base class with an unsorted list and a call to print() the list. If you have a sub-class which via a hook can be called to overwrite print() that sub-class might decide to first sort the actual list of the base class and than call other functions if needed. In this way the low level function can take over control from the high level function.

Diaphone answered 4/5, 2017 at 20:46 Comment(4)
So you are restricting Hollywood principle to subclassing and overriding but it's not true, see the example of CompareTo method in the Array static class which author also explained.Archy
I have seen in many places Hollywood principle is stated as another name to Inversion of Principle, what about that?Archy
You are right with your first comment, it was a more basic example where the hook is done via sub classing. You can also implement events or callback objects as the hooks and implement a lot more control in the lower level class.Diaphone
Maybe it is semantics which are used the same, but with Inversion of Control I personally think more of what a class should be responsible for, while with the the Hollywood principle I think more of how the control is given to other classes. Although wikki states: Inversion of control is sometimes facetiously referred to as the "Hollywood Principle: Don't call us, we'll call you".Diaphone
P
0

IoC is sometimes referred to as the Hollywood Principle. They are the same... but, like all idiomatic expressions, it is always subject to semantics. The principle of controlling low-level dependencies from higher level abstractions is not "a pattern", it is a principle. It is also not exemplified well by associating that principle solely with sub-classing, though there it does most naturally exist.

More commonly it is accomplished through composition/aggregation by holding a reference to some Interface or abstract type in a low-level object and injecting dependencies into that class. It has no control or responsibility for what it receives, it only knows how to process it.

In other words, it (low-level) must wait by the phone, rather than call for its next screening, audition? what ever they call that in Hollywood.

P answered 14/5, 2017 at 23:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.