locked
Why is interface loosely coupled? RRS feed

  • Question

  • User339993961 posted

    Why is interface loosely coupled?

    Why are classes called as tightly coupled?

    For example:

    We have a requirement in such a way that we need to get data from different data sources.

    -- From Files.

    -- From XML,

    -- From some other data sources.

    We took an interface for our convinience as

    interface iRetrive

    {

        void getData();

    }

    Now we will implement this in different classes.

    My doubt here is.., Even if we take an interface, we are still implementing in different classes like below

    public FileClass: iRetrieve

    {

    void getData()

      {

      }

    }

    public XmlClass: iRetrieve

    {

      void getData()

      {

    }

    }

    Why cant we just write everything in differnt classes itself(without writing an interface) like below..

    public FileClass

    {

      void getData()

    {

      }

    }

    public XmlClass

    {

    void getData()

      {

      }

    }

     

    Tuesday, September 9, 2014 1:41 AM

Answers

  • User-821857111 posted

    The code that calls the getData method doesn't have to know which type of data source it is dealing with. If it did, it would be tightly coupled to that type. Instead, it will call getData against the interface, not a concrete type. That way, it has no dependency on a specific implementation. You can use configuration (dependency injection) to change the implementation (perhaps to a FakeClass that implements the interface during testing) without having to change anything in the calling code.

    public class SomeClass
    {
        private iRetrieve _dataSource;
    
        public SomeClass(iRetrieve dataSource){
            _dataSource = dataSource;
        }
       
        public void SomeMethod()
        {
            _dataSource.getData();
        }
    }

    The dataSource type is injected via the constructor. All dependency injection containers support doing this. As part of the DI configuration, you tell it to swap iRetrieve instances for a concrete type. SomeClass has no dependency on any concrete type. It is not tightly coupled to a concrete type. It is loosely coupled.


        

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 9, 2014 2:26 AM
  • User-821857111 posted

    Testing against data sources can be very slow. Therefore you usually test against Fakes. However, you don;t want to have to change the code in the class under test (SomeClass) to use a Fake datasource each time you run the tests. That can be tedious and you have to change it back again. If you are testing loads of classes that use a data source, it can take some time to change the data source in the classes. Therefore you are unlikely to do it, and unlikely to run the tests. That makes them pointless. 

    Notice that SomeClass in the example I provided earlier doesn't refer to a specific data source. It only refers to an interface. The actual data source is provided at runtime via dependency injection. You only need one entry in a DI container's configuration to specify the actual type. If you were using Ninject as your DI container, the configuration might look like this:

    ioc.Bind<iRetrive>().To<XmlClass>();

    You set that up in one place and it runs on application start-up. Everywhere that iRetrive is specified, XmlClass will be used. In your test project, you have a different configuration:

    ioc.Bind<iRetrive>().To<FakeClass>();

    Now all the classes that programme against iRetrive will use FakeClass instead. But the code in the classes under test does not change. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 9, 2014 3:34 AM

All replies

  • User-821857111 posted

    The code that calls the getData method doesn't have to know which type of data source it is dealing with. If it did, it would be tightly coupled to that type. Instead, it will call getData against the interface, not a concrete type. That way, it has no dependency on a specific implementation. You can use configuration (dependency injection) to change the implementation (perhaps to a FakeClass that implements the interface during testing) without having to change anything in the calling code.

    public class SomeClass
    {
        private iRetrieve _dataSource;
    
        public SomeClass(iRetrieve dataSource){
            _dataSource = dataSource;
        }
       
        public void SomeMethod()
        {
            _dataSource.getData();
        }
    }

    The dataSource type is injected via the constructor. All dependency injection containers support doing this. As part of the DI configuration, you tell it to swap iRetrieve instances for a concrete type. SomeClass has no dependency on any concrete type. It is not tightly coupled to a concrete type. It is loosely coupled.


        

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 9, 2014 2:26 AM
  • User339993961 posted

    I am not able to understand the difference yet.

    Can you please elaborate a bit more.

    Please.

    Its been some years that this doubt is not getting clear.

    Tuesday, September 9, 2014 3:01 AM
  • User339993961 posted

    Imean, what are the things to be considered at the time of oject creation?

    Tuesday, September 9, 2014 3:02 AM
  • User339993961 posted

    Or please give me any real time implementation with code.

    So that I can understand in a better way.

    Tuesday, September 9, 2014 3:04 AM
  • User-821857111 posted

    I can't explain it in a different way. I don't understand what you don't understand.

    Tuesday, September 9, 2014 3:14 AM
  • User339993961 posted

    How is testing easy with the use of interfaces?

    Tuesday, September 9, 2014 3:18 AM
  • User-821857111 posted

    Testing against data sources can be very slow. Therefore you usually test against Fakes. However, you don;t want to have to change the code in the class under test (SomeClass) to use a Fake datasource each time you run the tests. That can be tedious and you have to change it back again. If you are testing loads of classes that use a data source, it can take some time to change the data source in the classes. Therefore you are unlikely to do it, and unlikely to run the tests. That makes them pointless. 

    Notice that SomeClass in the example I provided earlier doesn't refer to a specific data source. It only refers to an interface. The actual data source is provided at runtime via dependency injection. You only need one entry in a DI container's configuration to specify the actual type. If you were using Ninject as your DI container, the configuration might look like this:

    ioc.Bind<iRetrive>().To<XmlClass>();

    You set that up in one place and it runs on application start-up. Everywhere that iRetrive is specified, XmlClass will be used. In your test project, you have a different configuration:

    ioc.Bind<iRetrive>().To<FakeClass>();

    Now all the classes that programme against iRetrive will use FakeClass instead. But the code in the classes under test does not change. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 9, 2014 3:34 AM
  • User339993961 posted

    Thank you.

    Tuesday, September 9, 2014 4:49 AM
  • User339993961 posted

    How far interfaces are good in terms of memory?

    In the above example, if we take 3 concrete classes, we will create 3 different objects.

    If we take an interface, and 3 classes implement that interface, then also we must assign these 3 objects to the reference of the interface.

    So what are the advantages?

    Wednesday, September 10, 2014 12:23 AM
  • User-821857111 posted

    How far interfaces are good in terms of memory?

    I have absolutely no idea. It shouldn't even be a consideration. 

    Wednesday, September 10, 2014 2:15 AM