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程序设计有所帮助。

您可能感兴趣的文章:

  • java设计模式之装饰模式详细介绍
  • Java设计模式之装饰模式(Decorator模式)介绍
  • Java设计模式之代理模式与装饰模式实例详解
  • java设计模式学习之装饰模式
  • Java设计模式之策略模式原理与用法实例详解
  • Javasript设计模式之链式调用详解
  • Java设计模式之动态代理模式实例分析
  • Java设计模式之静态代理模式实例分析
  • Java设计模式之装饰者模式详解和代码实例
  • Java设计模式之装饰模式原理与用法实例详解
(0)

相关推荐

  • java设计模式之装饰模式详细介绍

    1.    装饰模式(Decorator)的定义:又名包装(Wrapper)模式,装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 2.    装饰模式以对客户端透明的方式动态的给一个对象附加上更多的责任.换言之客户端并不会觉的对象在装饰前和装饰后有什么区别. 3.    装饰模式可以在不创造更多的子类的模式下,将对象的功能加以扩展. 4.    装饰模式与类继承的区别: 1)    装饰模式是一种动态行为,对已经存在类进行随意组合,而类的继承是一种静态的行为,一个类定义成

  • Java设计模式之动态代理模式实例分析

    本文实例讲述了Java设计模式之动态代理模式.分享给大家供大家参考,具体如下: 前面介绍了静态代理模式,动态代理比静态代理模式更加强大.它能在程序运行时动态的生成代理对象.所谓动态代理类是在运行时生成的class,在生成它时,你必须提供一组interface给它,则动态代理类就宣称它实现了这些interface.当然,动态代理类就充当一个代理,你不要企图它会帮你干实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作. 动态代理的角色和静态代理的角色一样: ① 抽象角色:

  • java设计模式学习之装饰模式

    装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活. 优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能. 缺点:多层装饰比较复杂. 实例:给一个人配置穿衣 1:代码结构图 2:创建一个person类(  ConcreteComponent) package DecoratorModel; /** * 2017-10-9 10:39:09 * 装饰器设计模式 * Person 类 Concre

  • Javasript设计模式之链式调用详解

    本文实例为大家分享了js设计模式之链式调用的具体代码,供大家参考,具体内容如下 写过jquery的可能都知道,jquery里面可以很方便的使用以下代码: // 不使用链式调用 const element = $(ele); element.addClass('red'); element.removeClass('green'); element.show(); // 链式调用 $(ele) .addClass('red') .removeClass('green') .show(); 而jqu

  • Java设计模式之策略模式原理与用法实例详解

    本文实例讲述了Java设计模式之策略模式原理与用法.分享给大家供大家参考,具体如下: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.其中JDK里面的TreeSet类和TreeMap类就用到了策略模式.这两个类是带排序的集合类,其中排序的规则就相当于策略模式里定义的一系列算法,而集合类就相当于是策略模式里的环境类,供用户使用,用只知道TreeSet和TreeMap是带排序的,至于怎么排序的,是由排序的算法决定的. 策略模式

  • Java设计模式之装饰者模式详解和代码实例

    装饰者模式可以给已经存在的对象动态的添加能力.下面,我将会用一个简单的例子来演示一下如何在程序当中使用装饰者模式. 1.装饰者模式 让我们来假设一下,你正在寻找一个女朋友.有很多来自不同国家的女孩,比如:美国,中国,日本,法国等等,他们每个人都有不一样的个性和兴趣爱好,如果需要在程序当中模拟这么一种情况的话,假设每一个女孩就是一个Java类的话,那么就会有成千上万的类,这样子就会造成类的膨胀,而且这样的设计的可扩展性会比较差.因为如果我们需要一个新的女孩,就需要创建一个新的Java类,这实际上也

  • Java设计模式之代理模式与装饰模式实例详解

    本文实例讲述了Java设计模式之代理模式与装饰模式.分享给大家供大家参考,具体如下: 之所以把这两种模式放在一起说,是因为我发现这了两种模式几乎一模一样! 从网上也搜了一些资料,发现两者还是有一些区别的.我们在学习的同时也把这种困惑搞清楚. 定义: 代理模式,为其他对象提供一种代理以控制对这个对象的访问. 装饰模式,动态地给一个对象添加一些额外的职责. 代理模式,很好理解,就是把一个对象再次封装,以后就对封装的对象访问就可以了. 因为代理对象已经取代了被代理对象. 装饰模式,给一个对象增加功能,

  • Java设计模式之静态代理模式实例分析

    本文实例讲述了Java设计模式之静态代理模式.分享给大家供大家参考,具体如下: 代理模式,可以通过代理可以在原来的基础上附加一些其他的操作.静态代理模式相对比较简单无需再程序运行时动态的进行代理. 静态代理模式的角色: ① 抽象角色:真实对象和代理对象的共同接口.其中声明真实对象和代理对象需要做的事. ② 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用. ③ 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作. 下面提

  • Java设计模式之装饰模式原理与用法实例详解

    本文实例讲述了Java设计模式之装饰模式原理与用法.分享给大家供大家参考,具体如下: 装饰模式能在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.JDK中IO的设计就用到了装饰模式,通过过滤流对节点流进行包装来实现功能的扩展. 装饰模式的角色的组成: ① 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加工功能的对象.(InputStream.OutputStream) ② 具体构件(Concrete Co

  • Java设计模式之装饰模式(Decorator模式)介绍

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这两种实体在Decorator模式中是必须的. Decorator定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活. 为什么使用Decorator 我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生

随机推荐