工厂模式——简单工厂模式、工厂模式以及抽象工厂模式

背景

最近看了一篇挺有意思的漫画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 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

正如漫画中所说的那样,当一个类的初始化方法过于复杂的时候,如果直接写在这个类的构造函数里面,会使得代码的可读性可可扩展性大大降低,这个时候,工厂类应运而生。

简单工厂模式

代码例子引自菜鸟教程。

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 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();
    }
}

漫画里面提出了一种开闭原则,指出了简单工厂模式的缺点。

所谓面向对象的开放-封闭原则,就是在程序中对“扩展”开放,对“修改”封闭。如果每次业务改动都要增加新的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.");
    }
}

首先创建Shape工厂接口。

public interface ShapeFactory {
    Shape getShape();
}

三个形状工厂类,分别实现该接口。
例如圆的工厂类:

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();
    }
}

这样一来,当我想要增加一个新的形状,就只需要新增相应的工厂类即可,而无需修改原来的代码。
但是缺点也是显而易见的,这样的增加,开发难度明显增加。

抽象工厂模式

同样定义三个形状类。

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

创建抽象工厂AbstractFactoryShapeFactory继承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;
   }
}

创建工厂创造器。

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;
    }
}

这样就可以不用创建那么多的工厂类,只需要一个“工厂类创造器”就搞定了。

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

这样的好处,在于我可以随意创建各种各样的工厂,不需要局限于形状的范围,也可以创建颜色等等。

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

你可能感兴趣的:(工厂模式——简单工厂模式、工厂模式以及抽象工厂模式)