Introduction to the

Decoration mode is also a relatively common design mode, which is rarely deliberately implemented in the process of work, because this mode will also bring some problems.

For example, there are too many small classes, it is difficult to organize, completely visible to the client, if you do not understand the function of each class will be very messy, and so on

Of course, there are many advantages: you can add responsibilities to classes dynamically, adding functionality is more flexible, and more flexible than inheritance

So what does it look like

The setting

Take the car buying business model as an example (I have never bought a car and the business scenario is purely imaginary)

There are also a number of items to choose from, depending on the choice of decoration to determine the final price:

goods The price
Naked car 100000
Heated seats (optional) 4000
Leather interior (optional) 8000
Disco stereo (optional) 5000

First version implementation (we did it in a class)

package car; Public class Car {private int allPrice = 0; Private int nakedPrice = 100000; Private int heatedSeat = 1000; // Leather interior Private int dermalInteriors = 8000; Private int bengdiSound = 5000; publicCar() { this.allPrice += this.nakedPrice; } /** * Add leather seat */ public voidaddHeatedSeat() { this.allPrice += this.heatedSeat; } /** * Add leather interior */ public voidaddDermalInteriors() { this.allPrice += this.dermalInteriors; } /** * public void */addBengdiSound() { this.allPrice += this.bengdiSound; } /** * get the total price ** @return
     */
    public int cost() {
        returnthis.allPrice; }}Copy the code

Client call:

package car;

public class Main {

    public static void main(String[] args) {

        Car car = new Car();

        car.addBengdiSound();
        System.out.println("Total cost :"+ car.cost()); }}Copy the code

The output:

Cost price 105000Copy the code

It looks pretty neat, and it works pretty well

First of all, our scenario is simple enough, and there are few supporting components involved. In practice, there may be very complex acquisition and calculation logic for a certain method, and there may be many choices of components, which will cause class explosion, and maintenance cannot continue

If we use decoration mode, what changes will it make, what kind of experience will it give us

Design:

Implementation:

Declare abstract classes (which decorators and decorators inherit to formalize implementation methods)

package car;

public abstract class Car {

    public String name;

    public abstract String cost();
}
Copy the code

Main character: Decorated – naked car

package car; /** * public class extends Car {private int nakedPrice = 100000; publicNakeCar() {
        this.name = "Car"; } /** * get the total price ** @return
     */
    public String cost() {
        return this.name + ":"+ this.nakedPrice; }}Copy the code

Specific decoration categories:

Heated seats

package car; /** * public class HeatedSeat extends Car {private int HeatedSeat = 1000; Private Car Car; public HeatedSeat(Car car) { this.name ="Heated seat"; this.car = car; } /** * get the price ** @return
     */
    public String cost() {
        //todo
        return this.car.cost() + "| |" + this.name + ":"+ this.heatedSeat; }}Copy the code

Leather trim

package car; Public Class DermalInteriors extends Car {// Leather interior private int DermalInteriors = 8000; Private Car Car; public DermalInteriors(Car car) { this.name ="Leather interior"; this.car = car; } /** * get the price ** @return
     */
    public String cost() {
        //todo
        return this.car.cost() + "| |" + this.name + ":"+ this.dermalInteriors; }}Copy the code

Disco dancing sound

package car; Public class BengdiSound extends Car {// Private int BengdiSound = 5000; Private Car Car; public BengdiSound(Car car) { this.name ="Disco sound"; this.car = car; } /** * get the price ** @return
     */
    public String cost() {
        //todo
        return this.car.cost() + "| |" + this.name + ":"+ this.bengdiSound; }}Copy the code

Client call:

package car;

public class Main {

    public static void main(String[] args) {

        NakeCar car = new NakeCar();

        HeatedSeat heatedSeat = new HeatedSeat(car);
        BengdiSound bengdiSound = new BengdiSound(heatedSeat);
        System.out.println("Total cost :"+ bengdiSound.cost()); }}Copy the code

output:

The total cost price: naked car: 100000 | | heated seats: 4000 | | disco dancing sound: 5000Copy the code

conclusion

  • Advantages of decorator mode: You can dynamically add functionality to existing functions (to be decorated objects), simplifying existing classes. In our example, the bare car is the main class, which is the core of the business, while some dynamic components can be used according to the actual situation, which is the subsidiary extension function of our line of business.

    The distinction between master logic and extension logic makes our code more extensible.

  • Disadvantages of the decorator pattern: We can see that the introduction of the decorator pattern increases the number of classes and the complexity of using the client. Decorated-pattern classes depend on specific types and need to adhere to strict conventions (abstract class constraints)

More highlights of the public account: