工廠模式
就是工廠---生產(chǎn)-->產(chǎn)品
在設(shè)計(jì)模式中,分為 簡(jiǎn)單工廠模式, 工廠方法模式,抽象工廠模式.
工廠模式,就是:
提供創(chuàng)建對(duì)象的功能,不需要關(guān)心具體實(shí)現(xiàn).
類似于,接口隔離(模塊和模塊):不需要知道具體的構(gòu)建過程,就能得到相應(yīng)的結(jié)果.
例如,
Bitmap bitmap=BitmapFactory.decodeXXX();
decodeXXX 其實(shí)是創(chuàng)建了不同的bitmap.不用關(guān)心如何生產(chǎn)出bitmap
簡(jiǎn)單工廠:
以生產(chǎn) 二維圖形 為例.
工廠類角色:這是本模式的核心银亲,含有一定的商業(yè)邏輯和判斷邏輯究反。在java中它往往由一個(gè)具體類實(shí)現(xiàn)鸣剪。
抽象產(chǎn)品角色:它一般是具體產(chǎn)品繼承的父類或者實(shí)現(xiàn)的接口。在java中由接口或者抽象類來(lái)實(shí)現(xiàn)亡蓉。
具體產(chǎn)品角色:工廠類所創(chuàng)建的對(duì)象就是此角色的實(shí)例撒会。在java中由一個(gè)具體類實(shí)現(xiàn)遍尺。
類圖
代碼實(shí)現(xiàn)
1.產(chǎn)品抽象類
public class Shape {
/** @pdOid 6679a38e-beee-4da3-8749-c03329cfd976 */
public void sayHello() {
// TODO: implement
}
}
2.產(chǎn)品實(shí)體類
public class Circle extends Shape {
/** @pdOid 2abc7174-03ad-4365-8fff-3265612a3185 */
private int radium;
/** @pdOid b39ccef4-0987-473b-8e7d-1b8959c50985 */
public void sayHello() {
System.out.println("Hello, I am Circle from ShapeFactory!My address is "+this.hashCode());
}
}
public class Traingle extends Shape {
/** @pdOid 4911552c-ce2f-41e3-8a8f-d342dd482e50 */
private int high;
/** @pdOid 519ef847-62d8-435b-89a7-234c2fb5fcba */
private int bottom;
/** @pdOid 433ff6ef-9fbc-44f2-b159-97d17c6153a6 */
public void sayHello() {
// TODO: implement
System.out.println("Hello, I am Traingle from ShapeFactory! My address is "+this.hashCode());
}
}
3.圖形工廠類(包括緩存模式)
public class ShapeFactory {
private static HashMap<String,Shape> shapeMap=new HashMap<>();
/**
* 簡(jiǎn)單工廠創(chuàng)建
* @param type Traingle創(chuàng)建三角形traingle,Circle創(chuàng)建圓形Circle
* @return Shape
*/
public static Shape create(String type) {
Shape shape = null;
switch (type) {
case "Traingle":
//
shape=new Traingle();
break;
case "Circle":
shape=new Circle();
break;
default:
break;
}
return shape;
}
/**
* 簡(jiǎn)單工廠創(chuàng)建---單例緩存
* @param type Traingle創(chuàng)建三角形traingle,Circle創(chuàng)建圓形Circle
* @return Shape
*/
public static Shape createSingle(String type) {
Shape shape = null;
switch (type) {
case "Traingle":
shape = getSingleFromMap(type);
break;
case "Circle":
shape = getSingleFromMap(type);
break;
default:
break;
}
return shape;
}
private static Shape getSingleFromMap(String type) {
Shape shape;
if(shapeMap.get(type)==null){
shape=new Traingle();
shapeMap.put(type, shape);
}else{
shape=shapeMap.get(type);
}
return shape;
}
}
測(cè)試類
public class Test {
public static void main(String[] args) {
System.out.println("============簡(jiǎn)單工廠模式==================");
Shape traingle =ShapeFactory.create("Traingle");
traingle.sayHello();
Shape circle =ShapeFactory.create("Circle");
circle.sayHello();
Shape traingle3 =ShapeFactory.create("Traingle");
traingle3.sayHello();
Shape circle3 =ShapeFactory.create("Circle");
circle3.sayHello();
System.out.println("============簡(jiǎn)單工廠---緩存模式==================");
Shape traingle1 =ShapeFactory.createSingle("Traingle");
traingle1.sayHello();
Shape circle1 =ShapeFactory.createSingle("Circle");
circle1.sayHello();
Shape traingle2 =ShapeFactory.createSingle("Traingle");
traingle2.sayHello();
Shape circle2 =ShapeFactory.createSingle("Circle");
circle2.sayHello();
}
}
工廠方法模式
是簡(jiǎn)單工廠模式的優(yōu)化版,
有一個(gè)工廠抽象類,然后有很多具體的工廠.
當(dāng)有新的產(chǎn)品需要生產(chǎn)時(shí)候,只需要新建一個(gè)具體工廠,就能生產(chǎn),而不是在原來(lái)的工廠中,進(jìn)行修改. 每個(gè)具體工廠類只能創(chuàng)建一個(gè)具體產(chǎn)品類的實(shí)例质蕉。 體現(xiàn)了修改關(guān)閉原則.
抽象工廠角色: 這是工廠方法模式的核心,它與應(yīng)用程序無(wú)關(guān)传睹。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類耳幢。在java中它由抽象類或者接口來(lái)實(shí)現(xiàn)。
具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼欧啤。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象睛藻。
抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實(shí)現(xiàn)的接口。在java中一般有抽象類或者接口來(lái)實(shí)現(xiàn)邢隧。
具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對(duì)象就是此角色的實(shí)例旺罢。在java中由具體的類來(lái)實(shí)現(xiàn)庄岖。
類圖舉例
代碼實(shí)現(xiàn)
1.抽象產(chǎn)品類(同簡(jiǎn)單工廠)
2.具體產(chǎn)品類(同簡(jiǎn)單工廠)
3.一個(gè)抽象工廠類
public abstract class ShapeFactory {
/** @pdOid 4a15aecb-010c-4d48-811a-92b793f6612b */
public abstract Shape create();
}
4.多個(gè)具體工廠類
public class CircleFactory extends ShapeFactory {
/** @pdOid ffffb088-9334-47a3-bfb8-f99ddd6c77a1 */
public Shape create() {
// TODO: implement
return new Circle();
}
public class TraingleFactory extends ShapeFactory {
/** @pdOid 50f4544e-9c7a-407b-9478-247f45072997 */
public Shape create() {
// TODO: implement
return new Traingle();
}
}
5.測(cè)試類
public class Test {
public static void main(String[] args) {
System.out.println("==========工廠方法模式=========");
ShapeFactory factory=new TraingleFactory();
Shape shape=factory.create();
shape.sayHello();
ShapeFactory factory1=new CircleFactory();
Shape shape1=factory1.create();
shape1.sayHello();
}
}
==========工廠方法模式=========
Hello, I am Traingle from ShapeFactory! My address is 366712642
Hello, I am Circle from ShapeFactory!My address is 1829164700
抽象工廠模式
抽象工廠模式: 多個(gè)抽象產(chǎn)品類冷冗,每個(gè)抽象產(chǎn)品類可以派生出多個(gè)具體產(chǎn)品類若厚。 一個(gè)抽象工廠類,可以派生出多個(gè)具體工廠類迫靖。 每個(gè)具體工廠類可以創(chuàng)建多個(gè)具體產(chǎn)品類的實(shí)例院峡。
類圖
代碼實(shí)現(xiàn)
1.抽象產(chǎn)品
public interface Color {
/** @pdOid a12f0089-9a07-4426-8f7e-af49aa2a79bb */
int fill();
}
public interface Shape {
/** @pdOid 5a0c95e5-55e1-471e-a61a-740a673aece8 */
int draw();
}
2.抽象工廠
public abstract class AbstractFactory {
/** @pdOid 11ac6789-7964-4e4a-87a9-a64a69a506e5 */
public abstract Color getColor(String type);
/** @pdOid 3a57f707-a85a-4703-a3ff-084c6dd11587 */
public abstract Shape getShape(String type);
}
3.實(shí)體工廠
public class ColorFactory extends AbstractFactory {
/** @pdOid 4fb42edd-3722-4c38-9e14-86435450ccc1 */
public Color getColor(String shapeType) {
// TODO: implement
if (shapeType.equals("Red")) {
return new Red();
} else if (shapeType.equals("Blue")) {
return new Blue();
}
return null;
}
@Override
public Shape getShape(String type) {
// TODO Auto-generated method stub
return null;
}
}
/** @pdOid 5f64c413-67bb-4255-9197-9fb9f9a6d502 */
public class ShapeFactory extends AbstractFactory {
/** @pdOid 4e659634-78f7-48ae-9751-d3beaf5cc550 */
public Shape getShape(String shapeType) {
if (shapeType.equals("Traingle")) {
return new Traingle();
} else if (shapeType.equals("Circle")) {
return new Circle();
}
return null;
}
@Override
public Color getColor(String shapeType) {
// TODO Auto-generated method stub
return null;
}
}
4.創(chuàng)建工廠的驅(qū)動(dòng)
public class FactoryCreator {
public static AbstractFactory createFactory(String type){
if (type.equals("Color")) {
return new ColorFactory();
} else if (type.equals("Shape")) {
return new ShapeFactory();
}
return null;
}
}
測(cè)試
public class Test {
public static void main(String[] args) {
System.out.println("==========抽象工廠模式=========");
AbstractFactory factory = FactoryCreator.createFactory("Color");
factory.getColor("Red").fill();
System.out.println("==========極限調(diào)用.感覺好帥...=========");
FactoryCreator.createFactory("Shape").getShape("Circle").draw();
}
}
==========抽象工廠模式=========
Hello, I am Red from ColrFactory!My address is 366712642
==========極限調(diào)用.感覺好帥...=========
Hello, I am Circle from ShapeFactory!My address is 1829164700
工廠總結(jié)
簡(jiǎn)單工廠模式:
0.實(shí)體產(chǎn)品:產(chǎn)品是什么,能抽象成什么.
1.要知道要什么產(chǎn)品,將產(chǎn)品抽象話,作為抽象產(chǎn)品(產(chǎn)品抽象類),
2.建一個(gè)實(shí)體工廠,準(zhǔn)備開工.
3.生產(chǎn)同一類產(chǎn)品的不同型號(hào)(就像同一種豬不同的大小,重量等).
優(yōu)點(diǎn):靈活,簡(jiǎn)單
工廠方法:
0.實(shí)體產(chǎn)品:產(chǎn)品是什么,能抽象成什么.
1.抽象產(chǎn)品:目前有一種類型,不同型號(hào)的產(chǎn)品(圖形),
2.抽象工廠:工廠要做生產(chǎn)不同圖形.
3.建立實(shí)體工廠:分別將要生產(chǎn)的同類型的產(chǎn)品,按照不同型號(hào)(三角形,圓形)分別創(chuàng)建工廠.由實(shí) 體工廠提供產(chǎn)品.
優(yōu)勢(shì):以后如果想要生產(chǎn)一個(gè)不同的產(chǎn)品,就可以直接 創(chuàng)建產(chǎn)品實(shí)體,繼承抽象工廠創(chuàng)建實(shí)體工廠,進(jìn)行生產(chǎn),而不修改其他,體現(xiàn)開閉原則
抽象工廠模式:
抽象二字,體現(xiàn)在 抽象工廠,抽象出要生產(chǎn)的產(chǎn)品種類.
當(dāng)有多種產(chǎn)品的時(shí)候(多個(gè)產(chǎn)品族),可以考慮用抽象工廠模式,用一個(gè)抽象工廠(抽象出所需要的產(chǎn)品種類),然后用多個(gè)實(shí)體工廠(建造同族中不同的產(chǎn)品).
當(dāng)有新的產(chǎn)品進(jìn)入的時(shí)候,只需要添加抽象產(chǎn)品到抽象工廠,然后創(chuàng)建相應(yīng)的工廠即可,
體現(xiàn)了依賴倒置原則 :依賴于抽象,依賴于抽象,即程序中所有的依賴關(guān)系都應(yīng)該終止于抽象類或者接口.要針對(duì)接口編程,不針對(duì)實(shí)現(xiàn)編程系宜。
優(yōu)勢(shì):針對(duì)于多種產(chǎn)品,抽象出所需產(chǎn)品即可.
缺點(diǎn):模式過于臃腫,添加產(chǎn)品要修改抽象工廠.
區(qū)別: 工廠方法模式只有一個(gè)抽象產(chǎn)品類照激,而抽象工廠模式有多個(gè)。 工廠方法模式的具體工廠類只能創(chuàng)建一個(gè)具體產(chǎn)品類的實(shí)例盹牧,而抽象工廠模式可以創(chuàng)建多個(gè)俩垃。
總而言之,
工廠模式,是利用封裝,繼承和多態(tài)屬性,實(shí)現(xiàn)父類引用指向子類對(duì)象,進(jìn)行依賴倒置,面向抽象和接口編程,實(shí)現(xiàn)同一父類下各個(gè)子類的互換,而客戶端可以毫不察覺汰寓。進(jìn)而達(dá)到 不需要知道具體的構(gòu)建過程,就能得到相應(yīng)的結(jié)果.并盡量保持對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉.
模式,就是模式,沒有必要完全遵守,適時(shí)適地,靈活運(yùn)用,才是根本..
自己愚見,未能深刻領(lǐng)悟,有不足之處,希望能一起探討.