Java中的抽象工厂设计模式

时间:2020-02-23 14:36:06  来源:igfitidea点击:

欢迎使用Java示例中的"抽象工厂设计模式"。
抽象工厂设计模式是创新模式之一。
抽象工厂模式几乎类似于工厂模式,除了它更像工厂的工厂。

抽象工厂

如果您熟悉Java中的工厂设计模式,您会注意到我们只有一个Factory类。
该工厂类根据提供的输入返回不同的子类,并且工厂类使用if-else或者switch语句来实现此目的。

在抽象工厂模式中,我们摆脱了if-else块,并为每个子类都有一个工厂类。
然后是一个抽象工厂类,它将基于输入工厂类返回子类。
乍一看似乎令人困惑,但是一旦您看到了实现,就很容易理解和理解Factory模式与Abstract Factory模式之间的细微差别。

就像我们的工厂模式文章一样,我们将使用相同的超类和子类。

抽象工厂设计模式超类和子类

Computer.java

package com.theitroad.design.model;
 
public abstract class Computer {
   
  public abstract String get内存();
  public abstract String getHDD();
  public abstract String getCPU();
   
  @Override
  public String toString(){
      return "内存= "+this.get内存()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
  }
}

PC.java

package com.theitroad.design.model;
 
public class PC extends Computer {
 
  private String ram;
  private String hdd;
  private String cpu;
   
  public PC(String ram, String hdd, String cpu){
      this.ram=ram;
      this.hdd=hdd;
      this.cpu=cpu;
  }
  @Override
  public String get内存() {
      return this.ram;
  }
 
  @Override
  public String getHDD() {
      return this.hdd;
  }
 
  @Override
  public String getCPU() {
      return this.cpu;
  }
 
}

Server.java

package com.theitroad.design.model;
 
 
public class Server extends Computer {
 
  private String ram;
  private String hdd;
  private String cpu;
   
  public Server(String ram, String hdd, String cpu){
      this.ram=ram;
      this.hdd=hdd;
      this.cpu=cpu;
  }
  @Override
  public String get内存() {
      return this.ram;
  }
 
  @Override
  public String getHDD() {
      return this.hdd;
  }
 
  @Override
  public String getCPU() {
      return this.cpu;
  }
 
}

每个子类的工厂类

首先,我们需要创建一个Abstract Factory接口或者抽象类。

ComputerAbstractFactory.java

package com.theitroad.design.abstractfactory;

import com.theitroad.design.model.Computer;

public interface ComputerAbstractFactory {

	public Computer createComputer();

}

注意,createComputer()方法返回的是超类Computer的实例。
现在,我们的工厂类将实现此接口并返回其各自的子类。

PCFactory.java

package com.theitroad.design.abstractfactory;

import com.theitroad.design.model.Computer;
import com.theitroad.design.model.PC;

public class PCFactory implements ComputerAbstractFactory {

	private String ram;
	private String hdd;
	private String cpu;
	
	public PCFactory(String ram, String hdd, String cpu){
		this.ram=ram;
		this.hdd=hdd;
		this.cpu=cpu;
	}
	@Override
	public Computer createComputer() {
		return new PC(ram,hdd,cpu);
	}

}

同样,我们将为"服务器"子类提供一个工厂类。

ServerFactory.java

package com.theitroad.design.abstractfactory;

import com.theitroad.design.model.Computer;
import com.theitroad.design.model.Server;

public class ServerFactory implements ComputerAbstractFactory {

	private String ram;
	private String hdd;
	private String cpu;
	
	public ServerFactory(String ram, String hdd, String cpu){
		this.ram=ram;
		this.hdd=hdd;
		this.cpu=cpu;
	}
	
	@Override
	public Computer createComputer() {
		return new Server(ram,hdd,cpu);
	}

}

现在,我们将创建一个消费者类,该类将为客户端类创建子类提供入口。

ComputerFactory.java

package com.theitroad.design.abstractfactory;

import com.theitroad.design.model.Computer;

public class ComputerFactory {

	public static Computer getComputer(ComputerAbstractFactory factory){
		return factory.createComputer();
	}
}

注意,它的一个简单的类和getComputer方法是接受ComputerAbstractFactory参数并返回Computer对象。
此时,实现必须变得清晰。

让我们编写一个简单的测试方法,看看如何使用抽象工厂来获取子类的实例。

TestDesignPatterns.java

package com.theitroad.design.test;

import com.theitroad.design.abstractfactory.PCFactory;
import com.theitroad.design.abstractfactory.ServerFactory;
import com.theitroad.design.factory.ComputerFactory;
import com.theitroad.design.model.Computer;

public class TestDesignPatterns {

	public static void main(String[] args) {
		testAbstractFactory();
	}

	private static void testAbstractFactory() {
		Computer pc = com.theitroad.design.abstractfactory.ComputerFactory.getComputer(new PCFactory("2 GB","500 GB","2.4 GHz"));
		Computer server = com.theitroad.design.abstractfactory.ComputerFactory.getComputer(new ServerFactory("16 GB","1 TB","2.9 GHz"));
		System.out.println("AbstractFactory PC Config::"+pc);
		System.out.println("AbstractFactory Server Config::"+server);
	}
}

上面程序的输出将是:

AbstractFactory PC Config::内存= 2 GB, HDD=500 GB, CPU=2.4 GHz
AbstractFactory Server Config::内存= 16 GB, HDD=1 TB, CPU=2.9 GHz

这是抽象工厂设计模式实现的类图。

抽象工厂设计模式的好处

  • 抽象工厂设计模式提供了接口代码而不是实现代码的方法。

  • 抽象工厂模式是"工厂的工厂",可以轻松扩展以容纳更多产品,例如,我们可以添加另一个子类Laptop和一个Factory LaptopFactory。

  • 抽象工厂模式具有鲁棒性,避免了工厂模式的条件逻辑。

JDK中的抽象工厂设计模式示例

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()