工厂模式 - Go语言中文社区

工厂模式


目录

  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文本等。我们需要根据系统来切换不同的产品族,达到使用不同系统的控件)。
      注:具体工厂类应该只有一个,实际应用应该考虑成单例。

总结:

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

 

版权声明:本文来源博客园,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://www.cnblogs.com/tysonlee/p/11080624.html
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