設(shè)計(jì)模式之簡(jiǎn)單工廠鲸郊、工廠方法、抽象工廠
什么是設(shè)計(jì)模式团搞?
設(shè)計(jì)模式(Design pattern)代表了最佳的實(shí)踐严望,通常被有經(jīng)驗(yàn)的面向?qū)ο蟮能浖_(kāi)發(fā)人員所采用。設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在軟件開(kāi)發(fā)過(guò)程中面臨的一般問(wèn)題的解決方案逻恐。這些解決方案是眾多軟件開(kāi)發(fā)人員經(jīng)過(guò)相當(dāng)長(zhǎng)的一段時(shí)間的試驗(yàn)和錯(cuò)誤總結(jié)出來(lái)的像吻。
簡(jiǎn)單工廠模式
簡(jiǎn)單工廠模式(Simple Factory Pattern)是 Java 中最常用的設(shè)計(jì)模式之一。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式复隆,它提供了一種創(chuàng)建對(duì)象的方式拨匆。
在簡(jiǎn)單工廠模式中,包含必要的判斷邏輯挽拂,簡(jiǎn)單工廠實(shí)現(xiàn)了對(duì)象的創(chuàng)建和分離惭每。
在不修改任何客戶(hù)端代碼的情況下更換和增加新的具體產(chǎn)品類(lèi),在一定程度上提高了系統(tǒng)的靈活性亏栈。
何時(shí)使用:
我們明確地計(jì)劃不同條件下創(chuàng)建不同實(shí)例時(shí)台腥。
缺點(diǎn):
(1)工廠類(lèi)的職責(zé)過(guò)重,從類(lèi)圖中可以看出簡(jiǎn)單工廠中包含加減乘除的邏輯判斷語(yǔ)句绒北,它一旦有問(wèn)題打毛,整個(gè)系統(tǒng)都要出問(wèn)題
(2)在添加新的類(lèi)的時(shí)候沿后,例如我添加了開(kāi)根號(hào)運(yùn)算是尔,那么系統(tǒng)中的簡(jiǎn)單工廠類(lèi)就要修改烙样,違反了開(kāi)放——封閉原則贴汪!這樣及其不利于系統(tǒng)的擴(kuò)展和維護(hù)!
(3)簡(jiǎn)單工廠的靜態(tài)方法休吠,使得工廠角色無(wú)法形成基于繼承的等級(jí)結(jié)構(gòu)扳埂!
實(shí)例:
畫(huà)圓形
Shape shape= ShapeFactory.getShape("circle");
shape.draw();
畫(huà)正方形
Shape shape= ShapeFactory.getShape("rect");
shape.draw();
畫(huà)三角形
Shape shape= ShapeFactory.getShape("triangle");
shape.draw();
其中,Shape為interface或者抽象類(lèi)瘤礁,包括了draw()方法阳懂。ShapeFactory(工廠)肯定是一個(gè)類(lèi),getShape是其靜態(tài)方法蔚携,所以可以直接調(diào)用希太。圓形、正方形酝蜒、三角形,都是實(shí)現(xiàn)了Shape接口/抽象類(lèi)的對(duì)應(yīng)子類(lèi)矾湃。
工廠
public class ShapeFactory {
public static final String TAG = "ShapeFactory";
public static Shape getShape(String type) {
Shape shape = null;
if (type.equalsIgnoreCase("circle")) {
shape = new CircleShape();
} else if (type.equalsIgnoreCase("rect")) {
shape = new RectShape();
} else if (type.equalsIgnoreCase("triangle")) {
shape = new TriangleShape();
}
return shape;
}
}
工廠方法模式
工廠模式(Factory Pattern)是 Java 中最常用的設(shè)計(jì)模式之一亡脑。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式邀跃。
在工廠模式中霉咨,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶(hù)端暴露創(chuàng)建邏輯,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng)建的對(duì)象拍屑。
在增加修改新的運(yùn)算類(lèi)的時(shí)候不用修改代碼途戒,只需要增加對(duì)應(yīng)的工廠就好,完全符合開(kāi)放——封閉性原則僵驰。
并且創(chuàng)建對(duì)象的細(xì)節(jié)完全封裝在具體的工廠內(nèi)部喷斋,而且有了抽象的工廠類(lèi),所有的具體工廠都繼承了自己的父類(lèi)蒜茴,體現(xiàn)了多態(tài)性星爪。
何時(shí)使用:
我們明確地計(jì)劃不同條件下創(chuàng)建不同實(shí)例時(shí)。
缺點(diǎn):
(1)在增加新的產(chǎn)品時(shí)粉私,也必須增加新的工廠類(lèi)顽腾,會(huì)帶來(lái)額外的開(kāi)銷(xiāo)
(2)抽象層的加入使得理解程度加大
實(shí)例:
工廠:
public interface ShapeFactory{
void draw();
}
具體工廠(圓形)
public class CircleFactory implements ShapeFactory{
void draw(){
/*具體實(shí)現(xiàn)*/
}
}
具體工廠(正方形)
public class RectFactory implements ShapeFactory{
void draw(){
/*具體實(shí)現(xiàn)*/
}
}
具體工廠(三角形)
public class TriangleFactory implements ShapeFactory{
void draw(){
/*具體實(shí)現(xiàn)*/
}
}
畫(huà)圓形
ShapeFactory factory= new CircleFactory();
Shape shape = factory.getShape();
shape.draw();
畫(huà)正方形
ShapeFactory factory= new RectFactory();
Shape shape = factory.getShape();
shape.draw();
畫(huà)三角形
ShapeFactory factory= new TriangleFactory();
Shape shape = factory.getShape();
shape.draw();
“工廠方法模式讓一個(gè)類(lèi)的實(shí)例化延遲到其子類(lèi)”其實(shí)指的是,工廠方法模式先需要實(shí)例化工廠诺核,然后才能用該工廠實(shí)例造對(duì)應(yīng)的實(shí)例抄肖。而不是直接通過(guò)工廠類(lèi)+靜態(tài)方法來(lái)造實(shí)例。
抽象工廠模式
抽象工廠模式(Abstract Factory Pattern)是圍繞一個(gè)超級(jí)工廠創(chuàng)建其他工廠窖杀。該超級(jí)工廠又稱(chēng)為其他工廠的工廠漓摩。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式陈瘦。
在抽象工廠模式中幌甘,接口是負(fù)責(zé)創(chuàng)建一個(gè)相關(guān)對(duì)象的工廠潮售,不需要顯式指定它們的類(lèi)。每個(gè)生成的工廠都能按照工廠模式提供對(duì)象锅风。
抽象工廠模式除了具有工廠方法模式的優(yōu)點(diǎn)外酥诽,最主要的優(yōu)點(diǎn)就是可以在類(lèi)的內(nèi)部對(duì)產(chǎn)品族進(jìn)行約束。所謂的產(chǎn)品族皱埠,一般或多或少的都存在一定的關(guān)聯(lián)肮帐,抽象工廠模式就可以在類(lèi)內(nèi)部對(duì)產(chǎn)品族的關(guān)聯(lián)關(guān)系進(jìn)行定義和描述,而不必專(zhuān)門(mén)引入一個(gè)新的類(lèi)來(lái)進(jìn)行管理边器。
何時(shí)使用:
系統(tǒng)的產(chǎn)品有多于一個(gè)的產(chǎn)品族训枢,而系統(tǒng)只消費(fèi)其中某一族的產(chǎn)品。
缺點(diǎn):
產(chǎn)品族的擴(kuò)展將是一件十分費(fèi)力的事情忘巧,假如產(chǎn)品族中需要增加一個(gè)新的產(chǎn)品恒界,則幾乎所有的工廠類(lèi)都需要進(jìn)行修改。所以使用抽象工廠模式時(shí)砚嘴,對(duì)產(chǎn)品等級(jí)結(jié)構(gòu)的劃分是非常重要的十酣。
實(shí)例:
圖形接口:
public interface Shape{
void draw();
}
畫(huà)圓形
public class Circle implements Shape{
@Override
void draw(){
/*具體實(shí)現(xiàn)*/
}
}
畫(huà)正方形
public class Rectanglet implements Shape{
@Override
void draw(){
/*具體實(shí)現(xiàn)*/
}
}
畫(huà)三角形
public class Triangle implements Shape{
@Override
void draw(){
/*具體實(shí)現(xiàn)*/
}
}
顏色接口
public interface Color {
void fill();
}
紅色
public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
綠色
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
藍(lán)色
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
抽象工廠
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape) ;
}
圖形工廠
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("triangle")){
return new Triangle();
}
return null;
}
@Override
public Color getColor(String color) {
return null;
}
}
顏色工廠
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;
}
}
工廠創(chuàng)造器
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;
}
}
Test
public class Test {
public static void main(String[] args) {
//獲取形狀工廠
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
//獲取形狀為 Circle 的對(duì)象
Shape shape1 = shapeFactory.getShape("circle");
//調(diào)用 Circle 的 draw 方法
shape1.draw();
//獲取形狀為 Rectangle 的對(duì)象
Shape shape2 = shapeFactory.getShape("rectangle");
//調(diào)用 Rectangle 的 draw 方法
shape2.draw();
//獲取形狀為 Triangle 的對(duì)象
Shape shape3 = shapeFactory.getShape("triangle");
//調(diào)用 Triangle 的 draw 方法
shape3.draw();
//獲取顏色工廠
AbstractFactory colorFactory = FactoryProducer.getFactory("color");
//獲取顏色為 Red 的對(duì)象
Color color1 = colorFactory.getColor("red");
//調(diào)用 Red 的 fill 方法
color1.fill();
//獲取顏色為 Green 的對(duì)象
Color color2 = colorFactory.getColor("green")
//調(diào)用 Green 的 fill 方法
color2.fill();
//獲取顏色為 Blue 的對(duì)象
Color color3 = colorFactory.getColor("blue");
//調(diào)用 Blue 的 fill 方法
color3.fill();
}
}
抽象工廠中,一個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成一起工作時(shí)际长,它能保證客戶(hù)端始終只使用同一個(gè)產(chǎn)品族中的對(duì)象耸采。