Java

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

2019-03-20  本文已影响0人  梦想实现家_Z

1.简单工厂
先来一个简单工厂的示例:

import java.util.Objects;

public class SimpleFactoryMain {

    /**
     * Car接口
     */
    interface Car {
        /**
         * 行驶
         */
        void run();
    }

    /**
     * 奥迪车
     */
    static class AudiCar implements Car {

        @Override
        public void run() {
            System.out.println("奥迪车行驶速度150km/h");
        }
    }

    /**
     * 保时捷
     */
    static class PorscheCar implements Car {

        @Override
        public void run() {
            System.out.println("保时捷行驶速度200km/h");
        }
    }

    /**
     * 工厂接口
     */
    interface CarFactory {
        Car create(String name);
    }

    /**
     * 工厂类实现
     */
    static class DefaultCarFactory implements CarFactory {
        /**
         * 优点:
         * 对外屏蔽具体的实现细节,外界不需要关心里面的实现逻辑,使用者只需要放心的使用
         * 将生产者和消费者进行责任分割
         *
         * 缺点:
         * 无法灵活地应对产品的增加,比如后面需要增加其他的Car,无法避免修改代码的情况下实现功能,
         * 而且会造成整个实现方法越来越复杂,直至无法维护
         * @param name
         * @return
         */
        @Override
        public Car create(String name) {
            if (Objects.equals(name, "Audi")) {
                return new AudiCar();
            } else if (Objects.equals(name, "Porsche")) {
                return new PorscheCar();
            }
            return null;
        }
    }


    /**
     * 主函数
     *
     * @param args
     */
    public static void main(String[] args) {
        CarFactory carFactory = new DefaultCarFactory();
        Car car = carFactory.create("Audi");
        car.run();

        car = carFactory.create("Porsche");
        car.run();
    }
}

关于简单工厂在java中的使用,可以查看DateFormat类中的getTimeInstance()和getDateInstance()一系列方法,这是一个典型的简单工厂模式在java中的应用。DateFormat使用静态工厂方法,运用java的多态特性,如图:

//不需要关心子类SimpleDateFormat的创建细节,只需要通过静态工厂方法创建即可
DateFormat dateFormat = DateFormat.getDateInstance();

正是因为简单工厂的缺点,使用一个工厂类无法应对多样的产品变化,导致代码的维护越来越困难,脱离了设计模式的初衷。所以针对后期可能出现的多样产品,我们尝试使用一下工厂方法解决问题。

2.工厂方法
代码示例:

public class FactoryMain {

    /**
     * Car接口
     */
    interface Car {
        /**
         * 行驶
         */
        void run();
    }

    /**
     * 奥迪车
     */
    static class AudiCar implements Car {

        @Override
        public void run() {
            System.out.println("奥迪车行驶速度150km/h");
        }
    }

    /**
     * 保时捷
     */
    static class PorscheCar implements Car {

        @Override
        public void run() {
            System.out.println("保时捷行驶速度200km/h");
        }
    }

    /**
     * 工厂接口
     */
    interface CarFactory {
        /**
         * 生产车
         *
         * @return
         */
        Car create();
    }

    /**
     * 奥迪工厂类实现
     */
    static class AudiCarFactory implements CarFactory {
        /**
         * @return
         */
        @Override
        public Car create() {
            return new AudiCar();
        }
    }

    /**
     * 保时捷工厂类实现
     */
    static class PorscheCarFactory implements CarFactory {
        /**
         * @return
         */
        @Override
        public Car create() {
            return new PorscheCar();
        }
    }


    /**
     * 主函数
     *
     * @param args
     */
    public static void main(String[] args) {
        //奥迪车工厂
        CarFactory carFactory1 = new AudiCarFactory();
        Car car = carFactory1.create();
        car.run();


        /**
         * 保时捷工厂
         */
        CarFactory carFactory2 = new PorscheCarFactory();
        car = carFactory2.create();
        car.run();
    }
}

基于工厂方法的设计思想,即使有再多的产品需要加入进来,也是可以通过不断地创建对应的工厂类进行生产,完全不需要担心修改或维护非常复杂的创建逻辑。
工厂方法在jdk中的应用:

//  所有实现Collection接口的实现类都需要实现iterator()方法
//  不同的子类需要创建不同的Iterator子类
public interface Collection<E> extends Iterable<E> {

       Iterator<E> iterator();
}

3.抽象工厂
工厂方法和抽象工厂最大的区别在于,工厂方法针对于一个产品等级结构,而抽象工厂针对于多个产品等级结构。

public class AbstractFactoryMain {

    /**
     * Car接口
     */
    interface Car {
        /**
         * 行驶
         */
        void run();
    }

    /**
     * 奥迪车
     */
    static class AudiCar implements Car {

        @Override
        public void run() {
            System.out.println("奥迪车行驶速度150km/h");
        }
    }

    /**
     * 保时捷
     */
    static class PorscheCar implements Car {

        @Override
        public void run() {
            System.out.println("保时捷行驶速度200km/h");
        }
    }


    /**
     * 发动机
     */
    interface Engine {

        void run();
    }

    /**
     * 奥迪发动机
     */
    static class AudiEngine implements Engine {

        @Override
        public void run() {
            System.out.println("奥迪发动机在运行");
        }
    }

    /**
     * 保时捷发动机
     */
    static class PorscheEngine implements Engine {

        @Override
        public void run() {
            System.out.println("保时捷发动机在运行");
        }
    }


    /**
     * 工厂接口
     */
    interface CarFactory {
        /**
         * 生产车
         *
         * @return
         */
        Car createCar();

        /**
         * 生产发动机
         *
         * @return
         */
        Engine createEngine();
    }

    /**
     * 奥迪工厂类实现
     */
    static class AudiCarFactory implements CarFactory {
        /**
         * @return
         */
        @Override
        public Car createCar() {
            return new AudiCar();
        }

        @Override
        public Engine createEngine() {
            return new AudiEngine();
        }
    }

    /**
     * 保时捷工厂类实现
     */
    static class PorscheCarFactory implements CarFactory {
        /**
         * @return
         */
        @Override
        public Car createCar() {
            return new PorscheCar();
        }

        @Override
        public Engine createEngine() {
            return new PorscheEngine();
        }
    }


    /**
     * 主函数
     *
     * @param args
     */
    public static void main(String[] args) {
        //奥迪车工厂
        CarFactory carFactory1 = new AudiCarFactory();
        Car car = carFactory1.createCar();
        car.run();

        Engine engine1 = carFactory1.createEngine();
        engine1.run();


        /**
         * 保时捷工厂
         */
        CarFactory carFactory2 = new PorscheCarFactory();
        car = carFactory2.createCar();
        car.run();

        Engine engine2 = carFactory2.createEngine();
        engine2.run();
    }
}

从以上代码中可以看出,抽象工厂已经不仅仅是应对一类产品的变化了,它可以同时应对多类产品的变化。
以上是我对于简单工厂,工厂方法和抽象工厂的简单理解和认识,谢谢!

上一篇 下一篇

猜你喜欢

热点阅读