スプリングお気に入りのデザインモード(3)


5.テンプレートメソッドアレイ


ボルトという子犬とキティという猫を飼っていることを想像してみてください.ボルト、キティと素晴らしい時間を過ごした世界をプログラムで表現するには、2つのクラスが必要です.
Dog.java
public Class Dog {
    public void playWithOwner() {
        System.out.println("귀염둥이 이리온...";
        System.out.println("멍! 멍!");
        System.out.println("꼬리 살랑 살랑~");
        System.out.println("잘했어");
    }
}
Cat.java
public Class Cat {
    public void playWithOwner() {
        System.out.println("귀염둥이 이리온...";
        System.out.println("야옹~ 야옹~");
        System.out.println("꼬리 살랑 살랑~");
        System.out.println("잘했어");
    }
}
上記の例のコードのplayWithOwner()メソッドから、4行目を除いてすべての内容が同じであることがわかります.したがって,上記コードでは,オブジェクト向けの4つの特性のうち同じ部分(重複)が上位クラスであることを継承することにより,異なる部分だけ下位クラスに分割したいオブジェクト向け設計の意欲が刺激される.そこで、コードを改善してみましょう.
親を含むAnimal.java
package templateMethodPattern;

public abstract class Animal {
    // 템플릿 메서드
    public void playWithOwner() {
        System.out.println("귀염둥이 이리온...";
        play();
        runSomething();
        System.out.println("잘했어");
    }
    
    // 추상 메서드
    abstract void play();
    
    // Hook(갈고리) 메서드
    void runSomthing() {
        System.out.println("꼬리 살랑 살랑~");
    }
}
サブクラスを含むDog.java
package templateMethodPattern;

public Class Dog extends Animal {
    @Override
    // 추상 메서드 오버라이딩
    void play() {
        System.out.println("멍! 멍!");
    }
    
    @Override
    // Hook(갈고리) 메서드 오버라이딩
    void runSomthing() {
        System.out.println("멍! 멍!~ 꼬리 살랑 살랑~");
    }
}
サブクラスを含むCat.java
package templateMethodPattern;

public Class Cat extends Animal {
    @Override
    // 추상 메서드 오버라이딩
    void play() {
        System.out.println("야옹~ 야옹~");
    }
    
    @Override
    // Hook(갈고리) 메서드 오버라이딩
    void runSomthing() {
        System.out.println("야옹~ 야옹~ 꼬리 살랑 살랑~");
    }
}
Driver.java
package templateMethodPattern;

public Class Driver {
    public static void main(String[] args) {
        Animal bolt = new Dog();
        Animal kitty = new Cat();
        
        bolt.playWithOwner();
        
        System.out.println();
        System.out.println();
        
        kitty.playWithOwner();
    }
}
親Animalには、テンプレート(サンプル)を提供するplayWithOwner()メソッドと、子クラスの実装を強制するplay()抽象メソッドと、子クラスが選択的に上書きできるrunSomething()メソッドがある.サブクラスDogおよびCatは、親クラスAnimalで強制的に実装されるplay()抽象メソッドを実装しなければならない.runSomething()メソッドは選択的に上書きできます.이처럼 상위 클래스에 공통 로직을 수행하는 템플릿 메서드와 하위 클래스에 오버라이딩을 강제하는 추상 메서드 또는 선택적으로 오버라이딩할 수 있는 훅(Hook) 메서드를 두는 패턴을 템플릿 메서드 패턴이라고 한다.
テンプレートメソッドパターンを文に整理します.
「親クラスのサンプルメソッドでサブクラスオーバーライドメソッドを呼び出すモード」
クラス図から、テンプレートメソッドモードが의존 역전 원칙(DIP)を使用していることがわかる.

6.工場方法アレイ


工場は工場を意味する.工場は東西を生産し,対象工場に向けて対象を生成する.最終的に、ファクトリメソッドとは、オブジェクトを生成して返すメソッドです.여기에 패턴이 붙으면 하위 클래스에서 팩터리 메서드를 오버라이딩해서 객체를 반환하게 하는 것을 의미한다.位のテンプレート仕様モードで、かわいいペットたちと一緒に遊ぶコードに想像力を加えて、ボルトとキティがそれぞれ遊びたいおもちゃを持っている様子を想像してみましょう.ボルトは子犬のおもちゃをくわえて来て、キティは猫のおもちゃをくわえて来ます.コードで実現しましょう.
抽象クラスを表すAnimal.java
package factoryMethodPattern;

public abstract class Animal {
    // 추상 팩터리 메서드
    abstract AnimalToy getToy();
}
抽象クラスを表すAnimalToy.java
package factoryMethodPattern;

// 팩터리 메서드가 생성할 객체의 상위 클래스
public abstract class AnimalToy {
    abstract void identify();
}
Dog.java
package factoryMethodPattern;

public Class Dog extends Animal {
    // 추상 팩터리 메서드 오버라이딩
    @Override
    AnimalToy getToy() {
        return new DogToy();
    }
}
DogToy.java
package factoryMethodPattern;

// 팩터리 메서드가 생성할 객체
public Class DogToy extends AnimalToy {
    public void identify() {
        System.out.println("나는 테니스공! 강아지의 친구!");
    }
}
Cat.java
package factoryMethodPattern;

public Class Cat extends Animal {
    // 추상 팩터리 메서드 오버라이딩
    @Override
    AnimalToy getToy() {
        return new CatToy();
    }
}
CatToy.java
package factoryMethodPattern;

// 팩터리 메서드가 생성할 객체
public Class CatToy extends AnimalToy {
    public void identify() {
        System.out.println("나는 캣타워! 고양이의 친구!");
    }
}
Driver.java
package factoryMethodPattern;

public Class Driver {
    public static void main(String[] args) {
        // 팩터리 메서드를 보유한 객체들 생성
        Animal bolt = new Dog();
        Animal kitty = new Cat();
        
        // 팩터리 메서드가 반환하는 객체들
        AnimalToy boltBall = bolt.getToy();
        AnimalToy kittyTower = kitty.getToy();
        
        // 팩터리 메서드가 반환한 객체들을 사용
        boltBall.identify();
        kittyTower.identify();
    }
}

ファクトリメソッドモードを次のように定義します.
オーバーライドメソッドがオブジェクトを返すモード(Override Method Return Object Mode)
クラス図から,ファクトリメソッドモードは"의존 역전 원칙(DIP)"を用いていることがわかる.
リファレンス
  • Javaオブジェクト向けSpringの入門原理と
  • を理解する