Java设计模式之工厂模式分析【简单工厂、工厂方法、抽象工厂】

 更新时间:2018年04月26日 10:50:30   作者:aronykl  
这篇文章主要介绍了Java设计模式之工厂模式,结合实例形式分析了简单工厂、工厂方法、抽象工厂等相关功能、实现与使用方法,需要的朋友可以参考下

本文实例讲述了Java设计模式之工厂模式。分享给大家供大家参考,具体如下:

一、 简单工厂

先来思考一个问题。我们平时写程序时,会有这种情况,A对象里面需要调用B对象的方法,这时我们使用的一般是new关键字来创建一个B实例,然后调用B实例的方法。这种做法的坏处在于:A类的方法实现直接调用了B类的类名(这种方式也被称为硬编码耦合),一旦系统需要重构:需要使用C类来代替B类时,程序就不得不修改A类代码,如果应用中有100个或者10000个类以硬编码方式耦合了B类,则需要修改100个、10000个地方,这显然是一种非常可怕的事情。

换一个角度来看这个问题:对已A对象而言,它只需要调用B对象的方法,并不关心B对象的实现、创建过程,考虑让B类实现一个IB接口,而A类只需要与IB接口耦合——A类并不直接使用new关键字来创建B实例,而是重新定义一个工厂类:IBFactory,由该工厂类负责创建IB实例,而A类用过调用IBFactory工厂的方法来得到IB的实例。通过以上设计:需要使用C类代替B类,则只需要让C类也实现IB接口,并改写IBFactory工厂中创建IB实例的实现代码,让该工厂产生C实例即可。这种将多个类对象交给工厂类来生成的设计方式叫做简单工厂模式。

以下是简单工厂模式的代码:

/**
 * 简单工厂模式
 *
 * 需要工厂生产的对象实例所实现的共同的接口
 * 发型接口
 * @author Administrator
 *
 */
public interface Hair {
  /**
   * 画发型
   */
  public void draw();
}
/**
 * 左偏分发型
 * @author Administrator
 *
 */
public class LeftHair implements Hair {
  @Override
  public void draw() {
    System.out.println("----------------画左偏分发型-----------------");
  }
}
/**
 * 右偏分发型
 * @author Administrator
 *
 */
public class RightHair implements Hair {
  @Override
  public void draw() {
    System.out.println("-----------------画右偏分发型------------------");
  }
}
/**
 * 生产发型的工厂
 * 要生产什么发型 只需在这里改就行了
 * @author Administrator
 *
 */
public class HairFactory {
  public Hair getHair() {
    return new LeftHair();
    //return new RightHair();
  }
}
/**
 * 客户端测试类
 * @author Administrator
 *
 */
public class HairTest {
  public static void main(String[] args) {
    HairFactory factory = new HairFactory();
    Hair hair = factory.getHair();
    hair.draw();
  }
}

可以看到,如果想把HairTest里面生成的LeftHair改成RightHair,只需修改HairFactory里面getHair方法的实现即可。

使用简单工厂模式的优势在于:让对象的调用者和对象的创建过程分离,当对象调用者需要对象时,直接向工厂请求即可,从而避免了对象的调用者与对象实现类以硬编码方式耦合,以提高系统的可维护性、可扩展性。当然,工厂模式也有一个小小的缺陷,当产品修改时,工厂类也要做相应的修改,此处可使用策略模式进行解决,下面是代码。

public interface HairBuilder {
  /**
   * 制造发型
   * @return
   */
  public Hair getHair();
}
public class LeftHairBuilder implements HairBuilder {
  @Override
  public Hair getHair() {
    return new LeftHair();
  }
}
public class RightHairBuilder implements HairBuilder {
  @Override
  public Hair getHair() {
    return new RightHair();
  }
}
public class HairFactory {
  private HairBuilder hairBuilder;
  public HairFactory(HairBuilder hairBuilder) {
    this.hairBuilder = hairBuilder;
  }
  public void setHairBuilder(HairBuilder hairBuilder) {
    this.hairBuilder = hairBuilder;
  }
  public Hair getHair() {
    return hairBuilder.getHair();
  }
}
public class HairTest {
  public static void main(String[] args) {
//   HairBuilder builder = new LeftHairBuilder();
    HairBuilder builder = new RightHairBuilder();
    HairFactory factory = new HairFactory(builder);
    Hair hair = factory.getHair();
    hair.draw();
  }
}

这种做法的好处是无需再去修改工厂类,将工厂里面的创建对量逻辑根据不同的策略抽象出来,程序需要创建什么对象,只需网工厂中传入相应的builder即可。

二、工厂方法

在简单工厂模式中,系统使用工厂类生产所有产品实例,且该工厂类决定生产哪个类的实例,即工厂类负责所有的逻辑判断、实例创建等工作。

如果不想再工厂类中进行逻辑判断,程序可以为不同的产品类提供不同的工厂,不同的工厂类生产不同的产品,无需再工厂类中进行复杂的逻辑判断。这就有点类似于上面的简单工厂模式结合策略模式,不同的是前者只有一个工厂,后者需要有多个工厂。下面是工厂方法模式的代码。

