Java設計模式(一)工廠模式
目錄
1、工廠模式簡介
工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。
在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是通過使用一個共同的介面來指向新建立的物件。
2、工廠模式分類
2.1 簡單工廠模式
簡單工廠模式又 叫靜態工廠方法模式(Static FactoryMethod Pattern),是通過專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。
實現
我們將建立一個 Shape 介面和實現 Shape 介面的實體類。下一步是定義工廠類 ShapeFactory。
FactoryPatternDemo,我們的演示類使用 ShapeFactory 來獲取 Shape 物件。它將向 ShapeFactory 傳遞資訊(CIRCLE / RECTANGLE / SQUARE),以便獲取它所需物件的型別。
步驟1
建立一個介面:
//Shape.java
public interface Shape {
void draw();
}
步驟2
建立實現介面的實體類。
//Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
//Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
//Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
步驟 3
建立一個工廠,生成基於給定資訊的實體類的物件。
//ShapeFactory.java
public class ShapeFactory {
//使用 getShape 方法獲取形狀型別的物件
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
步驟 4
使用該工廠,通過傳遞型別資訊來獲取實體類的物件。
//FactoryPatternDemo.java
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//獲取 Circle 的物件,並呼叫它的 draw 方法
Shape shape1 = shapeFactory.getShape("CIRCLE");
//呼叫 Circle 的 draw 方法
shape1.draw();
//獲取 Rectangle 的物件,並呼叫它的 draw 方法
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//呼叫 Rectangle 的 draw 方法
shape2.draw();
//獲取 Square 的物件,並呼叫它的 draw 方法
Shape shape3 = shapeFactory.getShape("SQUARE");
//呼叫 Square 的 draw 方法
shape3.draw();
}
}
步驟 5
執行程式,輸出結果:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
2.2 工廠方法模式
定義了一個建立物件的介面,但由子類決定要例項化的類是哪一個,工廠方法讓類把例項化推遲到了子類。
實現
我們將建立 Shape 介面和介面的實體類。下一步是建立抽象工廠類 AbstractFactory。接著定義工廠類 ShapeFactory1和ShapeFactory2 ,兩個工廠類都擴充套件了 AbstractFactory。
AbstractFactoryPatternDemo,我們的演示類分別使用 ShapeFactory1 和 ShapeFactory2 來獲取兩個的 Shape 集合物件。
步驟 1
介面類和實體類的建立程式碼同簡單工廠模式
步驟2
為Shape 物件建立抽象類來獲取工廠。
//AbstractFactory.java
public abstract class AbstractFactory {
public abstract Shape[] getShapes() ;
}
步驟3
建立擴充套件了 AbstractFactory 的工廠類,生成Shape實體類的集合物件。
//ShapeFactory1.java
public class ShapeFactory1 extends AbstractFactory {
@Override
public Shape[] getShapes() {
return new Shape[] {new Circle(),new Square()};
}
}
//ShapeFactory2.java
public class ShapeFactory2 extends AbstractFactory {
@Override
public Shape[] getShapes() {
return new Shape[] {new Rectangle(),new Square()};
}
}
步驟 4
分別使用不同的工廠,來獲取Shape實體類的集合物件。
//AbstractFactoryPatternDemo.java
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
//獲取工廠1
ShapeFactory1 shapeFactory1 = new ShapeFactory1();
//獲取工廠1的物件集合
Shape[] shapes1 = shapeFactory1.getShapes();
System.out.println("==工廠1的物件集合==");
for(int i=0;i<shapes1.length;i++) {
//呼叫 物件 的 draw 方法
if(shapes1[i] != null) {
shapes1[i].draw();
}else {
break;
}
}
//獲取工廠2
ShapeFactory2 shapeFactory2 = new ShapeFactory2();
//獲取工廠2的物件集合
Shape[] shapes2 = shapeFactory2.getShapes();
System.out.println("==工廠2的物件集合==");
for(int i=0;i<shapes2.length;i++) {
//呼叫 物件 的 draw 方法
if(shapes2[i] != null) {
shapes2[i].draw();
}else {
break;
}
}
}
}
步驟 5
執行程式,輸出結果:
==工廠1的物件集合==
Inside Circle::draw() method.
Inside Square::draw() method.
==工廠2的物件集合==
Inside Rectangle::draw() method.
Inside Square::draw() method.
2.3 抽象工廠模式
抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠建立其他工廠。該超級工廠又稱為其他工廠的工廠。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。
在抽象工廠模式中,介面是負責建立一個相關物件的工廠,不需要顯式指定它們的類。每個生成的工廠都能按照工廠模式提供物件。
實現
我們將建立 Shape 和 Color 介面和實現這些介面的實體類。下一步是建立抽象工廠類 AbstractFactory。接著定義工廠類 ShapeFactory 和 ColorFactory,這兩個工廠類都是擴充套件了 AbstractFactory。然後建立一個工廠創造器/生成器類 FactoryProducer。
AbstractFactoryPatternDemo,我們的演示類使用 FactoryProducer 來獲取 AbstractFactory 物件。它將向 AbstractFactory 傳遞形狀資訊 Shape(CIRCLE / RECTANGLE / SQUARE),以便獲取它所需物件的型別。同時它還向 AbstractFactory 傳遞顏色資訊 Color(RED / GREEN / BLUE),以便獲取它所需物件的型別。
步驟 1
形狀介面類和實體類的建立程式碼同簡單工廠模式
步驟 3
為顏色建立一個介面。
//Color.java
public interface Color {
void fill();
}
步驟4
建立實現顏色介面的實體類。
//Red.java
public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
//Green.java
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
//Blue.java
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
步驟 5
為 Color 和 Shape 物件建立抽象類來獲取工廠。
//AbstractFactory.java
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape) ;
}
步驟 6
建立擴充套件了 AbstractFactory 的工廠類,基於給定的資訊生成實體類的物件。
//ShapeFactory.java
public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
@Override
public Color getColor(String color) {
return null;
}
}
//ColorFactory.java
public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
return null;
}
@Override
public Color getColor(String color) {
if(color == null){
return null;
}
if(color.equalsIgnoreCase("RED")){
return new Red();
} else if(color.equalsIgnoreCase("GREEN")){
return new Green();
} else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
}
return null;
}
}
步驟 7
建立一個工廠創造器/生成器類,通過傳遞形狀或顏色資訊來獲取工廠。
//FactoryProducer.java
public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
} else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}
步驟 8
使用 FactoryProducer 來獲取 AbstractFactory,通過傳遞型別資訊來獲取實體類的物件。
//AbstractFactoryPatternDemo.java
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
//獲取形狀工廠
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
//獲取形狀為 Circle 的物件
Shape shape1 = shapeFactory.getShape("CIRCLE");
//呼叫 Circle 的 draw 方法
shape1.draw();
//獲取形狀為 Rectangle 的物件
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//呼叫 Rectangle 的 draw 方法
shape2.draw();
//獲取形狀為 Square 的物件
Shape shape3 = shapeFactory.getShape("SQUARE");
//呼叫 Square 的 draw 方法
shape3.draw();
//獲取顏色工廠
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
//獲取顏色為 Red 的物件
Color color1 = colorFactory.getColor("RED");
//呼叫 Red 的 fill 方法
color1.fill();
//獲取顏色為 Green 的物件
Color color2 = colorFactory.getColor("Green");
//呼叫 Green 的 fill 方法
color2.fill();
//獲取顏色為 Blue 的物件
Color color3 = colorFactory.getColor("BLUE");
//呼叫 Blue 的 fill 方法
color3.fill();
}
}
步驟 9
執行程式,輸出結果:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.