• 工厂模式


    目录

    1. 简单工厂

    2. 工厂方法

    3. 抽象工厂

    简单工厂

      定义:

      提供一个创建对象实例的功能,而无需关心具体的实现。被创建的实例对象可以是接口,抽象类,也可以是具体的类

      角色:

      工厂(creator)角色

        简单工厂的核心,负责具体类的创建,实现创建对象的内部逻辑,返回抽象产品角色。工厂类创建产品的方法可以被外界直接调用,创建所需要的对象。

      抽象(Product)产品角色

        简单工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。

      具体(ConcreteProduct)产品角色

        是简单工厂创建的目标,所创建的对象都是具体类的实例。

      实现:

      以person为例,具体产品为man,women,工厂角色为personFactory

    package com.lxlyq.factoryPattern.simpleFactory;
    /**
     * 抽象产品
     */
    public abstract class Person {
        private String name;
        private String age;
        public abstract void seeName();
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    }

      

    package com.lxlyq.factoryPattern.simpleFactory;
    
    public class Man extends Person {
        public Man() {}
        public Man(String name){
            this.setName(name);
        }
        @Override
        public void seeName() {
            System.out.println(this.getName());
        }
    }
    

      

    package com.lxlyq.factoryPattern.simpleFactory;
    
    public class Women extends Person {
        public Women(){}
        public Women(String name) {
            this.setName(name);
        }
        @Override
        public void seeName() {
            System.out.println(this.getName());
        }
    }
    

      

    package com.lxlyq.factoryPattern.simpleFactory;
    
    /**
     * 提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类
     */
    public class PersonFactory {
        public static final  int MAN = 1;
        public static final int WOMEN = 2;
        public Person createMan(int type, String name) {
            switch (type) {
                case MAN:
                    return new Man(name);
                case WOMEN:
                    return new Women(name);
                default:
                    throw new RuntimeException("don't has type");
            }
        }
    }
    

      客服端调用

    package com.lxlyq.factoryPattern.simpleFactory;
    
    public class SimpleFactoryDemo {
        public static void main(String[] args) {
            Person man = new PersonFactory().createMan(PersonFactory.MAN, "women");
            man.seeName();
        }
    }
    

     优缺点

      优点:

        客户端只需创建一个工厂,而不用担心对象具体怎么实现。

      缺点:

        每次增加一个产品时,都需要更改工厂类,增加case或elseif判断创建新的产品对象,使得维护变得困难。

      使用场景

    • 工厂类负责创建的对象比较少;
    • 客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
    • 由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
          注:工厂类应该只有一个,实际应用应该考虑成单例。

    工厂方法

      定义:

           工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。

      角色:

      抽象工厂(creator)角色

        工厂方法的核心,与应用程序无关。提供一公共接口创建抽象产品方法,具体的实现由具体工厂实现。

      具体工厂(ConcreateCreator)角色

        对应简单工厂的工厂类,负责具体类的创建,实现创建对象的内部逻辑,返回抽象产品角色。工厂类创建产品的方法可以被外界直接调用,创建所需要的对象。但是不同的是,一个具体工厂只创建一个产品。所有的具体工厂都必须实现抽象工厂类。

      抽象产品(Product)角色

        具体工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。抽象工厂返回的类型。

      具体产品(ConcreteProduct)角色

        这个角色实现了抽象产品角色所定义的公共接口。具体工厂创建的目标,所创建的对象都是具体类的实例。

      实现:

      以汽车工厂为例,有宝马工厂,有奔驰工厂,汽车抽象类,奔驰,宝马,具体如下

    package com.lxlyq.factoryPattern.factoryMethod;
    /**
     * 抽象产品
     */
    public abstract class Car {
        private String name;
        public abstract void driver();
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    

      

    package com.lxlyq.factoryPattern.factoryMethod;
    
    /**
     * 宝马
     */
    public class BaoMaCar extends Car {
        {
            this.setName("baoMaCar");
        }
        @Override
        public void driver() {
            System.out.println(this.getName());
        }
    }
    

      

    package com.lxlyq.factoryPattern.factoryMethod;
    
    /**
     * 奔驰
     */
    public class BenCiCar extends Car {
        {
            this.setName("benCiCar");
        }
        @Override
        public void driver() {
            System.out.println(this.getName());
        }
    }
    

      

    package com.lxlyq.factoryPattern.factoryMethod;
    /**
     * 工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
     */
    
    public abstract class CarFactory {
        private String carName;
        public abstract Car createCar();
        public String getCarName() {
            return carName;
        }
        public void setCarName(String carName) {
            this.carName = carName;
        }
    }
    

      

    package com.lxlyq.factoryPattern.factoryMethod;
    
    /**
     * 奔驰工厂
     */
    public class BenCiFactory extends CarFactory {
        {
            this.setCarName("benCi");
        }
        @Override
        public Car createCar() {
            return new BenCiCar();
        }
    }
    

      

    package com.lxlyq.factoryPattern.factoryMethod;
    
    /**
     * 宝马工厂
     */
    public class BaoMaFactory extends CarFactory {
        {
            this.setCarName("baoMa");
        }
        @Override
        public Car createCar() {
            return new BaoMaCar();
        }
    }
    

      

    package com.lxlyq.factoryPattern.factoryMethod;
    
    /**
     * 测试
     */
    public class FactoryMethodDemo {
        public static void main(String[] args) {
            Car baoMaCar = new BaoMaFactory().createCar();
            baoMaCar.driver();
            Car benCiCar = new BenCiFactory().createCar();
            benCiCar.driver();
        }
    }
    

      

     优缺点

      优点:

        客户端不需要知道具体的产品,只有知道产品对应的工厂类。

        增加一个产品只用增加一个具体工厂实现抽象工厂,增加一个具体产品实现抽象产品,而不用处理以前的代码,符合开闭原则。

      缺点:

        产品与工厂类都是成对出现,这使得系统中的类越来越多。

      使用场景

    • 对于某个产品,调用者清楚需要实例化那个具体工厂来生产需要使用的实例;
    • 调用方只是需要一种产品,而不想知道也不需要知道它由那个工厂生产。由生产者根据系统环境或其他条件创建一个工厂返回给调用方,调用方通过工厂创建对象,这个决策对于调用方是透明的;
          注:具体工厂类应该只有一个,实际应用应该考虑成单例。

    抽象工厂

    定义:

          抽象工厂模式(Abstract Factory),提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。抽象工厂模式也称Kit模式,它属于类创建型模式。

      角色:

      抽象工厂(creator)角色

        抽象工厂的核心,它包含多个创建产品的方法 ,可以创建多个不同等级的产品。所有需要创建的不同等级的产品都需要在工厂中定义一个方法。

      具体工厂(ConcreateCreator)角色

        实现了抽象工厂的抽象方法,完成了具体产品的创建。具体工厂创建的产品应该至少2个。

      抽象产品(Product)角色

        具体工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。抽象工厂返回的类型。

      具体产品(ConcreteProduct)角色

        这个角色实现了抽象产品角色所定义的公共接口。具体工厂创建的目标,所创建的对象都是具体类的实例。

      实现:

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    /**
     * 抽象产品
     */
    public interface Shape {
        void draw();
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    /**
     * 产品种类
     */
    public abstract class Circle implements Shape {
        @Override
        public abstract void draw();
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    /**
     * 产品种类
     */
    public abstract class Rectangle implements Shape {
        @Override
        public abstract void draw();
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    /**
     * 不同等级
     */
    public class BlueCircle extends Circle {
        @Override
        public void draw() {
            System.out.println("blueCircle");
        }
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    public class BlueRectangle extends Rectangle {
        @Override
        public void draw() {
            System.out.println("blueRectangle");
        }
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    public class RedCircle extends Circle {
        @Override
        public void draw() {
            System.out.println("draw redCircle");
        }
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    public class RedRectangle extends Rectangle {
        @Override
        public void draw() {
            System.out.println("draw RedRectangle");
        }
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    /**
     * 抽象工厂模式(Abstract Factory),提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。
     * 抽象工厂模式也称Kit模式,它属于类创建型模式。
     */
    public interface ShapeFactory {
        Shape getCircle();
        Shape getRectangle();
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    /**
     * 产品族1工厂
     */
    public class BlueShapeFactory implements ShapeFactory {
        @Override
        public Shape getCircle() {
            return new BlueCircle();
        }
    
        @Override
        public Shape getRectangle() {
            return new BlueRectangle();
        }
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    /**
     * 产品族2工厂
     */
    public class RedShapeFactory implements  ShapeFactory{
    
        @Override
        public Shape getCircle() {
            return new RedCircle();
        }
    
        @Override
        public Shape getRectangle() {
            return new RedRectangle();
        }
    }
    

      

    package com.lxlyq.factoryPattern.abstractFactory;
    
    public class AbstractFactoryDemo {
        public static void main(String[] args) {
            ShapeFactory blueShapeFactory = new BlueShapeFactory();
            Shape circle = blueShapeFactory.getCircle();
            Shape rectangle = blueShapeFactory.getRectangle();
            circle.draw();
            rectangle.draw();
            // 切换工厂
            ShapeFactory redShapeFactory = new RedShapeFactory();
            circle = redShapeFactory.getCircle();
            rectangle = redShapeFactory.getRectangle();
            circle.draw();
            rectangle.draw();
        }
    }
    

      从demo中知道,我们切管产品族只需要切换工厂即可。

     优缺点

      优点:

        它分离了具体的类;

        它使得易于交换产品系列;

        它有利于产品的一致性;

        增加一个产品产品族只用增加一个具体工厂实现抽象工厂,增加具体产品实现抽象产品,而不用处理以前的代码,符合开闭原则。

      缺点:

        当新增一个产品种类时,(新增一个多边形),那么需要在抽象工厂中增加一个创建多边形的方法,从而之前写的所有具体工厂都需要变动,不符合开闭原则(难以支持新种类的产品)。

      使用场景

    • 抽象工厂模式最早的应用是用于创建属于不同操作系统的视窗构件。
    • 当我们需要多个产品族,而每次只单独使用其中一个产品族时(如操作系统中的控件,产品族分为Linux,windows,有linux按钮,windows按钮,linux文本,windows文本等。我们需要根据系统来切换不同的产品族,达到使用不同系统的控件)。
          注:具体工厂类应该只有一个,实际应用应该考虑成单例。

    总结:

      工厂模式帮我们统一生产对象,我们不需要知道对象具体生成逻辑。使得对象的创建与使用解耦。

  • 相关阅读:
    C#计算两个时间年份月份天数(根据生日计算年龄)差,求时间间隔
    C#四舍五入保留一位小数
    给Editplus去掉.bak文件
    $().each() 与 $.each()解析
    VS 2013+Qt 5.4.1
    HDU 5228 ZCC loves straight flush( BestCoder Round #41)
    产品经理的修炼:如何把梳子卖给和尚
    c++ STL unique , unique_copy函数
    linux定时备份mysql数据库文件
    Python——异常基础
  • 原文地址:https://www.cnblogs.com/tysonlee/p/11080624.html
Copyright © 2020-2023  润新知