简单工厂、工厂方法和抽象工厂

前言

在学习设计模式之前,可以先学习面向对象设计原则之六原则一法则,他们与设计模式互为表里,一脉相承。
另外,工厂设计模式也广泛应用到如Spring源码、JDK源码、实际生产工程中。

简单工厂

适用范围:当多个地方需要创建 “有共同特征的” 实例的时候
具体实现:把一类对象的实例化放到一个工厂中,当工厂持有者需要创建实例时,只要向工厂对象中拿就可以了,具体工厂对象能够提供多少种实例、实例的创建过程需要什么繁杂操作,工厂持有者并不需要关心。
举例
有三种产品,用户从控制台输入产品类型,然后系统返回对应型号的产品。

使用简单工厂模式的代码如下:

package com.zenghui.factory.pattern;

import java.util.Scanner;

public class SimpleFactoryDemo {
    public static void main(String[] args) {
        SimpleFactory simpleFactory = new SimpleFactory();
        Scanner input = new Scanner(System.in);

        System.out.println("第一个产品,产品类型:");
        int type1 = input.nextInt();
        System.out.print("生产产品:");
        System.out.println(simpleFactory.createProduct(type1));

        System.out.println("第二个产品,产品类型:");
        int type2 = input.nextInt();
        System.out.print("生产产品:");
        System.out.println(simpleFactory.createProduct(type2));
    }

}

interface Product {
}
class ConcreteProduct implements Product {
}
class ConcreteProduct1 implements Product {
}
class ConcreteProduct2 implements Product {
}

class SimpleFactory {
    public Product createProduct(int type){
        if (type ==1 ){
            return new ConcreteProduct1();
        }else if (type == 2){
            return new ConcreteProduct2();
        }else {
            return new ConcreteProduct();
        }
    }
}

如果不使用工厂模式会出现什么问题

如果不使用工厂模式,那么可以在main函数里面写两次判断,main代码如下:

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        Product product1;
        System.out.println("第一个产品,产品类型:");
        int type2 = input.nextInt();
        System.out.print("生产产品:");
        if (type2 ==1 ){
            product1 =  new ConcreteProduct1();
        }else if (type2 == 2){
            product1 =  new ConcreteProduct2();
        }else {
            product1 =  new ConcreteProduct();
        }
        System.out.println(product1);
        
        Product product2;
        System.out.println("第二个产品,产品类型:");
        int type2 = input.nextInt();
        System.out.print("生产产品:");
        if (type2 ==1 ){
            product2 =  new ConcreteProduct1();
        }else if (type2 == 2){
            product2 =  new ConcreteProduct2();
        }else {
            product2 =  new ConcreteProduct();
        }
        System.out.println(product2);
    }

这里出现了代码的重复,同样逻辑的代码写了两次。
造成的问题就是:

  1. 代码冗余,同样的逻辑写了多次,事不过三,三则重构
  2. 新增一个产品时需要修改多个地方
  3. 违背最少知识原则、单一职责原则

工厂方法

工厂方法其实就是继承和多态的一个应用。
OOP特性——继承,可以让父类的代码复用
OOP特性——多态,可以让方法动态绑定

package com.zenghui.factory.pattern;

public class FactoryMethodDemo {
   public static void main(String[] args) {
       System.out.println("生产产品1,并包装:");
       Factory concreteFactory1 = new ConcreteFactory1();
       Factory concreteFactory2 = new ConcreteFactory2();
       Product product = concreteFactory1.factoryMethod();
       concreteFactory1.createAndWrap();
       System.out.println();
       System.out.println("生产产品2,并包装:");
       concreteFactory2.createAndWrap();
   }
}


abstract class Factory{
   abstract Product factoryMethod();

   public void createAndWrap(){
       Product product = factoryMethod();
       System.out.println("创建产品:" + product);
       System.out.println("。。。。包装完成!");
   }
}

class ConcreteFactory extends Factory {
   public Product factoryMethod() {
       return new ConcreteProduct();
   }
}
class ConcreteFactory1 extends Factory {
   public Product factoryMethod() {
       return new ConcreteProduct1();
   }
}
class ConcreteFactory2 extends Factory {
   public Product factoryMethod() {
       return new ConcreteProduct2();
   }
}

如果不使用工厂方法会出现什么问题

不使用工厂方法,那么每个Factory的子类都要写一遍createAndWrap()方法。

抽象工厂

抽象工厂像是简单工厂和工厂方法的结合。
他像简单工厂一样,可以创建不同对象。
他像工厂方法一样,继承抽象类,让子类工厂有不同的实现

抽象工厂的作用是创建不同系列的产品,比如把产品分为1系列和2系列:

package com.zenghui.factory.pattern;

public class AbstractFactoryDemo {
   public static void main(String[] args) {
       AbstractFactory abstractFactory = new ConcreteFactoryD1();
       AbstractProductA productA = abstractFactory.createProductA();
       AbstractProductB productB = abstractFactory.createProductB();
       // do something with productA and productB
   }
}

class AbstractProductA {
}
class AbstractProductB {
}
class ProductA1 extends AbstractProductA {
}
class ProductA2 extends AbstractProductA {
}
class ProductB1 extends AbstractProductB {
}
class ProductB2 extends AbstractProductB {
}
abstract class AbstractFactory {
   abstract AbstractProductA createProductA();
   abstract AbstractProductB createProductB();
}
class ConcreteFactoryD1 extends AbstractFactory {
   AbstractProductA createProductA() {
       return new ProductA1();
   }

   AbstractProductB createProductB() {
       return new ProductB1();
   }
}
class ConcreteFactoryD2 extends AbstractFactory {
   AbstractProductA createProductA() {
       return new ProductA2();
   }

   AbstractProductB createProductB() {
       return new ProductB2();
   }
}

你可能感兴趣的:(简单工厂,工厂方法,抽象工厂,设计模式)