Don’t confuse DIP, IoC, and DI together. They are all different but related.

DIP (or Dependency Inversion Principle) is one of the principles of SOLID.  SOLID stands for:

  • Single responsibility – a class should only have one responsibility
  • Open / closed principle – a class should be open for extension but closed for modification
  • Liskov substitution principle – a class should be replaceable without altering the functionality of the whole
  • Interface segregation principle – better to have more specific interfaces than a general purpose one
  • Dependency inversion principle – a higher-level class should never depend on a lower-level class, instead higher-level class should define an abstraction that lower-level class should depend on

IoC (or Inversion of Control) is a paradigm that adheres to the dependency inversion principle by inverting the control to avoid dependencies.  Most inversions can be generalized into these three types of control:

  • Control over interface – consumer class should have control over the interface and provider classes should depend on that interface
  • Control over flow – a “don’t call us, we’ll call you” paradigm
  • Control over creation – where creating objects is done outside of the class they are being used in

DI (or Dependency Injection) is one way of inverting control over creation (other ways being the factory method and the service locator).  It moves the creation and binding of a dependency outside of the class that depends on it.  Common types of dependency injection:

  • Constructor injection
  • Setter injection
  • Interface injection

 

Additional Resources:

Advertisements

Design Patterns: Factory Method, Abstract Factory, and Singleton

Back again with design patterns, defining them briefly and the design principles they are based on, and providing several very good (almost) real-world C# examples that are available on the Internet.  In this series we have the factory patterns and the singleton pattern and their several different implementations.

 

Design Pattern #4: Factory Method Pattern

  • Defines an interface for creating an object but lets subclasses decide which class to instantiate.  It lets a class defer instantiation to the subclasses.
  • Design Principle:
    • Design Principle #6 :  Depend on abstraction.  Do not depend on concrete classes.
  • C# Examples:
    • An online bookstore application using multiple distributors to send books to its customers.  This example uses the parameterized factory implementation or the procedural solution/basic noob implementation, wherein the bookstore factory receives the customer location to determine which distributor to choose from.
      Product IDistributor
      ConcreteProduct EastCoastDistributor, MidwestDistributor, WestCoastDistributor
      Creator IBookStore; with abstract method GetDistributor()
      ConcreteCreator BookStoreA
    • A lodging inquiry system wherein a customer can get details of different types of available rooms.  This example also shows the registration with reflection implementation, the self registration without reflection implementation and the self registration with reflection implementation.  It is actually using a factory pattern, a pattern that is the basis for the factory method pattern and the abstract factory pattern. The only difference between the factory pattern and the factory method pattern is in the creator. The factory method pattern requires an abstract class which defines the interface for several factories, thus abstracting the client from both the type of product and type of factory used to create the product.
      Product IRoomType
      ConcreteProduct ACRoom, DeluxeRoom, NonACRoom
      Creator
      ConcreteCreator RoomFactory; concrete class with concrete method GetRoomType()

 

Design Pattern #5: Abstract Factory Pattern

  • Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
  • Design Principle:
    • Same as the factory method pattern, it follows the Design Principle #6.
  • C# Examples:
    • A drawing and printing machine that can process low and high resolution.  This can be extended to process medium resolution by creating a medium resolution factory that provides the medium resolution display and print drivers.
      AbstractFactory ResFactory; with abstract methods getDispDrvr() and getPrtDrvr()
      ConcreteFactory LowResFact, HighResFact
      AbstractProduct DisplayDriver, PrintDriver
      ConcreteProduct LowDisplayDriver, HighDisplayDriver, LowPrintDriver, HighPrintDriver
      Client ApControl
    • An audio/video device object providing access to it’s audio and video properties.  Again this can be extended to include Bluray by creating a Bluray object that exposes Bluray audio and video objects.
      AbstractFactory IAVDevice; with abstract methods GetAudio() and GetVideo()
      ConcreteFactory CCd, CDvd
      AbstractProduct IAudio, IVideo
      ConcreteProduct CCdAudio, CDvdAudio, CCdVideo, CDvdVideo
      Client CAVMaker
    • An example using employee and customer factories that provides personal information.  This example shows the dependency injection implementation and the inversion of control container implementation.  These types of implementations, factory pattern, dependency injection, and inversion of control container, are all techniques to implement inversion of control, a programming technique in which object coupling is bound at run time and is typically not known at compile time.  I will talk more about inversion of control on a separate post, as this I think, is a hot topic too in the object oriented programming world.
      AbstractFactory IPersonAbstractFactory
      ConcreteFactory EmployeeFactory, CustomerFactory
      AbstractProduct IPerson
      ConcreteProduct Employee, Customer
      Client MySample

 

