📜 ⬆️ ⬇️

Barbara Liskov substitution principle

Hi, habracheloveki!

I wanted to share my secret knowledge on this topic. In addition, the materials on this rather important principle of designing classes and their inheritance in RuNet are somehow sparse. There are formulations of the form:

“Let q (x) be a property true with respect to objects x of some type T. Then q (y) must also be true for objects y of type S, where S is a subtype of type T.” © Wikipedia
')
But they endure my brain, they do not please me at all.

If you want to hear an explanation of this crap clever phrase - I ask for cat.

So, the principle of substitution by Barbara Liskov. He is Liskov Substitution Principle. He is an LSP. In simple terms, the principle is:

The next class should complement, not replace, the behavior of the base class.

1. What does this mean in practice?


If we have class A (not virtual, but quite realistically used in code) and class B inherited from it, then if we replace all uses of class A with B, nothing should change in the operation of the program. After all, class B only expands the functionality of class A. If this check works, then congratulations: your program corresponds to the Liskov substitution principle! If not, it is worth dismissing the lead programmer to think: “are the classes designed correctly?”.

2. Well, why is it necessary?


I hope everyone understands that the Liskov principle is from the field of OOP theory. In practice, no one forces him to follow at gunpoint. Moreover, there may be cases when it is difficult to follow it and no one needs it.

In a word, just like with valid HTML: the site passed the test on the W3C validator - plusin to the maker's karma. I didn’t pass - you need to clearly understand why he didn’t pass: is this a mistake or is it impossible to implement another freak in other ways?

From this we can draw conclusions:
* following the principle of substitution Liskov makes your project closer to the spirit of the PLO;
* This will avoid a number of errors (about them below).

3. Example


I decided not to reinvent the bicycle, and besides, I really liked the example from here . I will use it then (with light modifications).

So, the situation: we are designing a program for controlling thermostats. The program should be able to work with several different device models. The program cyclically checks the temperature and tries to rectify it to the required one. We will not, of course, write the program itself, but will focus on designing a hierarchy of interface classes for thermostats.

3.1. Debut

First of all - the base class. It should have the following methods:
* InitializeDevice : initialization of the connected thermostat. Understandably, the pure virtual method: different devices may require different foreplay to make it work properly.
* Get / Set Reference : getter / setter for the required (reference) temperature. Quite to itself specific methods (not virtual) for variable setting.
* GetTemperature : read temperature from device. Again purely virualny method.
* AdjustTemperature : again pure virtual method. Actually, to set the temperature.

