추상적인 공장?? 지난번에도 factory는 추상화 시켜주었는데 어떤 차이점이 있는 것일까??
지난번에 공부했던 팩토리 패턴과 어떤 차이가 있으며 무엇이 더 좋아졌는지 알아보도록 합시다.
이전 Factory Pattern에서는 추상화된 Factory만이 존재했습니다. 하지만 Abstract Factory패턴은 추상적인 Factory는 물론 부품, 제품들도 추상화하여 객체를 생성하는 패턴입니다.
한마디로 추상화된 Factory에서 추상화된 제품을 추상화된 부품을 통해서 만드는 패턴입니다.
패턴 UML
추상화된 공장 SmartPhoneFactory
추상화된 부품들 Ram, Display, Cpu 등이 있습니다.
위에 적힌 추상화된 것들을 ...Factory나 SamsungRam, LgDisplay등 으로 구현해주어서 공장등에서 실행할 수 있게 만들어줍니다. 코드를 통해서 더 자세히 설명드리겠습니다.
추상화된 부분들을 알아봅시다.
Cpu.java
package Factory; public interface Cpu { String createCpu(); }
Display.java
package Factory; public interface Display { String createDisplay(); }
Ram.java
package Factory; public interface Ram { String createRam(); }
이 부품들을 하위 클래스에 구현되어져 구체화 되며 Factory에서 호출되어 집니다.
SmartPhoneFactory.java //추상화된 Factory
package Factory; public abstract class SmartPhoneFactory { public abstract Cpu makeCpu(); public abstract Ram makeRam(); public abstract Display makeDisplay(); public String assemble(String deviceName){ StringBuilder spec = new StringBuilder(); spec.append(deviceName).append("\n"); spec.append("cpu: ").append(makeCpu().createCpu()).append("\n"); spec.append("ram: ").append(makeRam().createRam()).append("\n"); spec.append("Display: ").append(makeDisplay().createDisplay()).append("\n"); return spec.toString(); } }
assemble method는 부품들을 가져와서 조립하는 함수입니다. template패턴을 통해 구현되어있습니다.
그리고 여기서 template 패턴이 아니라 Product라는 클래스를 만들어서 활용해주어도 됩니다.
LGFactory
package Product; import Factory.Cpu; import Factory.Display; import Factory.Ram; import Factory.SmartPhoneFactory; public class LgFactory extends SmartPhoneFactory { @Override public Cpu makeCpu() { return new QualcommCpu(); }
@Override public Ram makeRam() { return new SkHynix(); }
@Override public Display makeDisplay() { return new LgDisplay(); } }
공장에서는 자기에게 맞는 각종 부품들을 만들어주어 호출해주고 있습니다.
Cpu, Ram, Display 부품들의 구현을 봅시다.
Display
package Product; import Factory.Display; public class LgDisplay implements Display { private String DEPSCRIPTION = "5.5인치 WQHD LGD IPS TFT-LCD"; @Override public String createDisplay() { return DEPSCRIPTION; } }
Cpu
package Product; import Factory.Cpu; public class QualcommCpu implements Cpu { private final String DEPSCRIPTION = "퀄컴 스냅드래곤 801"; @Override public String createCpu() { return DEPSCRIPTION; } }
Ram
package Product; import Factory.Ram; public class SkHynix implements Ram { private String DEPSCRIPTION = "2 GB LPDDR3 SDRAM"; @Override public String createRam() { return DEPSCRIPTION; } }
Samsung Factory
Lg와 달리 다른 부품들을 생산하여 호출해주고 있습니다.
package Product; import Factory.Cpu; import Factory.Display; import Factory.Ram; import Factory.SmartPhoneFactory; public class SamsungFactory extends SmartPhoneFactory { @Override public Cpu makeCpu() { return new ExinosCpu(); }
@Override public Ram makeRam() { return new SamsungRam(); }
@Override public Display makeDisplay() { return new SamsungDisplay(); } }
Exinos Cpu
package Product; import Factory.Cpu; public class ExinosCpu implements Cpu { private String DEPSCRIPTION = "삼성 엑시노스 4 Quad"; @Override public String createCpu() { return DEPSCRIPTION; } }
SamSungDisplay
package Product; import Factory.Display; public class SamsungDisplay implements Display { private String DESCRIPTION = "4.8인치 HD 삼성 HD Super AMOLED"; @Override public String createDisplay() { return DESCRIPTION; } }
SamsungRam
package Product; import Factory.Ram; public class SamsungRam implements Ram { private String DEPSCRIPTION = "2 GB LPDDR2 SDRAM"; @Override public String createRam() { return DEPSCRIPTION; } }
그리고 스마트폰 주문서를 관리 해준 후
import Factory.SmartPhoneFactory; import Product.AnotherPhoneFactory; import Product.LgFactory; import Product.SamsungFactory; public class OrderSmartPhone { public static SmartPhoneFactory makeFactory(String type){ switch(type){ case "Samsung": return new SamsungFactory(); case "LG": return new LgFactory(); default: return new AnotherPhoneFactory(); } } }
main.java
import Factory.SmartPhoneFactory; public class Main { public static void main(String[] args){ SmartPhoneFactory galaxyS3 = OrderSmartPhone.makeFactory("Samsung"); System.out.println(galaxyS3.assemble("Galaxy S3")); SmartPhoneFactory LgG3 = OrderSmartPhone.makeFactory("LG"); System.out.println(LgG3.assemble("LG G3")); } }
결과
Galaxy S3
cpu: 삼성 엑시노스 4 Quad
ram: 2 GB LPDDR2 SDRAM
Display: 4.8인치 HD 삼성 HD Super AMOLED
LG G3
cpu: 퀄컴 스냅드래곤 801
ram: 2 GB LPDDR3 SDRAM
Display: 5.5인치 WQHD LGD IPS TFT-LCD
처음에 말했던 대로 추상화된 공장에서 Lg, Samsung등의 구체적인 공장을 만들어 주었습니다. 기존의 Factory패턴에 없는 Cpu, Display, Ram등의 부품들을 추상적으로 만들어 주어서 더 구체화된 제품(객체)를 만들 수 있었습니다.
이패턴을 사용하면서 느낀 점은
장점은 Main에 변화없이 다양한 Factory를 만들고 제거할 수 있지만 부품들이 만들어지면 너무 고쳐야할점들이 많은 단점이 있습니다. 이점을 잘생각하여 만들어주면 될 것 같습니다.