(5)工厂方法模式

定义

定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法模式是创建型设计模式


一个普通的例子

  • 工厂和产品的关系

UML图

(5)工厂方法模式_第1张图片
工厂方法模式

源代码

  • 普通模式
    1. 普通的类与抽象类调用
  • 常用模式
    范型和反射构造的,类似这样
public  T createAudiCar(Class clz) {
        AudiCar car = null;
        try {
            //用反射构造具体的AudiCar对象
            car = (AudiCar) Class.forName(clz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) car;
    }

例子

一、普通模式

普通的抽象类和类调用的方式

  1. 抽象产品类
/** 抽象产品类
 * Created by Niwa on 2017/7/22.
 */
public abstract class Product {
    /**
     *  产品类的抽象方法
     *  由具体的产品类去实现
     *
     * */
    public abstract void method();
}
  1. 具体产品类A
/** 具体产品类A
 * Created by Niwa on 2017/7/22.
 */
public class ConcreteProductA extends Product{
    public ConcreteProductA() {
    }

    @Override
    public void method() {
        System.out.println("我是具体的产品类A");
    }
}

  1. 具体产品类B
/** 具体产品类B
 * Created by Niwa on 2017/7/22.
 */
public class ConcreteProductB extends Product{
    public ConcreteProductB() {
    }

    @Override
    public void method() {
        System.out.println("我是具体的产品类A");
    }
}
  1. 抽象工厂类
/**
 * 抽象工厂类
 * Created by Niwa on 2017/7/22.
 */
public abstract class Factory {
    /**
     * 抽象工厂方法
     * 具体生成什么由子类去实现
     *
     * @return 具体的产品类
     */
    public abstract Product createProduct();
}

  1. 具体的工厂类,关键在这里头,生成什么产品的方法
/** 具体的工厂类
 * Created by Niwa on 2017/7/22.
 */
public class ConcreteFactory extends Factory {

    @Override
    public Product createProduct() {
        return new ConcreteProductA();
//        return new ConcreteProductB();
    }
}
  1. 测试
 public static void main(String[] args){
        Factory factory = new ConcreteFactory();
        ConcreteProductA concreteProductA = (ConcreteProductA) factory.createProduct();
        concreteProductA.method();
    }


结果:

我是具体的产品类A

二、反射构造模式

奥迪Q5,Q7和工厂的故事

  1. 奥迪汽车抽象产品类
/** 奥迪汽车抽象产品类
 * Created by Niwa on 2017/7/25.
 */
public abstract class AudiCar {
    /**
     *  车开走方法
     *
     * */
    public abstract void drive();

    /**
     *  车自动导航
     *
     * */
    public abstract void selfNavigation();

}

  1. Q5和Q7

/**
 * 奥迪汽车具体产品类Q5
 * Created by Niwa on 2017/7/25.
 */
public class AudiQ5 extends AudiCar {
    @Override
    public void drive() {
        System.out.println("Q5启动");
    }

    @Override
    public void selfNavigation() {
        System.out.println("Q5开始自动导航");
    }
}
/**
 * 奥迪汽车具体产品类Q7
 * Created by Niwa on 2017/7/25.
 */
public class AudiQ7 extends AudiCar {
    @Override
    public void drive() {
        System.out.println("Q7启动");
    }

    @Override
    public void selfNavigation() {
        System.out.println("Q7开始自动导航");
    }
}

  1. 奥迪的抽象工厂类
/**
 * 奥迪的抽象工厂类
 * Created by Niwa on 2017/7/25.
 */
public abstract class AudiFactory {
    /**
     * 这里的范型指定很关键
     * 某车型的工厂方法,创建某车型对象
     *
     * @param clz 具体的suv 型号类型
     * @return 具体型号的suv车对象
     */
    public abstract  T createAudiCar(Class clz);
}
  1. 具体的奥迪汽车工厂,关键在这里,反射构造具体的AudiCar对象

/**
 * 具体的奥迪汽车工厂
 * Created by Niwa on 2017/7/25.
 */
public class AudiCarFactory extends AudiFactory {
    @Override
    public  T createAudiCar(Class clz) {
        AudiCar car = null;
        try {
            //用反射构造具体的AudiCar对象
            car = (AudiCar) Class.forName(clz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) car;
    }
}
  1. 测试,

public static void main(String[] a){
        //构造一个制造汽车的工厂对象
        AudiCarFactory audiCarFactory = new AudiCarFactory();

        //生产Q5
        AudiQ5 audiQ5 = audiCarFactory.createAudiCar(AudiQ5.class);
        audiQ5.drive();
        audiQ5.selfNavigation();

        //生产Q7
        AudiQ7 audiQ7 = audiCarFactory.createAudiCar(AudiQ7.class);
        audiQ7.drive();
        audiQ7.selfNavigation();

    }


结果:

Q5启动
Q5开始自动导航
Q7启动
Q7开始自动导航

源代码:DesignPattern



参考

《Android源码设计模式解析与实战读书》
各大佬博客


end

你可能感兴趣的:((5)工厂方法模式)