Java簡單工廠模式詳細(xì)解釋
簡單工廠模式概述
1.定義:定義一個工廠類,他可以根據(jù)參數(shù)的不同返回不同類的實例,被創(chuàng)建的實例通常都具有共同的父類
2.在簡單工廠模式中用于被創(chuàng)建實例的方法通常為靜態(tài)(static)方法,因此簡單工廠模式又被成為靜態(tài)工廠方法(Static Factory Method)
3.需要什么,只需要傳入一個正確的參數(shù),就可以獲取所需要的對象,而無需知道其實現(xiàn)過程
4.例如,我開一家披薩店,當(dāng)客戶需要某種披薩并且我這家店里也能做的時候,我就會為其提供所需要的披薩(當(dāng)然是要錢的哈哈),如果其所需的我這沒有,則是另外的情況,后面會談。這時候,我這家 披薩店就可以看做工廠(Factory),而生產(chǎn)出來的披薩被成為產(chǎn)品(Product),披薩的名稱則被稱為參數(shù),工廠可以根據(jù)參數(shù)的不同返回不同的產(chǎn)品,這就是簡單工廠模式
簡單工廠模式的結(jié)構(gòu)與實現(xiàn)
結(jié)構(gòu):

1.Factory(工廠):核心部分,負(fù)責(zé)實現(xiàn)創(chuàng)建所有產(chǎn)品的內(nèi)部邏輯,工廠類可以被外界直接調(diào)用,創(chuàng)建所需對象
2.Product(抽象類產(chǎn)品):工廠類所創(chuàng)建的所有對象的父類,封裝了產(chǎn)品對象的公共方法,所有的具體產(chǎn)品為其子類對象
3.ConcreteProduct(具體產(chǎn)品):簡單工廠模式的創(chuàng)建目標(biāo),所有被創(chuàng)建的對象都是某個具體類的實例。它要實現(xiàn)抽象產(chǎn)品中聲明的抽象方法(有關(guān)抽象類)
實現(xiàn)
abstract class Product
{
public void MethName()
{
//公共方法的實現(xiàn)
}
public abstract void MethodDiff();
//聲明抽象業(yè)務(wù)方法
}
class ConcreteProductA : Product
{
public override void MethodDiff()
{
//業(yè)務(wù)方法的實現(xiàn)
}
}
class Factory
{
public static Product GetProduct(string arg)
{
Product product = null;
if(arg.Equals("A")
{
product = new ConcreteProductA();
//init
}
else if(arg.Equals("B"))
{
product = new ConcreteProductB();
//init
}
else
{
....//其他情況
}
return product;
}
}
class Program
{
static void Main(string[] args)
{
Product product;
product = Factory.GetProduct("A");//工廠類創(chuàng)建對象
Product.MethName();
product.MethodDiff();
}
}
簡單工廠模式的簡化
1.為了簡化簡單工廠模式,將抽象產(chǎn)品類和工廠類合并,將靜態(tài)工廠方法移到抽象產(chǎn)品類中

客戶端可以調(diào)用產(chǎn)品父類的靜態(tài)工廠方法,根據(jù)不同的參數(shù)創(chuàng)建不同類型的產(chǎn)品子類對象。
簡單工廠模式的優(yōu)缺點和適用環(huán)境
簡單工廠模式的優(yōu)點
(1)工廠類包含必要的邏輯判斷,可以決定在什么時候創(chuàng)建哪一個產(chǎn)品的實例??蛻舳丝梢悦獬苯觿?chuàng)建產(chǎn)品對象的職責(zé)
(2)客戶端無需知道所創(chuàng)建具體產(chǎn)品的類名,只需知道參數(shù)即可
(3)也可以引入配置文件,在不修改客戶端代碼的情況下更換和添加新的具體產(chǎn)品類。(這也是我在開始的披薩店里遇到?jīng)]有的披薩的解決情況)
簡單工廠模式的缺點
(1)工廠類集中了所有產(chǎn)品的創(chuàng)建邏輯,職責(zé)過重,一旦異常,整個系統(tǒng)將受影響
(2)使用簡單工廠模式會增加系統(tǒng)中類的個數(shù)(引入新的工廠類),增加系統(tǒng)的復(fù)雜度和理解難度
(3)系統(tǒng)擴(kuò)展困難,一旦增加新產(chǎn)品不得不修改工廠邏輯,在產(chǎn)品類型較多時,可能造成邏輯過于復(fù)雜
(4)簡單工廠模式使用了static工廠方法,造成工廠角色無法形成基于繼承的等級結(jié)構(gòu)。
簡單工廠模式的適用環(huán)境
(1)工廠類負(fù)責(zé)創(chuàng)建對的對象比較少,因為不會造成工廠方法中的業(yè)務(wù)邏輯過于復(fù)雜
(2)客戶端只知道傳入工廠類的參數(shù),對如何創(chuàng)建對象不關(guān)心
簡單案例
題目:
使用簡單工廠模式設(shè)計一個可以創(chuàng)建不同幾何圖形(Shape),如Circle,Rectangle,Triangle等繪圖工具類,每個幾何圖形均具有繪制Draw()和擦除Erase()兩個方法要求在繪制不支持的幾何圖形時,拋出一個UnsuppShapeException異常,繪制類圖并使用C#語言實現(xiàn)。
UML:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/*使用簡單工廠模式設(shè)計一個可以創(chuàng)建不同幾何圖形(Shape),如Circle,Rectangle,Triangle等繪圖工具類,每個幾何圖形均具有繪制Draw()和擦除Erase()兩個方法
* 要求在繪制不支持的幾何圖形時,拋出一個UnsuppShapeException異常,繪制類圖并使用C#語言實現(xiàn)。
*/
namespace SimpleShapeFactory
{
public interface InShape//圖形接口 抽象產(chǎn)品類
{
void Draw();
void Erase();
}
public class Circle : InShape//圓形類,具體產(chǎn)品類
{
private static int count; //生成圖形計數(shù)
string radious;
public Circle()//構(gòu)造
{
Console.WriteLine("Create Circle");
Console.WriteLine("Input the radious of Circle:");
radious = Console.ReadLine();
}
public void Draw()//實現(xiàn)接口方法
{
int Radious = int.Parse(radious);
Console.WriteLine("Display circle " + (++count) +" information:");
Console.WriteLine("Circle "+ count+ " circumference:" + 2 * Radious * 3.14159);
Console.WriteLine("Circle "+ count+" area:" + 3.14159 * Radious * Radious);
}
public void Erase()//實現(xiàn)接口方法
{
while (true)
{
Console.WriteLine("Erase current shape(y/n)?");
string choose;
choose = Console.ReadLine();
if (choose.Equals("y") || choose.Equals("Y"))
{
Console.WriteLine("Erase Circle "+count +" successfully!");
count--;
break;
}
else if (choose.Equals("n") || choose.Equals("N"))
{
Console.WriteLine("Circle "+ count+" successfully saved!");
break;
}
else
{
Console.WriteLine("Input error, re-enter!");
}
}
}
}
class Rectangle : InShape//矩形類,具體產(chǎn)品類
{
private static int count = 0;//生成圖形計數(shù)
string length;
string wideth;
public Rectangle()//構(gòu)造
{
Console.WriteLine("Create Rectangle");
Console.WriteLine("Input the length and wideth of Rectangle:");
length = Console.ReadLine();
wideth = Console.ReadLine();
}
public void Draw()//實現(xiàn)接口方法
{
int Length = int.Parse(length);
int Wideth = int.Parse(wideth);
Console.WriteLine("Display rectangle " + (++count) + " information:");
Console.WriteLine("Rectangle "+ count + "circumference:" + 2 * Length * Wideth);
Console.WriteLine("Rectangle "+ count + "area:" + Length * Wideth);
}
public void Erase()//實現(xiàn)接口方法
{
while (true)
{
Console.WriteLine("Erase current shape(y/n)?");
string choose;
choose = Console.ReadLine();
if (choose.Equals("y") || choose.Equals("Y"))
{
Console.WriteLine("Erase rectangle "+count+ "successfully!");
--count;
break;
}
else if (choose.Equals("n") || choose.Equals("N"))
{
Console.WriteLine("Rectangle "+ count+" successfully saved!");
break;
}
else
{
Console.WriteLine("Input error, re-enter!");
}
}
}
}
class Triangle : InShape//三角形類,具體產(chǎn)品類
{
private static int count = 0;//生成圖形計數(shù)
string lengtha;
string lengthb;
string lengthc;
public Triangle()//構(gòu)造
{
Console.WriteLine("Create Triangle");
Console.WriteLine("Input the lengtha ,lengthb and lengthc of Triangle:");
lengtha = Console.ReadLine();
lengthb = Console.ReadLine();
lengthc = Console.ReadLine();
}
public void Draw()//實現(xiàn)接口方法
{
int Lengtha = int.Parse(lengtha);
int Lengthb = int.Parse(lengthb);
int Lengthc = int.Parse(lengthc);
if ((Lengtha + Lengthb > Lengthc) && (Lengtha + Lengthc > Lengthb) && (Lengthb + Lengthc > Lengtha))
{
double S = (Lengtha + Lengthb + Lengthc) * 0.5;
double area = Math.Sqrt(S * (S - Lengtha) * (S - Lengthb) * (S - Lengthc));
Console.WriteLine("Display triangle "+ (++count)+" information:");
Console.WriteLine("Triangle " + count +" circumference:" + (Lengtha + Lengthb + Lengthc));
Console.WriteLine("Triangle "+ count +" area:" + area);
Erase();
}
else
{
Console.WriteLine("Create triangle failed!");
}
}
public void Erase()//實現(xiàn)接口方法
{
while (true)
{
Console.WriteLine("Erase shape(y/n)?");
string choose;
choose = Console.ReadLine();
if (choose.Equals("y") || choose.Equals("Y"))
{
Console.WriteLine("Erase tirangle " +count +" successfully!");
--count;
break;
}
else if (choose.Equals("n") || choose.Equals("N"))
{
Console.WriteLine("Triangle "+ count +" successfully saved!");
break;
}
else
{
Console.WriteLine("Input error, re-enter!");
}
}
}
}
class ShapeFactory//圖形工廠類,充當(dāng)工廠類
{
public static InShape Getshape(string type)//靜態(tài)工廠方法
{
InShape shape;
shape = null;
if (type.Equals("Circle"))
{
shape = new Circle();
Console.WriteLine("Init set Circle");
shape.Draw();
shape.Erase();
}
else if(type.Equals("Rectangle"))
{
shape = new Rectangle();
Console.WriteLine("Init set Rectangle");
shape.Draw();
shape.Erase();
}
else if (type.Equals("Triangle"))
{
shape = new Triangle();
Console.WriteLine("Init set Triangle");
shape.Draw();
}
else//異常 這里我應(yīng)該聲明調(diào)用異常處理類的,那樣會更好些
{
Console.WriteLine("UnsupportShapeException!");
Console.WriteLine("Emotional reminders :Pay 1 million$ to Alipay:132****6151 can create every shape you want!!! ");
}
return shape;
}
}
class Program//客戶端測試類
{
static void Main(string[] args)
{
while (true)
{
InShape shape;
Console.WriteLine("Please input the shape you want to create");
string str = Console.ReadLine();
shape = ShapeFactory.Getshape(str);//通過靜態(tài)工廠方法創(chuàng)建產(chǎn)品
Console.ReadLine();
}
}
}
}
運行結(jié)果:

