Richter six principles of software design patterns substitution principle (PHP language)

Reprinted, the original link https://www.cnblogs.com/zhanghengscnc/p/8299459.html

Sure a lot of people with the same time I just saw this principle, for the name of the principle of full of doubts. Actually, the reason is that this principle was first stated in 1988, presented by MIT surnamed Ms. Lane (Barbara Liskov) come.

Definition 1: If the object type for each of T1 o1, o2 T2 has an object type, such that all defined P T1 program when all the generations are replaced objects o1 o2, the program does not change the behavior of P , then the type is a subtype of type T2 T1.

Definition 2: All references to base classes must be transparently used where the object whose subclasses.

The origin of the problem: a function of P1, completed by the class A. P1 is now necessary to extend the function, after the function is expanded to P, where P is the original function of P1 and P2 composition new features. New functions carried out by P B subclass of class A, B is a subclass of new features in the completion of P2, it may lead to failure of the original function P1.

Solution: When using inheritance, follow the Richter substitution principle. Class A class B inherits the time, in addition to a new method of adding new features to complete P2 outside, so as not to override the parent class A, and try not to overload the parent class A.

Inheritance contain this layer of meaning: the parent class who have achieved good way (relative to the abstract methods), it is in fact a series of set norms and contract, although it is not mandatory for all subclasses must comply with these contract, but if any of these sub-class non-abstract methods modified, it will cause damage to the entire inheritance hierarchy. The Richter substitution principle is an expression of this layer of meaning.

As for one of the three inherited characteristics of the object, in a huge convenience to programming, but also it brings disadvantages. For example, the use of inheritance will bring invasive procedures, reduced portability procedures, increasing the coupling between objects, if a class is inherited by other classes, then when this class needs to be modified, it must take into account all the sub class, the superclass and modifications, all references are to the functional subclass may malfunction.

Examples of inherited risk, we need to complete a number two subtraction functions from class A to be responsible.

class Calculate
{
public function func1(int $a, int $b)
{
return $a - $b;
}
}

$sub = new Calculate();
echo "100-50=" . $sub->func1(100, 50); //100-50=50
echo "100-80=" . $sub->func1(100, 80); //100-80=20

Later on, we need to add a new feature: the completion of two numbers together, and then with 100 sum to be responsible by the class B. I.e., class B complete two functions:

  • Subtract two numbers.
  • Adding two numbers, then add 100.

Since class A has achieved the first function, class B inherits class A, the second function only need to complete it, as follows:

class Calculate
{
    public function func1(int $a, int $b)
    {
        return $a - $b;
    }
}

class Other extends Calculate
{
    public function func1(int $a, int $b)
    {
        return $a + $b;
    }

    public function func2(int $a, int $b)
    {
        return $this->func1($a,$b) + 100;
    }
}

$o = new Other();
echo "100-50=" . $o->func1(100, 50); //100-50=150
echo "100-80=" . $o->func1(100, 80); //100-80=180
echo "100+20+100=" . $o->func2(100, 20); //100+20+100=220

 

We found that the original function of normal operation of subtraction error has occurred. The reason is that when class B to a method named inadvertently override the parent class method, resulting in all operational functions of a subtraction method was called after all the Class B rewritten, resulting in the original run normal function error occurred. In the present embodiment, the reference functions performed by the base class A, then into sub-Classes B, abnormality occurs. In actual programming, we often accomplished by means of a new function to rewrite the parent class, write up is simple, but the whole system of inherited reusability will be relatively poor, especially the more frequent use of multi-state program run the chance of error is very large. If the parent class have to override the method, the more common practice is: the original parent class and subclasses inherit a more popular base class inheritance remove the original, use dependence, polymerization, instead of the combination relationship.

Richter substitution principle is popular terms: subclass can extend the functionality of the parent class, but can not change the parent class of the original function. It contains the following four layers meanings:

  • Subclasses may implement the abstract parent class, but non-abstract parent class can not be covered.
  • Subclass can add their own unique way.
  • When the method of the parent class subclass overloaded, the pre-conditions of the process (i.e., process parameter) input parameters than the parent class method more relaxed.
  • When subclass of the implementation of the abstract parent class, method postcondition (i.e., return value) is more stringent than the parent.

It looks incredible, because we will find themselves in programming often violate the Richter substitution principle, the program still running good. So we will have this question, if I do not have to follow the principle of what will be the consequences Richter replaced?

Consequence is: your chance to write code problems will be greatly increased.

Guess you like

Origin www.cnblogs.com/shamohai/p/11093871.html