//*****공통 기능을 제공할 신발 원재료 공장 정의*****
interface ShoesIngredientFactory {
 
    public Bottom makeBottom();
 
    public Leather makeLeather();
 
    public boolean hasPattern();
 
}
//******원재료 공장 인터페이스를 구현하는 구현 클래스 만들기********
//일본 매장으로 가는 재료 공장
class JPShoesIngredientFactory implements ShoesIngredientFactory {
 
    @Override
    public Bottom makeBottom() {
        // TODO Auto-generated method stub
        return new RubberBottom();
    }
 
    @Override
    public Leather makeLeather() {
        // TODO Auto-generated method stub
        return new LeatherOfCows();
    }
 
    @Override
    public boolean hasPattern() {
        // TODO Auto-generated method stub
        return false;
    }
 
}
 
//프랑스 매장으로 가는 재료 공장
class FRShoesIngredientFactory implements ShoesIngredientFactory {
 
    @Override
    public Bottom makeBottom() {
        // TODO Auto-generated method stub
        return new PlasticAndRubberBottom();
    }
 
    @Override
    public Leather makeLeather() {
        // TODO Auto-generated method stub
        return new LeatherOfSheeps();
    }
 
    @Override
    public boolean hasPattern() {
        // TODO Auto-generated method stub
        return true;
    }
 
}
//*********재료 인터페이스*********
interface Bottom {
 
    public String getName();
 
}
 
interface Leather {
 
    public String getName();
 
}
 
//******Shoes 추상 클래스*************
abstract class Shoes {
 
    String name;
    Bottom bottom;
    Leather leather;
    boolean hasPattern;
 
    abstract void assembling();
 
    void prepare() {
 
        System.out.println("완성된 신발을 준비 중 입니다..");
    }
 
    void packing() {
 
        System.out.println("신발을 포장 하고 있습니다..");
    }
 
    public String getName() {
 
        return name;
    }
 
    public void setName(String name) {
 
        this.name = name;
    }
 
}
//********인터페이스 구현 ***********
class BlackShoes extends Shoes {
 
    ShoesIngredientFactory shoesIngredientFactory;
 
    public BlackShoes(factory_abstract_factory.ShoesIngredientFactory shoesIngredientFactory) {
        this.shoesIngredientFactory = shoesIngredientFactory;
    }
 
    @Override
    void assembling() {
        // TODO Auto-generated method stub
 
        System.out.println("신발을 만들고 있습니다.. " + name);
        leather = shoesIngredientFactory.makeLeather();
        bottom = shoesIngredientFactory.makeBottom();
        System.out.println("신발 정보 : 밑창은 " + bottom.getName() + " 사용 하였으며 가죽은 " + leather.getName() + " 사용하였음");
 
    }
 
}
 
class BrownShoes extends Shoes {
 
    ShoesIngredientFactory shoesIngredientFactory;
 
    public BrownShoes(factory_abstract_factory.ShoesIngredientFactory shoesIngredientFactory) {
        this.shoesIngredientFactory = shoesIngredientFactory;
    }
 
    @Override
    void assembling() {
        // TODO Auto-generated method stub
 
        System.out.println("신발을 만들고 있습니다.. " + name);
        leather = shoesIngredientFactory.makeLeather();
        bottom = shoesIngredientFactory.makeBottom();
        System.out.println("신발 정보 : 밑창은 " + bottom.getName() + " 사용 하였으며 가죽은 " + leather.getName() + " 사용하였음");
 
    }
 
}
 
class RedShoes extends Shoes {
 
    ShoesIngredientFactory shoesIngredientFactory;
 
    public RedShoes(factory_abstract_factory.ShoesIngredientFactory shoesIngredientFactory) {
        this.shoesIngredientFactory = shoesIngredientFactory;
    }
 
    @Override
    void assembling() {
        // TODO Auto-generated method stub
 
        System.out.println("신발을 만들고 있습니다.. " + name);
        leather = shoesIngredientFactory.makeLeather();
        bottom = shoesIngredientFactory.makeBottom();
        System.out.println("신발 정보 : 밑창은 " + bottom.getName() + " 사용 하였으며 가죽은 " + leather.getName() + " 사용하였음");
 
    }
 
}
//**********고객 주문을받을 Store 추상 클래스**********
abstract class ShoesStore {
 
    public Shoes orderShoes(String name) {
 
        Shoes shoes;
 
        shoes = makeShoes(name);
        shoes.assembling();
        shoes.prepare();
        shoes.packing();
 
        return shoes;
 
    }
 
    abstract Shoes makeShoes(String name);
 
}
 
//***************원재료 공장에서 재료를 받고, 조합 후 작업 마무리***********************
class JPShoesStore extends ShoesStore {
 
    @Override
    Shoes makeShoes(String name) {
        // TODO Auto-generated method stub
 
        Shoes shoes = null;
        ShoesIngredientFactory shoesIngredientFactory = new JPShoesIngredientFactory();
        if (name.equals("blackShoes")) {
 
            shoes = new BlackShoes(shoesIngredientFactory);
            shoes.setName("일본 스타일의 검은 구두");
 
        } else if (name.equals("brownShoes")) {
 
            shoes = new BrownShoes(shoesIngredientFactory);
            shoes.setName("일본 스타일의 갈색 구두");
        } else if (name.equals("redShoes")) {
 
            shoes = new RedShoes(shoesIngredientFactory);
            shoes.setName("일본 스타일의 빨간 구두");
        }
 
        return shoes;
 
    }
 
}
 
class FRShoesStore extends ShoesStore {
 
    @Override
    Shoes makeShoes(String name) {
        // TODO Auto-generated method stub
 
        Shoes shoes = null;
        ShoesIngredientFactory shoesIngredientFactory = new FRShoesIngredientFactory();
        if (name.equals("blackShoes")) {
 
            shoes = new BlackShoes(shoesIngredientFactory);
            shoes.setName("프랑스 스타일의 검은 구두");
 
        } else if (name.equals("brownShoes")) {
 
            shoes = new BrownShoes(shoesIngredientFactory);
            shoes.setName("프랑스 스타일의 갈색 구두");
        } else if (name.equals("redShoes")) {
 
            shoes = new RedShoes(shoesIngredientFactory);
            shoes.setName("프랑스 스타일의 빨간 구두");
        }
 
        return shoes;
 
    }
 
}
//*******************Client 주문********************
public class ShoesDrive {
 
    public static void main(String[] args) {
 
        JPShoesStore jpStore = new JPShoesStore();
        jpStore.orderShoes("blackShoes");
 
        FRShoesStore frStore = new FRShoesStore();
        frStore.orderShoes("redShoes");
 
    }
 
}