javac#oopdesign-patternsinversion-of-control

Is the definition of "inversion of control" on wikipedia correct?


inversion of control (IoC) is a design principle in which custom-written portions of a computer program receive the flow of control from a generic framework.

The framework can be Java Spring Framework but we can also implement the inversion of control using:

So why the definition of inversion of control on wikipedia is limited to a framework?


Solution

  • "Is the definition of "inversion of control" on wikipedia correct?"

    Yes, it is.

    First of all, your list contains design patterns. A design pattern can't be a framework (because you were annotating your list with remarks that e.g. Factory pattern is not a framework to prove that the Wikipedia article is wrong). Of course, design patterns are not frameworks. And design patterns are not "implementations" of IoC. Frameworks use these design patterns to implement IoC.

    The definition of a framework is clear. As you are using Wikipedia as a source, you can also use Wikipedia to lookup how it describes a framework:

    "In computer programming, a software framework is an abstraction in which software, providing generic functionality, can be selectively changed by additional user-written code, thus providing application-specific software." Wikipedia

    Now with this definition we can answer your question:

    "So why the definition of inversion of control on wikipedia is limited to a framework?"

    We have to differentiate between IoC and Dependency Inversion.
    Writing code that depends on abstractions is following the Dependenc Inversion principle. It's not IoC.
    Instantiating and injecting an implementation of an abstract type and managing the lifetime of that instance is Dependency Injection but still not IoC.
    However, if the component that implements Dependency Inversion (to decouple client code from internal code) qualifies as a framework, in that it encapsulates generic functionality and behavior which is extensible via external code that is pre-defined as abstractions (Dependency Inversion) and invoked by that framework, then we call it IoC. That's simply the definition.
    IoC is a special case of Dependency Inversion in that it focuses on the dependency between a library and its clients.

    In other words, to make a library extensible with client code (i.e. modification or specialization of selective generic predefined functionality), we need to invert the control of the flow between components (client and library). Remember, a library is always called by client code: the control flow is from client to library. The idea of inverting this control flow is called IoC.
    A library that has its control flow inverted, is called a framework. That means, IoC is not limited to frameworks, frameworks are the result of applied IoC.

    A framework is a special form of a library (a collection of reusable functionalities and behaviors and other kinds of resources).
    The main characteristic is that a framework implements design patterns to realize the Inversion of Control (IoC) principle. The control flow is reversed in that the specialized and extending code (client code, high-level code) is no longer calling the library code (low-level code). Instead, the framework calls the client code (low-level code calls high-level code). This should highlight that the focus is on controlling functionality and not dependencies.

    The focus of IoC is on the extension of an encapsulated generic functionality/behavior where the low-level framework code calls high-level client code. The goal of IoC is not decoupling, although frameworks need to decouple their internals from externals.
    The goal is the efficient extensibility and specializatrion of existing generic functionality/behavior.

    All of your mentioned design patterns effectively help to invert the control of the flow or the caller callee relationship. However, implementing those design patterns like Dependency Injection alone doesn't make a library qualify as a framework.

    You have (a) the generic functionality that can be (b) extended and specialized by plugging in custom/external code and that (c) does not need and allow modification in order to be extended/call client code. Following this definition, a framework can be a single class or thousands of classes. It depends on the functionality it provides.

    A simple class that executes an operation on two operands (like a calculator) would also qualify as a framework, where you extend the functionality by providing the actual operations that the framework (the calculator) then executes (IoC). This calculator would create the expression trees and implement and ensure arithmetic rules, provide a history or undo/redo behavior etc. - the generic calculator functionality.
    You now have a small calculator framework: "[...] generic functionality, [that] can be selectively changed by additional user-written code.", because of the inversion of the control flow (IoC).

    Frameworks are nothing magical. They are just implementations of IoC. IoC is usually achieved by implementing certain design patterns. In other words, if you are able to implement IoC, you are always having a set of functionalities that qualify as a library. A library that applies IoC is a framework:

    Frameworks have key distinguishing features that separate them from normal libraries:

    • inversion of control: In a framework, unlike in libraries or in standard user applications, the overall program's flow of control is not dictated by the caller, but by the framework. This is usually achieved with the Template Method Pattern.
    • default behavior [qualifies a library]: This can be provided with the invariant methods of the Template Method Pattern in an abstract class which is provided by the framework.
    • extensibility: A user can extend the framework–usually by selective overriding–or programmers can add specialized user code to provide specific functionality. This is usually achieved by a hook method in a subclass that overrides a template method in the superclass.
    • non-modifiable framework code: The framework code, in general, is not supposed to be modified, while accepting user-implemented extensions. In other words, users can extend the framework, but cannot modify its code.

    Wikipedia