Java设计模式学习记录-简单工厂模式、工厂方法模式

前言

之前介绍了设计模式的原则和分类等概述。今天开启设计模式的学习,首先要介绍的就是工厂模式,在介绍工厂模式前会先介绍一下简单工厂模式,这样由浅入深来介绍。

简单工厂模式

做法:创建一个工厂(方法或类)用来制造对象。

当一个人想要用手机的时候,需要自己创建手机然后来使用。

如下:

public class IphoneX {

    public IphoneX(){
System.out.println("##### 制造iphoneX #####");
}
}
public class Iphone8 {

    public Iphone8(){
System.out.printf("##### 制造iphone8 #####");
} }
public class Customer {

    /**
* 使用手机
*/
@Test
public void usePhone(){
IphoneX iphoneX = new IphoneX();
Iphone8 iphone8 = new Iphone8();
} }

这种实现方式,客户在使用的手机的时候会看到手机的具体实现方式,客户就和手机的耦合度非常高,其实客户并不关心手机具体是什么实现的,为了降低耦合,就出现了工厂类,把手机的制造过程放到工厂里去实现。客户想使用手机时,将手机型号传递给工厂类里创建手机的方法就可以了。而不必关心手机制造的整个过程,这样一来在创建手机的过程中添加额外的一些操作也显得很灵活。这种实现方式就是下面要介绍的简单工厂模式

public abstract class Iphone {
public Iphone(){ }
}
public class IphoneX extends Iphone{

    public IphoneX(){
System.out.println("##### 制造iphoneX #####");
}
}
public class Iphone8 extends Iphone{

    public Iphone8(){
System.out.printf("##### 制造iphone8 #####");
}
}

工厂类:

public class FoxconnFactory {

    /**
* 创建手机
* @param model 型号
* @return
*/
public static Iphone createIphone(String model){ switch (model){
case "X":{
return new IphoneX();
}
case "8":{
return new Iphone8();
}
default:break;
}
return null;
}
}

客户类:

public class Customer {

    /**
* 使用手机
*/
@Test
public void usePhone(){
Iphone iphoneX = FoxconnFactory.createIphone("X");
     Iphone iphone8 = FoxconnFactory.createIphone("8");
  }
}

简单工厂模式的类图如下:

Java设计模式学习记录-简单工厂模式、工厂方法模式

这个类图上包含三个角色:

  • 工厂类角色(Factory):这是本模式的核心,含有一定的商业逻辑和判断逻辑。在Java中往往由一个具体类实现。
  • 抽象产品角色(Abstract Iphone Class):一般是具体产品继承的父类或者实现的接口,在Java中由一个具体类来实现。
  • 具体产品角色(IphoneX):工厂类所创建的对象就是此角色的实例,在Java中由一个具体类来实现。

在实际情况中如果我们想使用新的型号的手机,就需要改造FoxconnFactory这个类(在类中加case)这违背了开闭原则,因为在使用新产品的时候,工厂类是属于被动改变的。为了解决这种情况,就出现了工厂方法模式,工厂方法模式与简单工厂模式的最大不同在于,简单工厂模式只有一个(对于一个项目或一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。

工厂方法模式提供了多个实现相同接口的工厂类,这样每个工厂类生产不同类型的产品,这样如果新增加一款手机只需要新增加一个生产此款手机的工厂类就可以了,不用去改变已经存在的工厂类。这样就符合开闭原则了。

例子如下:

public abstract class Iphone {
public Iphone(){ }
}
public class IphoneX extends Iphone{

    public IphoneX(){
System.out.println("##### 制造iphoneX #####");
}
}
public class Iphone8 extends Iphone{

    public Iphone8(){
System.out.printf("##### 制造iphone8 #####");
}
}

工厂类:

public interface Factory {

    Iphone createIphone();

}
public class FoxconnFactory implements Factory{

    /**
* 创建iphoneX手机
* @return
*/
@Override
public Iphone createIphone(){ return new IphoneX();
}
}
public class HeShuoFactory implements Factory {

    /**
* 生产iphone8手机
* @return
*/
@Override
public Iphone createIphone() { return new Iphone8();
}
}

客户类:

public class Customer {

    /**
* 使用手机
*/
@Test
public void usePhone(){ Factory foxconn = new FoxconnFactory();
Factory heshuo = new HeShuoFactory(); Iphone iphoneX = foxconn.createIphone();
Iphone iphone8 = heshuo.createIphone();
} }

工厂方法模式结构图如下:

Java设计模式学习记录-简单工厂模式、工厂方法模式

此结构图的中含四个角色:

  • 抽象工厂角色(代加工工厂):这是工厂方法模式的核心,它与应用程序无关,是具体工厂角色必须实现的接口或者必须继承的父类。在Java中他由抽象类或者接口来实现。
  • 具体工厂角色(富士康工厂):它含有与具体业务逻辑有关的代码。由应用程序调用,以创建对应的具体产品对象。在Java中它由具体类来实现。
  • 抽象产品角色(苹果手机抽象类):它是具体产品继承父类或者是实现的接口。在Java中一般有抽象类或接口来实现。
  • 具体产品角色(iphoneX手机):具体工厂角色所创建的对象就是此角色的实例。在Java中由具体的类来实现。

虽然说工厂方法模式解决了简单工厂模式的不满足开闭原则的问题,但是这也造成了,代码量的成本增加,当产品数量过多时,维护起来会很麻烦,反而简单工厂没有这么麻烦,当多个产品需要修改时,简单工厂模式仍然只需要修改唯一的工厂类。无论哪种方式都是以实现功能为目的。

对比一下得出个人结论:简单工厂模式,更简洁方便。工厂方法模式更松散,更先进。

上一篇:string.empty和null的区别


下一篇:.NET持续集成与自动化部署之路第一篇——半天搭建你的Jenkins持续集成与自动化部署系统