PHP Interface Isolation Principle of Five Object Oriented Principles of ISP Detailed Explanation

  • 2021-09-20 19:45:21
  • OfStack

In this paper, the interface isolation principle (ISP), which is one of the five object-oriented principles of PHP, is described by examples. Share it for your reference, as follows:

When designing an application, if a module contains multiple sub-modules, we should be careful to abstract the module. Assuming that the module is implemented by a class, we can abstract the system into an interface. But when adding a new module extender, if the module to be added contains only 1 sub-module in the original system, then the system will force us to implement all the methods in the interface, and we should write 1 dumb method. Such an interface is called a fat interface or a contaminated interface. Using such an interface will introduce some improper behaviors to the system, which may lead to incorrect results and waste of resources.

1. Interface isolation

The Interface Isolation Principle (Interface Segregation Principle, ISP) states that clients should not be forced to implement one interface that they will not use, but should group methods in a fat interface and replace it with multiple interfaces, each serving one sub-module. Simply put, it is much better to use multiple specialized interfaces than to use a single interface.

The main points of ISP are as follows:

1) The dependency of one class on another should be based on the smallest interface.

ISP does not force customers (the way the interface is used) to rely on methods they do not use, and the implementation class of the interface should only be rendered as a single 1-duty role (following SRP principles)

ISP also reduces customer interaction--when a customer demands a new responsibility (which requires a change) and forces a change in the interface, the other client programs are least likely to be affected.

2) The client program should not rely on interface methods (functionality) that it does not need.

The client program should rely on interface methods (functions) that it does not need. What does it rely on? Depends on the interface it needs. What interface the client needs is to provide what interface, and eliminate the unnecessary interface, which requires refinement of the interface to ensure its purity.

For example, when inheriting, because the subclass will inherit all available methods in the parent class; Some methods in the parent class may not be needed in the subclass. For example, both the average employee and the manager inherit from the employee interface. Employees need to write daily work logs, while managers don't. Therefore, you can't use the work log to card the manager, which means that the manager should not rely on the method of submitting the work log.

It can be seen that ISP and SRP have a definite intersection in concept. In fact, many design patterns intersect conceptually, and it is even difficult for you to judge which design pattern a piece of code belongs to.

ISP emphasizes that the interface promises as little as possible to the client, and it should be specialized. When the requirements of one client change and the interface is forced to change, it is less likely to affect other clients. This is actually the problem of interface pollution.

2. Contamination of interfaces

Too bloated interface design is pollution to the interface. The so-called interface pollution is to add unnecessary responsibilities to the interface. If the developer adds a new function to the interface only for the purpose of reducing the number of interface implementation classes, this design will cause the interface to be constantly "polluted" and "fat".

"Interface isolation" is actually the principle of customized service design. Multiple inheritance of interfaces is used to realize the combination of different interfaces, so as to provide the combination function to the outside world-to achieve "providing services on demand".

The interface should be dismantled, but it should not be dismantled too finely, so there must be a standard, that is, high cohesion. The interface should have some basic functions and be able to complete one basic task alone.

In practical application, I will encounter the following problems: For example, I need an DAO implementation that can adapt to various types of databases, so I should first implement a database operation interface, which stipulates some basic methods of database operation, such as connecting the database, adding, deleting, modifying and checking, closing the database, etc. This is a least functional interface. For some methods that are unique to MySQL and do not exist in other databases or have different properties, such as pconnect method of MySQL that may be used in PHP, the same concept as this method does not exist in other databases, so this method should not appear in this basic interface. What basic methods should this basic interface have? PDO has told you.

PDO is an abstract database interface layer, which tells us what basic methods a basic database operation interface should implement. Interface is a high-level abstraction, so the methods in the interface should be general, basic and not easy to change.

There is another question, how should those unique methods be implemented? According to the principle of ISP, these methods can exist in another interface, so that this "heterogeneous" can implement both interfaces at the same time.

For interface pollution, you can consider these two treatment methods:

Separate interfaces with delegates.

Separate interfaces with multiple inheritance.

In delegate pattern, two objects participate in processing the same request, and the object that accepts the request delegates the request to another object to handle it. For example, the concept of delegate is applied in policy pattern and proxy pattern.

Let's look at the following example

Have you ever encountered a very "fat" interface?

For example, there is an interface related to animals, and the code is as follows:


<?php
interface Animal{
  public function walk();
  public function speak();
}

Dog is a concrete implementation of this interface:


<?php
require_once "animal.php";
class Dog implements Animal{
  public function walk(){
    echo "dogs can walk";
  }
  public function speak(){
    echo "dogs can speak";
  }
}

ok, now we want to create a fish that can swim. What should we do? We have to modify the interface, which also affects the implementation of the dog class, and fish also needs to implement the walk and speak methods, as shown in the following code:

Animal interface class:


<?php
interface Animal{
  public function walk();
  public function speak();
  public function swim();
}

Class dog:


<?php
require_once "animal.php";
class Dog implements Animal{
  public function walk(){
    echo "dogs can walk";
  }
  public function speak(){
    echo "dogs can speak";
  }
  public function swim(){
  }
}

Class fish:


<?php
require_once "animal.php";
class Fish implements Animal{
  public function walk(){
  }
  public function speak(){
  }
  public function swim(){
    echo "fish can swim";
  }
}

At this time, Animal interface class presents the characteristics of "fat" interface. The so-called fat interface is actually a method defined in the interface that not all implementation classes need, just like Animal interface class, some animals can't swim, some animals can't walk, and some animals can't fly. If all these methods are written in an Animal interface class, the later extension and maintenance will be a disaster.

So, how to solve the above problems?

Very simple, the interface can be refined, and the Animal interface class is split into three interface classes:

animalCanWalk interface classes:


<?php
interface animalCanSpeak{
  public function speak();
}

AnimalCanSwim interface class:


<?php
interface AnimalCanSwim{
  public function swim();
}

animalCanSpeak interface classes:


<?php
interface animalCanSpeak{
  public function speak();
}

With these interface classes defined, the implementation of dog and fish is much easier,


<?php
require_once "animalCanSpeak.php";
require_once "animalCanWalk.php";
class Dog implements animalCanSpeak,animalCanWalk{
  public function walk(){
    echo "dogs can walk";
  }
  public function speak(){
    echo "dogs can speak";
  }
}


<?php
require_once "animalCanSwim.php";
class Fish implements AnimalCanSwim{
  public function swim(){
    echo "fish can swim";
  }
}

Under summary 1:

The concept of the Interface Isolation Principle (Interface Segregation Principle, ISP): Use multiple specialized interfaces instead of a single 1 master interface, that is, the client should not rely on those interfaces it does not need.

When using the principle of interface isolation, we need to pay attention to controlling the granularity of interfaces. Interfaces should not be too small. If they are too small, they will lead to the proliferation of interfaces in the system, which is not conducive to maintenance; Interface can not be too large, too large interface will violate the principle of interface isolation, poor flexibility, very inconvenient to use. In general, an interface should only contain methods that are customized for a class 1 user, and customers should not be forced to rely on methods that they do not use.

For more readers interested in PHP related content, please check the topics on this site: "Introduction to php Object-Oriented Programming", "Encyclopedia of PHP Array (Array) Operation Skills", "Introduction to PHP Basic Syntax", "Summary of PHP Operation and Operator Usage", "Summary of php String (string) Usage", "Introduction to php+mysql Database Operation Skills" and "Summary of php Common Database Operation Skills"

I hope this article is helpful to everyone's PHP programming.


Related articles: