工廠模式是最常用的設(shè)計(jì)模式之一虱疏,這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式毒涧,它提供了一種創(chuàng)建對(duì)象的最佳方式。在工廠模式中徙邻,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶端暴露創(chuàng)建邏輯排嫌,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng)建的對(duì)象。
工廠模式分為簡(jiǎn)單工廠模式和工廠方法模式兩種缰犁。
簡(jiǎn)單工廠模式
簡(jiǎn)單工廠模式主要有四種角色:
- 抽象產(chǎn)品角色:接口或抽象類淳地,定義一個(gè)產(chǎn)品的共有屬性怖糊;
- 具體產(chǎn)品角色:對(duì)抽象產(chǎn)品的具體實(shí)現(xiàn),由工廠類創(chuàng)建颇象;
- 工廠類角色:創(chuàng)建具體產(chǎn)品類伍伤,產(chǎn)品都必須由該類實(shí)例化;
- 客戶端:創(chuàng)建工廠類實(shí)例遣钳,通過(guò)工廠類簡(jiǎn)介創(chuàng)建產(chǎn)品類扰魂;
結(jié)構(gòu)圖如下:
創(chuàng)建抽象產(chǎn)品角色:
public interface Shape {
void draw();
}
創(chuàng)建三個(gè)具體產(chǎn)品對(duì)象:
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.");
}
}
常見(jiàn)工廠類角色:
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();
}
}
運(yùn)行后輸出
draw the Rectangle.
draw the Square.
draw the Circle.
工廠模式的優(yōu)點(diǎn)
假設(shè)我們不使用工廠模式,要?jiǎng)?chuàng)建這三個(gè)具體產(chǎn)品類對(duì)象你可能會(huì)這樣寫(xiě):
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();
}
}
這樣同樣是輸出了和上面一樣的輸出結(jié)果耍贾,而且代碼量減少了阅爽,看起來(lái)好像這種方式會(huì)更好是不是。如果這樣想的話你就too young too simple了荐开。
根據(jù)依賴倒置原則:要依賴抽象付翁,不依賴具體類。
第二種寫(xiě)法客戶端FactoryPartternDemo依賴了三個(gè)具體類晃听,如下圖:
而第一種寫(xiě)法FactoryPartternDemo只依賴了抽象類Shape百侧,它需要什么類型的對(duì)象,只需要向ShapeFactory傳入一個(gè)類型值能扒,就能獲取到需要的對(duì)象佣渴,而不需要關(guān)心具體是什么類。
假設(shè)后面由于業(yè)務(wù)擴(kuò)展初斑,需要增加類似Oval, Rhombus等多個(gè)具體產(chǎn)品時(shí)辛润,第二種寫(xiě)法會(huì)隨著業(yè)務(wù)產(chǎn)品的增加,依賴的類也隨著增加见秤,而第一種寫(xiě)法不管增加多少業(yè)務(wù)類砂竖,它還是只依賴Shape抽象類。