We describe this in a more understandable language, that is, C ++:
  1. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  2. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  3. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  4. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  5. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  6. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  7. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  8. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  9. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  10. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  11. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  12. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  13. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  14. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  15. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  16. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };
  17. class TemperatureController { // int m_referenceTemperature; public : int GetReferenceTemperature() const { return m_referenceTemperature; } void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; };


3.2. Mitchel spiel

And now we will draw 2 specific classes for working with “real” thermostats of well-known and popular companies Brand_A and Brand_B (How? Do you not know them? Me neither):
  1. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  2. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  3. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  4. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  5. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  6. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  7. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  8. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  9. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  10. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  11. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  12. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  13. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  14. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  15. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  16. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  17. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  18. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  19. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  20. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  21. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  22. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  23. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  24. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  25. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  26. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  27. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  28. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  29. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  30. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  31. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  32. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  33. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };
  34. class Brand_A_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(TEMP_REGISTER)); } void AdjustTemperature( int temperature) { io_write(TEMP_CHANGE_REGISTER, temperature); } void InitializeDevice() { // } }; class Brand_B_TemperatureController : public TemperatureController { public : int GetTemperature() const { return (io_read(STATUS_REGISTER) & TEMP_MASK); } void AdjustTemperature( int temperature) { // : // ! , . io_write(CHANGE_REGISTER, temperature + 273); } void InitializeDevice() { // } };

Voila! It remains to write a couple of lines in our program:
  1. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .
  2. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .
  3. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .
  4. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .
  5. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .

And it's cool! The program works, the customer is satisfied, we read Habr.

3.3. Endgame

It takes some time and marketers (they do not eat bread for nothing!) Came up with a new stylish thermostat with a large touch screen and FM tuner. Our customer, having purchased a new device, is announced again and from the doorway declares: “I want to, do you understand, so that the program supports my beauty!”.

Ok, let's add another device. Write Brand_C_TemperatureController we will not be difficult? In the process of finalization, it suddenly turns out that the new thermostat, in addition to its touch screen, also has advanced automation: i.e. it is not necessary to manually check and adjust the temperature. It is enough to feed the required temperature once (we have this ReferenceTemperature), and he will do the rest. This is good (less fuss), and bad (our classes are not particularly adapted to this situation).

We find the exit in 5 minutes: in the base class, Get / Set Reference is declared virtual, and in the class for the new Brand_C thermostat, we simply redefine these methods to read / write the temperature directly to the thermostat. Beauty, isn't it? No sooner said than done:

  1. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  2. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  3. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  4. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  5. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  6. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  7. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  8. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  9. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  10. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  11. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  12. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  13. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  14. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  15. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  16. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  17. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  18. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  19. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  20. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  21. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  22. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  23. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  24. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  25. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  26. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  27. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  28. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  29. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  30. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  31. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  32. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  33. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  34. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  35. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  36. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  37. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  38. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  39. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  40. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  41. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  42. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  43. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };
  44. class TemperatureController { // int m_referenceTemperature; public : // / // virtual int GetReferenceTemperature() const { return m_referenceTemperature; } virtual void SetReferenceTemperature( int referenceTemperature) { m_referenceTemperature = referenceTemperature; } virtual int GetTemperature() const = 0; virtual void AdjustTemperature( int temperature) = 0; virtual void InitializeDevice() = 0; }; class Brand_C_TemperatureController : public TemperatureController { public : // / int GetReferenceTemperature() const { return (io_read(REFERENCE_REGISTER); } void SetReferenceTemperature( int referenceTemperature) { io_write(REFERENCE_REGISTER, referenceTemperature); } int GetTemperature() const { return (io_read(TEMP_MONITORING_REGISTER)); } void AdjustTemperature( int temperature) { // : } void InitializeDevice() { // , } };

Under the law of the genre, it becomes clear that now there will be a climax. It's time to say: "Checkmate!"

3.4. Oh, and what was it?

Before debriefing, let us recall the Liskov principle of substitution: The next class should complement, not replace, the behavior of the base class. And what have we just done? Right! We have replaced the methods GetReferenceTemperature and SetReferenceTemperature. We changed class behavior. What is it fraught with? I will quote again the use of our classes in order not to wear the wheel of your mouse:
  1. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .
  2. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .
  3. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .
  4. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .
  5. . . . TemperatureController *pTempCtrl = GetNextTempController(); pTempCtrl->SetReferenceTemperature(10); pTempCtrl->InitializeDevice(); . . .

Still not clear? In the case of working with equipment Brand_A and Brand_B - everything is fine. But if Brand_C is used, we first write the temperature to the device, and then just initialize the device. What can all this be - fantasize yourself. It is possible that nothing terrible will happen. And it is possible that we will spend half a day in debug.

But if during the creation of the Brand_C_TemperatureController class (more precisely, during the stupid redefinition of the ill-fated getters / setters), we remembered the substitution principle, we could guess that the model of abstraction invented by us in new realities is complete bullshit. How to fix this situation? Alas, this is not the topic of this article. I think so tired all of them.

4. I want more!


On the topic I can suggest to read:
* Wikipedia article (I warned at the very beginning!);
* The Liskov Substitution Principle - it was from here that I stole the example for this topic;
* Google

5. Dessert


ABOUT! I remembered! The article should be diluted with pictures. Here is:
Barbara Liskov substitution principle ©

If this demotivator made you smile, it means that you understand what I have written about so much text.

Good luck! And let the bugs are less common on your way!

Source: https://habr.com/ru/post/83269/


All Articles