[java] Factory Method Pattern

박철진·2022년 11월 2일
0

팩토리 메소드 패턴

  • 객체 생성을 위한 패턴
  • 구체적으로 생성할 클래스를 유연하게 정할 수 있다.
  • 인터페이스(Unit, Brood)와 구현(Zerg, Terran, Protos, BroodFactory)의 분리가 가능하다.

Unit

  • 종족들에게 공통된 동작을 부여할 interface 구현부이다.
public class Unit {
	void use();
}

Zerg, Terran, Protos

  • Unit에서 정한 interface를 구현하는 종족 클래스들이다.
public class Zerg implement Unit {
	public void use() {
    	System.out.println("zerg");
    }
}
public class Terran implement Unit {
	public void use() {
    	System.out.println("Terran");
    }
}
public class Protos implement Unit {
	public void use() {
    	System.out.println("Protos");
    }
}

Brood

  • 어떤 종족을 생성할지를 결정하는 추상클래스이다.
public abstract Brood {
	public Unit creat(String name) {
    	boolean bCreateable = this.isCreateable(name);
        if(bCreateable) {
        	// 객체 생성할 메서드 호출
        	Unit unit = this.createable(name);
            postprocessUnit(name);
            return unit;
        }
    }
    public abstract boolean isCreatealbe(String name);
    public abstract Unit createable(String name);
    public abstract void postprocessUnit(String name);
}

BroodFactory

  • 내부 클래스를 만들어서 각 유닛에 대한 최대 생성 갯수와 현재 생성된 갯수를 저장한다.
  • Brood의 추상 메서드를 구현하는 클래스이다.
public class BroodFactory extends Brood {
	private class UnitData {
    	int maxCount;
        int currentCount;
        
        public UnitData(int maxCount) {
        	this.maxCount = maxCount;
        }
    }
    private HashMap<String, UnitData> repository;
    
    public BroodFactory() {
    	repository = new HashMap<String, UnitData>();
        // 종족이 생성할 수 있는 최대 생성값을 설정한다.
        repository.put("zerg", new UnitData(7);
        repository.put("terran", new UnitData(5);
        repository.put("protos". new UnitData(3);
    }
    
    // 상속 받은 추상메서드 구현
    @Override
    public boolean isCreateable(String name) {
    	UnitData unitData = repository.get(name);
        
        if(unitData == null) {
        	System.out.println(name + "알 수 없는 종족입니다.");
            return false;
        }
        
        if(unitData.currentCount >= unitData.maxCount) {
        	System.out.println(name + "더 이상 생산할 수 없습니다.);
            return false;
        }
        
        return true;
    }
    
    @Override
    public Unit createable(String name) {
    	Unit unit = null;
        if(name == "zerg") {
        	unit = new Zerg();
        }
        if(name == "terran") {
        	unit = new Terran();
        }
        if(name == "protos") {
        	unit = new Porotos();
        }
        
        return unit;
    }
    
    @Override
    public void postprocessUnit(String name) {
    	UnitData unitData = repository.get(name);
        if(unitData != null) {
        	unitData.currentCount++;
        }
    }
}

MainEntry

  • 각 종족 값을 생성해서 최대 종족 갯수와 일치하는지 확인한다.
public class MainEntry {
	public static void main(String[] args) {
    	Brood brood = new BroodFactory();
        
        Unit unit1 = brood.create("zerg");
        if(unit1 != null) {
            unit1.use();
        }
        Unit unit2 = brood.create("zerg");
        if(unit2 != null) {
            unit2.use();
        }

        brood.create("terran");
        brood.create("terran");
        brood.create("terran");
        
    }
}
profile
개발자를 위해 기록하는 습관

0개의 댓글