Design Pattern #6: Singleton Pattern

  • Ensures a class only has one instance and provides a global point of access to it
  • C# Examples:
    • Singleton implementations from MSDN.  It shows 3 implementations: the basic implementation, the static initialization implementation, and the multithreaded or double-check locking implementation.

     

    • Singleton implementations from the book C# In Depth.  It shows 6 implementations:
      • basic implementation that is not thread-safe
      • simple thread-safe implementation using a lock
      • attempted thread-safe using double-check locking implementation
      • static initialization implementation that is thread-safe without using locks but not quite as lazy

       

      • full lazy static initialization implementation
      public sealed class Singleton
      {
      private Singleton()
      {
      }

      public static Singleton Instance { get { return Nested.instance; } }

      private class Nested
      {
      // Explicit static constructor to tell C# compiler
      // not to mark type as beforefieldinit
      static Nested()
      {
      }

      internal static readonly Singleton instance = new Singleton();
      }
      }

       

      • C# 4.0’s Lazy<T> static initialization implementation
      public sealed class Singleton
      {
      private static readonly Lazy<Singleton> lazy =
      new Lazy<Singleton>(() => new Singleton());

      public static Singleton Instance { get { return lazy.Value; } }

      private Singleton()
      {
      }
      }

* This is the second in the Design Patterns series.  The first one is Design Patterns: Strategy, Observer, and Decorator.

Design Patterns: Strategy, Observer, and Decorator

Here and in the next posts, I will talk about design patterns, it’s definition, the guiding design principles they embody, and their C# examples.  But before you dive into design patterns, here is a refresher on four OO basics.

 

Design Pattern #1: Strategy Pattern

  • Defines a family of algorigthms, encapsulates each one, and makes them interchangeable.  It lets the algorithm vary independently from clients that use it.
  • Design Principles:
    • Design Principle #1 : Separate code that change from code that stays the same
    • Design Principle #2 : Program to an interface and not to an implementation
    • Design Principle #3 : Favor composition (HAS-A) over inheritance (IS-A)
      • Note: To implement composition, a class will have an interface type reference to a concrete implementation that is usually initialized during the class constructor

 

Design Pattern #2: Observer Pattern

  • Defines a one-to-many dependency between objects so that  when one object changes state, all of its dependents are notified and  updated automatically.  A good example is a newspaper publisher and its  subscribers.
  • Design Principles:
    • Design Principle #4 : Strive for loosely coupled designs between objects that interact

 

Design Pattern #3: Decorator Pattern

  • Attaches additional responsibilities to an object dynamically.  Decorators provide a flexible alternative to sub-classing for extending functionality.  It does this by using composition and delegation.  Decorator classes have same types as the components they decorate, either through inheritance or interface implementation.  They add behavior by adding new functionality before and/or after method calls to the component.
  • Design Principles:
    • Design Principle #5 : Classes should be open for extension but closed for modification

Design Patterns: The Four OO Basics

Before going into design patterns, one must need to know the four OO basics:

  • Abstraction is showing only the necessary details to the outside world. It is the abstract form of anything. It is implemented using interface and abstract class.
  • Encapsulation is hiding the details from the outside world. It is the opposite of abstraction. It is implemented using private and protected access modifiers inside a class.
  • Inheritance is a way for an entity to inherit the characteristics of another entity, thus establishing a parent-child relationship, or in a more technical OO term, an IS-A relationship. It is implemented using base and derived classes.

Design Patterns: Fundamentals

Fundamental design patterns are divided into 3 categories:

EDIT: The above patterns are called the 23 Gang of Four (GoF) patterns.  More information can be found from this link.  The site provides a description, a UML class diagram and C# code as well.