工廠模式——簡單工廠模式、工廠模式以及抽象工廠模式

背景

最近看了一篇挺有意思的漫畫https://blog.csdn.net/bjweimengshu/article/details/108459337?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-7.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-7.nonecase&request_id=5f6000f2dfc5717f9a0d7742,看了之后還是覺得基礎知識不牢固,所以還是寫一篇博客,學習以及分享一下工廠模式。

工廠模式

工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種類型的設計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。
在工廠模式中,我們在創(chuàng)建對象時不會對客戶端暴露創(chuàng)建邏輯,并且是通過使用一個共同的接口來指向新創(chuàng)建的對象。

正如漫畫中所說的那樣,當一個類的初始化方法過于復雜的時候,如果直接寫在這個類的構造函數(shù)里面,會使得代碼的可讀性可可擴展性大大降低,這個時候,工廠類應運而生。

簡單工廠模式

代碼例子引自菜鳥教程

public interface Shape {
    void draw();
}
public class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Circle.");
    }
}
public class Rectangle implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Rectangle.");
    }
}
public class Square implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Square.");
    }
}

分別有三個形狀,創(chuàng)建工廠類,根據(jù)需要得到想要的形狀。

public class ShapeFactory {
    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;
    }

    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();
        Shape circle = shapeFactory.getShape("CIRCLE");
        circle.draw();
    }
}

漫畫里面提出了一種開閉原則,指出了簡單工廠模式的缺點。

所謂面向對象的開放-封閉原則,就是在程序中對“擴展”開放,對“修改”封閉。如果每次業(yè)務改動都要增加新的if-else,就涉及對舊有代碼的修改,不但容易出錯,可讀性也不好。

工廠模式

為了避免上述簡單工廠模式的缺點,提出了工廠模式,工廠模式是對簡單工廠模式的進一步解耦。

public interface Shape {
    void draw();
}
public class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Circle.");
    }
}
public class Rectangle implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Rectangle.");
    }
}
public class Square implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Square.");
    }
}

首先創(chuàng)建Shape工廠接口。

public interface ShapeFactory {
    Shape getShape();
}

三個形狀工廠類,分別實現(xiàn)該接口。
例如圓的工廠類:

public class CircleFactory implements ShapeFactory {
    @Override
    public Shape getShape() {
        return new Circle();
    }
}

如何獲取想要的形狀?

public class test {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        ShapeFactory circleFactory = (ShapeFactory) Class.forName("com.zhudan.factory.factorypattern.CircleFactory").newInstance();
        Shape c = circleFactory.getShape();
        c.draw();
    }
}

這樣一來,當我想要增加一個新的形狀,就只需要新增相應的工廠類即可,而無需修改原來的代碼。
但是缺點也是顯而易見的,這樣的增加,開發(fā)難度明顯增加。

抽象工廠模式

同樣定義三個形狀類。

public interface Shape {
    void draw();
}
public class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Circle.");
    }
}
public class Rectangle implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Rectangle.");
    }
}
public class Square implements Shape{
    @Override
    public void draw() {
        System.out.println("This is Square.");
    }
}

同樣定義顏色

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.");
   }
}

public class Blue implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

創(chuàng)建抽象工廠AbstractFactory,ShapeFactory繼承AbstractFactory

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("SQUARE")){
            return new Square();
        }
        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)建工廠創(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;
    }
}

這樣就可以不用創(chuàng)建那么多的工廠類,只需要一個“工廠類創(chuàng)造器”就搞定了。

public class test {
    public static void main(String[] args) {
        AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
        Shape shape1 = shapeFactory.getShape("CIRCLE");
        shape1.draw();
        AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
        Color color1 = colorFactory.getColor("RED");
    }
}

這樣的好處,在于我可以隨意創(chuàng)建各種各樣的工廠,不需要局限于形狀的范圍,也可以創(chuàng)建顏色等等。

引自:
https://blog.csdn.net/u012156116/article/details/80857255

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容