總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java中的LinkedHashMap及LRU緩存機(jī)制詳解
這篇文章主要介紹了Java中的LinkedHashMap及LRU緩存機(jī)制詳解,LinkedHashMap繼承自HashMap,它的多種操作都是建立在HashMap操作的基礎(chǔ)上的,同HashMap不同的是,LinkedHashMap維護(hù)了一個Entry的雙向鏈表,保證了插入的Entry中的順序,需要的朋友可以參考下2023-09-09
Java使用elasticsearch基礎(chǔ)API使用案例講解
這篇文章主要介紹了Java使用elasticsearch基礎(chǔ)API使用案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
SpringBoot整合Kotlin構(gòu)建Web服務(wù)的方法示例
這篇文章主要介紹了SpringBoot整合Kotlin構(gòu)建Web服務(wù)的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02
springboot 啟動項目打印接口列表的實現(xiàn)
這篇文章主要介紹了springboot 啟動項目打印接口列表的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
Java 中Object的wait() notify() notifyAll()方法使用
這篇文章主要介紹了Java 中Object的wait() notify() notifyAll()方法使用的相關(guān)資料,需要的朋友可以參考下2017-05-05
SpringCloud-Hystrix實現(xiàn)原理總結(jié)
通過hystrix可以解決雪崩效應(yīng)問題,它提供了資源隔離、降級機(jī)制、融斷、緩存等功能。接下來通過本文給大家分享SpringCloud-Hystrix實現(xiàn)原理,感興趣的朋友一起看看吧2021-05-05
Java使用路徑通配符加載Resource與profiles配置使用詳解
這篇文章主要介紹了Java使用路徑通配符加載Resource與profiles配置使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06