/**
 * 工厂方法模式
 * 需要工厂生产的对象实例所实现的共同的接口
 * @author Administrator
 *
 */
public interface Person {
  public void drawPerson();
}
public class Man implements Person {
  @Override
  public void drawPerson() {
    System.out.println("---------------------draw a man--------------------");
  }
}
public class Women implements Person {
  @Override
  public void drawPerson() {
    System.out.println("--------------------draw a women---------------------");
  }
}
/**
 * 生产人的工厂
 * @author Administrator
 *
 */
public interface PersonFactory {
  //生产人
  public Person getPerson();
}
/**
 * 生产man的工厂
 * @author Administrator
 *
 */
public class ManFactory implements PersonFactory {
  @Override
  public Person getPerson() {
    return new Man();
  }
}
/**
 * 声场women的工厂
 * @author Administrator
 *
 */
public class WomenFactory implements PersonFactory {
  @Override
  public Person getPerson() {
    return new Women();
  }
}
/**
 * 客户端测试类
 * @author Administrator
 *
 */
public class PersonTest {
  public static void main(String[] args) {
//   PersonFactory factory = new ManFactory();
    PersonFactory factory = new WomenFactory();
    Person person = factory.getPerson();
    person.drawPerson();
  }
}

这种的典型的特点就是在客户端代码中根据不同的工厂生产其对应的产品,不必把复杂的逻辑都放在工厂类里面判断。这种实现有一个很明显的缺陷,就是客户端与工厂类进行了耦合。

三、抽象工厂

采用上面的工厂方法的设计架构,客户端代码成功与被调用对象的实现类分离,但带来了另一种耦合:客户端代码与不同的工厂类耦合。为了解决这种耦合的问题,考虑在增加一个工厂类,用来生成工厂实例,实现生产产品的工厂与客户端分离,这种设计方式被称为抽象工厂模式。下面是抽象工厂模式的代码

/**
 * 抽象工厂模式
 * 生产PersonFactory的工厂
 * @author Administrator
 *
 */
public class PersonFactoryFactory {
  public static PersonFactory getPersonFactory(String type) {
    if(type.equalsIgnoreCase("man")) {
      return new ManFactory();
    } else {
      return new WomenFactory();
    }
  }
}
/**
 * 客户端测试类
 * @author Administrator
 *
 */
public class PersonTest {
  public static void main(String[] args) {
    PersonFactory factory = PersonFactoryFactory.getPersonFactory("man");
    Person person = factory.getPerson();
    person.drawPerson();
  }
}

更多java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

相关文章

  • Spring高阶用法之自定义业务对象组件化

    Spring高阶用法之自定义业务对象组件化

    这篇文章主要介绍了Spring高阶用法之自定义业务对象组件化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • 超详细的Java 问题排查工具单

    超详细的Java 问题排查工具单

    这篇文章主要介绍了超详细的Java 问题排查工具单,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Java之CountDownLatch原理全面解析

    Java之CountDownLatch原理全面解析

    这篇文章主要介绍了Java之CountDownLatch原理解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • 浅谈Java模板引擎性能对比

    浅谈Java模板引擎性能对比

    本篇文章主要介绍了浅谈Java模板引擎性能对比 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 深入理解SpringMVC的参数绑定与数据响应机制

    深入理解SpringMVC的参数绑定与数据响应机制

    本文将深入探讨SpringMVC的参数绑定方式,包括基本类型、对象、集合等类型的绑定方式,以及如何处理参数校验和异常。同时,本文还将介绍SpringMVC的数据响应机制,包括如何返回JSON、XML等格式的数据,以及如何处理文件上传和下载。
    2023-06-06
  • Java中finally和return的关系实例解析

    Java中finally和return的关系实例解析

    这篇文章主要介绍了Java中finally和return的关系实例解析,总结了二者的关系,然后分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • java中this与super关键字的使用方法

    java中this与super关键字的使用方法

    这篇文章主要介绍了java中this与super关键字的使用方法的相关资料,希望通过本文能帮助到大家,让大家彻底理解应用java中this与super,需要的朋友可以参考下
    2017-09-09
  • SpringBoot3整合pageHelper实现分页功能

    SpringBoot3整合pageHelper实现分页功能

    PageHelper是一个开源的Java分页插件,它提供了方便的分页查询功能,适用于大多数基于Java的持久层框架(如MyBatis、Hibernate等),本文给大家介绍了springboot3整合pageHelper实现分页功能的方法,需要的朋友可以参考下
    2024-08-08
  • 关于Java中try finally return语句的执行顺序浅析

    关于Java中try finally return语句的执行顺序浅析

    这篇文章主要介绍了关于Java中try finally return语句的执行顺序浅析,需要的朋友可以参考下
    2017-08-08
  • Java 8 Function函数式接口及函数式接口实例

    Java 8 Function函数式接口及函数式接口实例

    函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。接下来通过本文给大家介绍Java 8 Function函数式接口及函数式接口实例代码,需要的朋友可以参考下
    2018-05-05

最新评论