什麼是工廠模式?
工廠模式是建立型模式的一種,工廠是用來生産的,而在Java裡,是用來生産對象執行個體的。
和單例模式相似,工廠模式同樣聚焦于在考慮整個軟體建構的情況下合理建立對象,進而保證軟體的擴充性和穩定性。
工廠模式分為三種:
- 簡單工廠模式
- 工廠方法模式
- 抽象工廠模式
簡單工廠模式(實作服務端自擴充)
服務端:提供代碼的人(作者)
用戶端:使用代碼的人(使用者)
【對于程式員來說,自己是作者,使用者是普通人;那麼對于發明語言,架構的人來說,建立者是作者,而普通程式員是使用者】
假設沒有使用簡單工廠模式:
定義一個Coder接口,然後定義JavaCoder和PythonCoder實作Coder接口。用戶端通過new來建立對象。(耦合)
//服務端
interface Coder {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
//===============================================================================
public class ProductManager //用戶端
{
public static void main(String[] args) {
Coder javaCoder = new JavaCoder();
javaCoder.express();
}
}
複制
當服務端需要擴充一個類時:需要進行1,2兩步
//服務端
interface Coder {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
class GoCoder implements Coder //1.服務端擴充
{
@Override
public void express()
{
System.out.println("I am a Go Coder");
}
}
//===============================================================================
public class ProductManager //用戶端
{
public static void main(String[] args) {
Coder javaCoder = new JavaCoder();
javaCoder.express();
Coder goCoder = new GoCoder(); //2.用戶端跟着修改
goCoder.express();
}
}
複制
服務端和用戶端處于高度耦合狀态。(服務端的變化會引起用戶端的變化)
使用簡單工廠模式:(如果服務端要擴充一個GoCoder,用戶端無需做修改)
//服務端
interface Coder {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
class GoCoder implements Coder //1.服務端擴充
{
@Override
public void express()
{
System.out.println("I am a Go Coder");
}
}
class SimpleFactory
{
//使用靜态内部類實作單例模式
private static class StaticClassInnerInstance {
private static final SimpleFactory INSTANCE = new SimpleFactory();
}
public static SimpleFactory getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
public Coder createCoder(String language)
{
Coder coder = null;
if(language.equals("Java"))
{
coder= new JavaCoder();
}
else if(language.equals("Python"))
{
coder= new PythonCoder();
}
else if(language.equals("Go")) //2.擴充條件
{
coder= new GoCoder();
}
return coder;
}
}
//===============================================================================
public class ProductManager //用戶端
{
public static void main(String[] args) {
SimpleFactory factory = SimpleFactory.getInstance();
Coder javaCoder = factory.createCoder("Java");
javaCoder.express();
}
}
複制
簡單工廠UML類圖:

簡單工廠的優缺點:
優點:
解決了服務端與用戶端的耦合問題,實作了服務端的自擴充。
缺點:
當用戶端需要進行功能擴充時,無法在SimpleFactory中添加對應修改代碼。
簡單工廠可以完成服務端的自擴充,但用戶端隻能調用,無法擴充。
工廠方法模式(實作用戶端自擴充)
//服務端
interface Coder {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
class GoCoder implements Coder //1.服務端擴充
{
@Override
public void express()
{
System.out.println("I am a Go Coder");
}
}
interface CoderFactory //抽象出CoderFactory
{
public Coder createCoder(String language);
}
class ServerFactory implements CoderFactory
{
private static class StaticClassInnerInstance {
private static final ServerFactory INSTANCE = new ServerFactory();
}
public static ServerFactory getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
@Override
public Coder createCoder(String language)
{
Coder coder = null;
if(language.equals("Java"))
{
coder= new JavaCoder();
}
else if(language.equals("Python"))
{
coder= new PythonCoder();
}
else if(language.equals("Go")) //2.擴充條件
{
coder= new GoCoder();
}
return coder;
}
}
//===============================================================================
class RustCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Rust Coder");
}
}
class ClientFactory implements CoderFactory
{
private static class StaticClassInnerInstance1 {
private static final ClientFactory INSTANCE = new ClientFactory();
}
public static ClientFactory getInstance() {
return ClientFactory.StaticClassInnerInstance1.INSTANCE;
}
@Override
public Coder createCoder(String language)
{
return new RustCoder();
}
}
public class ProductManager //用戶端
{
public static void main(String[] args) {
ClientFactory clientFactory = ClientFactory.getInstance();
Coder coder = clientFactory.createCoder("Rust");
coder.express();
}
}
複制
工廠方法UML類圖:
工廠方法模式的優缺點:
優點:實作了用戶端的自擴充。
缺點:無法擴充多個産品。
抽象工廠模式(實作産品簇)
适應多個産品,加入設計師。
抽象工廠中可以生産多個産品,産品之間存在内在聯系。比如說JavaCoder對應JavaDesigner。
而執行個體化的工廠就是根據這種内在聯系來劃分的。
同一個工廠的産品屬于一個産品簇,不同産品簇之間是不能互相組合的。比如說GoDesigner和PythonCoder是不能組合到一個工廠裡的。
//服務端
interface Coder {
void express();
}
interface Designer {
void express();
}
class JavaCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Java Coder");
}
}
class PythonCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Python Coder");
}
}
class GoCoder implements Coder
{
@Override
public void express()
{
System.out.println("I am a Go Coder");
}
}
class JavaDesigner implements Designer
{
@Override
public void express()
{
System.out.println("I am a Java Designer!");
}
}
class PythonDesigner implements Designer
{
@Override
public void express()
{
System.out.println("I am a Python Designer!");
}
}
class GoDesigner implements Designer
{
@Override
public void express()
{
System.out.println("I am a Go Designer!");
}
}
interface ProductFactory
{
public Coder createCoder();
public Designer createDesigner();
}
class GoFactory implements ProductFactory
{
private static class StaticClassInnerInstance {
private static final GoFactory INSTANCE = new GoFactory();
}
public static GoFactory getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
@Override
public Coder createCoder()
{
Coder coder= new GoCoder();
return coder;
}
@Override
public Designer createDesigner()
{
Designer designer= new GoDesigner();
return designer;
}
}
class JavaFactory implements ProductFactory
{
private static class StaticClassInnerInstance {
private static final JavaFactory INSTANCE = new JavaFactory();
}
public static JavaFactory getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
@Override
public Coder createCoder()
{
Coder coder= new JavaCoder();
return coder;
}
@Override
public Designer createDesigner()
{
Designer designer= new JavaDesigner();
return designer;
}
}
//===============================================================================
public class ProductManager //用戶端
{
public static void main(String[] args) {
JavaFactory javaFactory = JavaFactory.getInstance();
Coder coder =javaFactory.createCoder();
Designer designer = javaFactory.createDesigner();
coder.express();
designer.express();
}
}
複制
抽象工廠UML類圖:
工廠模式總結
簡單工廠模式:适用用戶端無需擴充的應用場景
工廠方法模式:适合用戶端建立單個産品的應用場景
抽象工廠模式:适合建立多個産品的應用場景(但産品類别需要固定)
-------------------------------------------------------------------------------------------------------------2019.8.11