工廠模式是最常用的設計模式之一,這種類型的設計模式屬于創建型模式,它提供了一種創建對象的最佳方式。在工廠模式中,我們在創建對象時不會對客戶端暴露創建邏輯,并且是通過使用一個共同的接口來指向新創建的對象。
工廠模式分為簡單工廠模式和工廠方法模式兩種。
簡單工廠模式
簡單工廠模式主要有四種角色:
- 抽象產品角色:接口或抽象類,定義一個產品的共有屬性;
- 具體產品角色:對抽象產品的具體實現,由工廠類創建;
- 工廠類角色:創建具體產品類,產品都必須由該類實例化;
- 客戶端:創建工廠類實例,通過工廠類簡介創建產品類;
結構圖如下:
創建抽象產品角色:
public interface Shape {
void draw();
}
創建三個具體產品對象:
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("draw the Rectangle.");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("draw the Square.");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("draw the Circle.");
}
}
常見工廠類角色:
public class ShapeFactory {
public final static int TYPE_RECTANGLE = 0;
public final static int TYPE_SQUARE = 1;
public final static int TYPE_CIRLE = 2;
@Override
Shape createShape(int type) {
Shape mShape = null;
switch (type){
case TYPE_RECTANGLE:
mShape = new Rectangle();
break;
case TYPE_SQUARE:
mShape = new Square();
break;
case TYPE_CIRLE:
mShape = new Circle();
break;
}
return mShape;
}
}
客戶端代碼:
public class FactoryPartternDemo {
public static void main(String[] args){
ShapeFactory mShapeFactory = new ShapeFactory();
Shape mRectangle = mShapeFactory.createShape(ShapeFactory.TYPE_RECTANGLE);
mRectangle.draw();
Shape mSquare = mShapeFactory.createShape(ShapeFactory.TYPE_SQUARE);
mSquare.draw();
Shape mCircle = mShapeFactory.createShape(ShapeFactory.TYPE_CIRLE);
mCircle.draw();
}
}
運行后輸出
draw the Rectangle.
draw the Square.
draw the Circle.
工廠模式的優點
假設我們不使用工廠模式,要創建這三個具體產品類對象你可能會這樣寫:
public class FactoryPartternDemo {
public static void main(String[] args){
Rectangle rectangle = new Rectangle();
rectangle.draw();
Square square = new Square();
square.draw();
Circle circle = new Circle();
circle.draw();
}
}
這樣同樣是輸出了和上面一樣的輸出結果,而且代碼量減少了,看起來好像這種方式會更好是不是。如果這樣想的話你就too young too simple了。
根據依賴倒置原則:要依賴抽象,不依賴具體類。
第二種寫法客戶端FactoryPartternDemo依賴了三個具體類,如下圖:
而第一種寫法FactoryPartternDemo只依賴了抽象類Shape,它需要什么類型的對象,只需要向ShapeFactory傳入一個類型值,就能獲取到需要的對象,而不需要關心具體是什么類。
假設后面由于業務擴展,需要增加類似Oval, Rhombus等多個具體產品時,第二種寫法會隨著業務產品的增加,依賴的類也隨著增加,而第一種寫法不管增加多少業務類,它還是只依賴Shape抽象類。