To the end? programming

Procedure Oriented programming (REFERRED to as PO) and Object Oriented programming (referred to as OO) we must have heard, but the actual enterprise development is more used in a programming thought that is: Interface-Oriented programming!

Interface this concept we are certainly not unfamiliar, the most common example in real life is: socket!

We only need to define the socket interface standard in advance, as long as the major socket manufacturers according to this interface standard production, tube you what brand, what internal circuit structure, these have nothing to do with the user, the user can be used; And even if the socket doesn’t work, as long as you get a new one that meets the interface standard, everything works fine!

The same goes for actual code design!

When we design the code architecture of a software, we all hope to agree on the interface of each function in advance (namely: agree on the interface signature and method), and we only need to implement this interface to complete the specific function in actual development! In the future, even if the project changes and functions are upgraded, the programmer only needs to re-implement it according to the interface convention, so that the system can be upgraded and expanded!

As it happens, Java is born with the interface syntax, which is made for interface oriented programming!

So the next implementation of the code, to take a little more popular Lao Lao, the actual business code is more complex than this, but the principle is exactly the same.


dreaming

If one day program sheep really developed, a bold bought two luxury cars, a Wuling macro light, a fit, and also specially hired a driver to help drive.

Here are two luxury cars:

public class Wuling {
    public void drive(a) {
        System.out.println("Driving Wuling Hongguang Car"); }}public class Fit {
    public void drive(a) {
        System.out.println("Driving a Fit car."); }}Copy the code

Drivers are defined here:

The driver defines two drive() methods, one for driving two cars:

public class Driver { public void drive( Wuling wuling ) { wuling.drive(); } public void drive(Fit Fit) {fit.drive(); Public static void main(String[] args) {Wuling Wuling = new Wuling(); Fit fit = new Fit(); // instantiate Driver = new Driver(); driver.drive( wuling ); Drive (fit); // Drive (fit); // Help me fly}}Copy the code

That seems ok for now! Life went on harmoniously.

But over time, the program goat grew a bit more developed, and this time he bought a new Alto!

But the existing Driver class of the two drive() method can not drive this new bought Alto how to do?


Flexible decoupling of code

At this point, I don’t think anyone would add a new drive() method to the Driver class to do that. After all, you never know if he’ll ever buy a new car!

What if I want the driver I hire to be able to handle everything?

It’s easy to imagine that we should do a layer of abstraction. After all, both Alto and Audi are cars, so we’ll define a parent class called Car, which declares only one generic drive() method, regardless of how to drive it:

Public class Car {void; public class Car {voiddrive() {} // Common car driving method}Copy the code

At this point, as long as my new Alto meets the driving standards defined by Car, it can be driven by my driver, so I just need to inherit the Car class from the new Alto:

public class Alto extends Car {
    public void drive() {
        System.out.println("Driving an Alto Car."); }}Copy the code

Similarly, as long as my driver has the driving ability of General Motors Car, it is not a problem to drive all cars. Therefore, the drive() method of Drvier class has universality as long as the parameter is the parent:

Public class Driver {public void drive(Car Car) {// The method argument uses the parent class instead of car.drive(); } public static void main( String[] args ) { Alto alto = new Alto(); Driver driver = new Driver(); driver.drive( alto ); }}Copy the code

Problem solved for the time being!


I don’t even want to ride in a car. I want to buy a Donkey that the driver can take me around.

Obviously, the drive() method used for cars is not suitable for donkeys! But what about the driver we want to hire who can drive a car and ride a donkey?

Harm! Let’s just define a common interface called TrafficTools. It contains a general method of using transportation, regardless of whether you drive a car, ride a donkey or ride a horse:

Public interface TrafficTools {void drive(); // Common use of transportation}Copy the code

With this interface convention in place, it’s easy to follow. Let’s make all cars, or donkeys, horses, etc., implement this interface:

public class Car implements TrafficTools {
    @Override
    public void drive() { }
}

public class Wuling extends Car {
    public void drive() {
        System.out.println("Driving Wuling Hongguang Car");
    }
}

public class Fit extends Car {
    public void drive() {
        System.out.println("Driving a Fit car.");
    }
}

public class Alto extends Car {
    public void drive() {
        System.out.println("Driving an Alto Car.");
    }
}

public class Donkey implements TrafficTools {
    @Override
    public void drive() {
        System.out.println("Ride a donkey."); }}Copy the code

At this time, as long as our driver master also face interface programming, there is no problem:

Public void drive(TrafficTools TrafficTools) {traffictools.drive (); } public static void main( String[] args ) { Driver driver = new Driver(); driver.drive( new Wuling() ); Drive (new Fit()); // Drive (new Alto()); // Drive (new Donkey()); // Ride a donkey}}Copy the code

Clearly, the code is completely decoupled! This is the convenience of interfaces.


Extensibility of code

The benefits of interface oriented programming go beyond the above code decoupling scenarios, and flexible extensions of existing code using interface ideas are particularly common in real enterprise development.

For another example, let’s say program Goat has a very ambitious friend named Program Cow. They don’t travel by car, but by private jet.

Public interface Plane {void fly(); } public class PlaneDriver implements Plane {@override public voidfly() {
        System.out.println("A professional pilot controls the plane."); }} public class Travel {// this function is also interface oriented programming!! public void fly( Plane plane ) { plane.fly(); } public static void main( String[] args ) { Travel travel = new Travel(); PlaneDriver PlaneDriver = new PlaneDriver(); Fly (planeDriver); fly(planeDriver); // A pleasant trip by a professional captain}}Copy the code

But then one day, the pilot they hired jumped ship, and the family couldn’t travel because they didn’t know how to fly.

So he came to me and asked me to lend him a driver. He wanted my pilot to help him fly the plane for a trip.

As soon as I looked, since their code was for interfaces, I definitely said yes!

At this point, it is very easy for my extension, I just need to arrange my pilots to train flying skills (implement a method) :

// Let my pilots train their flying skills (i.e. Public class Driver implements Plane {public void drive(TrafficTools TrafficTools) {traffictools.drive ();  } // Implement the fly() method, which gives my pilot the ability to fly the plane! @Override public voidfly() {
        System.out.println("Ordinary pilots fly planes."); }}Copy the code

At this time, my Driver class can directly serve their family travel:

public class Travel { public void fly( Plane plane ) { plane.fly(); } public static void main( String[] args ) { Travel travel = new Travel(); PlaneDriver PlaneDriver = new PlaneDriver(); travel.fly( planeDriver ); // Driver = new Driver(); travel.fly( driver ); }}Copy the code

See, in this transformation process, we only added code, but did not modify any existing code, completed the code extension task, very in line with the open and closed principle!


The actual project

In practical development, we are used to using interfaces in the Service layer for a layer of isolation, not to mention the fact that frameworks such as Spring use interfaces internally and provide them for external use:

This separation of interface definition and concrete implementation logic is very conducive to subsequent expansion and maintenance!


summary

Interface oriented programming development, decoupling and expansion of code architecture is really good, this kind of coding idea is also worth repeated understanding and aftertaste of daily development combined with practice!