What does “program to interfaces, not implementations” mean?

前端 未结 7 2029
情深已故
情深已故 2020-11-22 07:41

One stumbles upon this phrase when reading about design patterns.

But I don\'t understand it, could someone explain this for me?

7条回答
  •  旧巷少年郎
    2020-11-22 08:05

    If you were to write a Car Class in Combustion-Car era, then there is a great chance you would implement oilChange() as a part of this Class. But, when electric cars are introduced, you would be in trouble as there is no oil-change involved for these cars, and no implemention.

    The solution to the problem is to have a performMaintenance() Interface in Car class and hide details inside appropriate implementation. Each Car type would provide its own implementation for performMaintenance(). As a owner of a Car all you have to deal with is performMaintenance() and not worry about adapting when there is a CHANGE.

    class MaintenanceSpecialist {
        public:
            virtual int performMaintenance() = 0;
    };
    
    class CombustionEnginedMaintenance : public MaintenanceSpecialist {
        int performMaintenance() { 
            printf("combustionEnginedMaintenance: We specialize in maintenance of Combustion engines \n");
            return 0;
        }
    };
    
    class ElectricMaintenance : public MaintenanceSpecialist {
        int performMaintenance() {
            printf("electricMaintenance: We specialize in maintenance of Electric Cars \n");
            return 0;
        }
    };
    
    class Car {
        public:
            MaintenanceSpecialist *mSpecialist;
            virtual int maintenance() {
                printf("Just wash the car \n");
                return 0;
            };
    };
    
    class GasolineCar : public Car {
        public: 
            GasolineCar() {
            mSpecialist = new CombustionEnginedMaintenance();
            }
            int maintenance() {
            mSpecialist->performMaintenance();
            return 0;
            }
    };
    
    class ElectricCar : public Car {
        public: 
            ElectricCar() {
                 mSpecialist = new ElectricMaintenance();
            }
    
            int maintenance(){
                mSpecialist->performMaintenance();
                return 0;
            }
    };
    
    int _tmain(int argc, _TCHAR* argv[]) {
    
        Car *myCar; 
    
        myCar = new GasolineCar();
        myCar->maintenance(); /* I dont know what is involved in maintenance. But, I do know the maintenance has to be performed */
    
    
        myCar = new ElectricCar(); 
        myCar->maintenance(); 
    
        return 0;
    }
    

    Additional explanation: You are a car owner who owns multiple cars. You carve out the service that you want to outsource. In our case we want to outsource the maintenance work of all cars.

    1. You identify the contract(Interface) that holds good for all your cars and service providers.
    2. Service providers come out with a mechanism to provide the service.
    3. You don't want to worry about associating the car type with the service provider. You just specify when you want to schedule maintenance and invoke it. Appropriate service company should jump in and perform the maintenance work.

      Alternate approach.

    4. You identify the work(can be a new interface Interface) that holds good for all your cars.
    5. You come out with a mechanism to provide the service. Basically you are going to provide the implementation.
    6. You invoke the work and do it yourself. Here you are going to do the job of appropriate maintenance work.

      What is the downside of the 2nd approach? You may not be the expert at finding the best way to do the maintenance. Your job is to drive the car and enjoy it. Not to be in the business of maintaining it.

      What it the downside of the first approach? There is the overhead of finding a company etc. Unless you are a rental car company, it may not be worth the effort.

提交回复
热议问题