博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工厂模式
阅读量:5156 次
发布时间:2019-06-13

本文共 8293 字,大约阅读时间需要 27 分钟。

目录

简单工厂

  定义:

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

  角色:

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

总结:

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

 

转载于:https://www.cnblogs.com/tysonlee/p/11080624.html

你可能感兴趣的文章
virtual、abstract、interface区别以及用法
查看>>
visual studio 容器工具首次加载太慢 vsdbg\vs2017u5 exists, deleting 的解决方案
查看>>
学习yii2.0框架阅读代码(五)
查看>>
552. Student Attendance Record II
查看>>
Sublime Text 3 常用插件以及安装方法(转)
查看>>
洛谷 U6254 最低费用
查看>>
安卓学习第20课——progressBar
查看>>
初涉GitHub
查看>>
C# WebForm 使用NPOI 2 生成简单的word文档(.docx)
查看>>
vim中文手册,gcc中文手册,gdb中文手册打包赠送
查看>>
MVC和传统的以模板为中心的web架构比较
查看>>
python之路_django路由配置及模板
查看>>
Java基础知识总结
查看>>
现在网页中流行的css3样式
查看>>
Flask 学习 八 用户角色
查看>>
元类编程-- 实现orm,以django Model为例
查看>>
关于type return to continue,or q <return> to quit
查看>>
如果我们想读一下Struts2中的源码,在myeclipse中我们该如何配置呢?
查看>>
在客户端缓存Servlet的输出
查看>>
744. Find Smallest Letter Greater Than Target
查看>>