Статьи

Прикладной дизайн декоратора

Всем привет!

Сегодня я покажу шаблон дизайна декоратора в действии. Шаблон дизайна декоратора является широко используемым шаблоном дизайна при работе с графикой, деревьями и динамическими изменениями во время выполнения.

Это также отличный выбор, если вы ищете или пытаетесь сделать рекурсию. Я люблю это. В этом посте мы будем реализовывать украшения для студентов. Мы украсим его дипломами и званиями доктора. Хороший пример, чтобы увидеть, как это работает в реальном мире.

Прежде всего, давайте взглянем на UML-диаграмму в ее простейшем варианте. После этого мы возьмем аналогию для нашего примера.

Самый простой UML

Обратите особое внимание, потому что, как только вы это поймете, все станет ясным и простым для понимания. Вот почему я ставлю здесь самую простую модель.

декоратор

Понимание деталей

Decorable будет каждой конкретной реализацией общего взаимодействия Decorable. Декораторы будут каждой реализацией абстрактного класса Decorator. Который определяет контракт декоратора, содержащий экземпляр для предметов декора. Давайте углубимся в некоторый код, чтобы исправить это:

01
02
03
04
05
06
07
08
09
10
11
12
// 1. COMMON INTERFACE FOR DECORABLES
public interface Decorable {
    public String getDescription();
}
// 2. THE ABSTRACT DECORADOR WHICH HOLDS A REFERENCE TO DECORABLES
public abstract class Decorator implements Decorable {
    protected Decorable component;
    public Decorator(Decorable component){
        super();
        this.component=component;
    }
}

Пример аналогии с нашими студентами

Давайте сначала начнем с диаграммы UML:

декоратор (1)

Обыкновенная декорируемая девушка

Здесь мы начнем с аналогий. Интерфейс Girl является декорируемым. GirlDecorator определяет контракт абстрактного декоратора с конкретными декораторами ниже.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 1. COMMON INTERFACE FOR DECORABLES
public interface Girl {
    public String getDescription();
}
// 2. THE ABSTRACT DECORADOR WHICH HOLDS A REFERENCE TO DECORABLES
public abstract class GirlDecorator implements Girl {
    protected Girl girl;
    public GirlDecorator(Girl girl){
        super();
        this.girl=girl;
    }
}
// 3. DEFINING CONCRETE DECORATORS
public class Science extends GirlDecorator {
    public Science(Girl girl) {super(girl);}
    @Override
    public String getDescription() {
        // DECORATES WITH A SCIENCE'S DEGREE
        return girl.getDescription() + "+Like Science";
    }
    public void caltulateStuff() {
        // ADDS NEW FEATURES (METHOD) TO IT
        System.out.println("scientific calculation!");
    }
}
public class Art extends GirlDecorator {
    public Art(Girl girl) {super(girl);}
    @Override public String getDescription() {return girl.getDescription() + "+Like Art";}
    public void draw() {System.out.println("draw pictures!");}
}
public class Doctor extends GirlDecorator {
    public Doctor(Girl girl) {super(girl);}
    @Override public String getDescription() {return girl.getDescription() + "+Like Doctor";}
    public void calculateStuff() {System.out.println("doctor calculation!");}
    public void doctorTitle() {System.out.println("doctor title");}
}

Предметы декора

AmericanGirl и EuropeanGirl — это украшение, которое будет украшаться дипломами и званиями доктора во время выполнения, улучшая его учебный план и способности.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
// 4. AN AMERICAN GIRL WILL BE DEFINED AS A DECORABLE
public class AmericanGirl implements Girl {
    private String description="";
    // NORMAL AMERICAN GIRL
    public AmericanGirl(){
        super();
        description = "+American";
    }
    @Override public String getDescription() {return description;}
}
public class EuropeanGirl implements Girl {
    private String description="";
    public EuropeanGirl() {
        super();
        description = "+European";
    }
    @Override public String getDescription() {return description;}
}

Тестирование это

Теперь посмотрим на практике, как это выглядит. Как мы можем украсить и улучшить его возможности во время выполнения:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Client {
    public static void main(String[] args) {
        // COMMOM GIRL
        Girl girl;
         
        // CREATING NORMAL AMERICAN GIRL
        girl = new AmericanGirl();
        System.out.println(girl.getDescription());
  
        // DECORANTING AMERICANA GIRL WITH SCIENCE'S DEGREE
        girl = new Science(girl);
        System.out.println(girl.getDescription());
  
        // DECORANTING AMERICANA GIRL WITH ART'S DEGREE
        girl = new Art(girl);
        System.out.println(girl.getDescription());
         
        // EUROPEAN GIRL HAS ALREADY ALL DEGREES  
        Girl europeia = new Science(new Art(new EuropeanGirl()));
        System.out.println(europeia.getDescription());
         
        // DOCTOR HAS NEW FUNCTIONS   
        girl = new Doctor(girl);
        System.out.println(girl.getDescription());
        // BECAUSE DOCTOR EXTENDS FROM COMMON GIRL, IT CAN DO A DOWNCAST
        ((Doctor)girl).doctorTitle();
        ((Doctor)girl).calculateStuff();
         
        // PAY ATTENTION THAT WE USE THE SAME INSTANCE, BUT THEY BEHAVIOR DIFFERENT
        // AT DIFFERENT TIME SLOTS. THE CLIENT HAS THE IMPRESSION THAT WE HAVE
        // CHANGED THE IMPLEMENTATION, BUT IN FACT NOT.
    }
}

Вот и все! Надеюсь, вам понравится!