设计模式-工厂(译)

113 阅读3分钟

我正在参加跨端技术专题征文活动,详情查看:juejin.cn/post/710123…

欢迎来到java中的工厂模式,Factory Pattern 是一个创建型设计模式 Creational Design pattern。工厂模式在JDK和一些框架中有很广泛的应用,比如spring和Struts

工厂模式

工厂模式通常用于一个超类和多个子类实现。基于输入参数返回一个子类的实例。这种模式将实例化子类的职责从客户程序中剥离开来,交给工厂类

我们首先学习在java中怎么实现一个工厂模式,然后看到它的优点。我们也可以在JDK中看工厂模式的使用。工厂模式也被称为工厂方法模式

工厂模式超类

在工厂模式中超类可以是一个接口、抽象类,或者是个普通java类。在我们这个例子中,我们用一个含有可被重写toString()方法抽象类来做测试

package com.journaldev.design.model;

public abstract class Computer {
	
	public abstract String getRAM();
	public abstract String getHDD();
	public abstract String getCPU();
	
	@Override
	public String toString(){
		return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
	}
}

工厂模式子类

下面有两个子类实现 PC 和 Server

package com.journaldev.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 getRAM() {
		return this.ram;
	}

	@Override
	public String getHDD() {
		return this.hdd;
	}

	@Override
	public String getCPU() {
		return this.cpu;
	}

}

可以看到我们的子类都实现了Computer的超类

package com.journaldev.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 getRAM() {
		return this.ram;
	}

	@Override
	public String getHDD() {
		return this.hdd;
	}

	@Override
	public String getCPU() {
		return this.cpu;
	}

}

工厂类

现在我们超类和子类都准备好了,我们可以写一个工厂类。下面是一个基本的实现

package com.journaldev.design.factory;

import com.journaldev.design.model.Computer;
import com.journaldev.design.model.PC;
import com.journaldev.design.model.Server;

public class ComputerFactory {

	public static Computer getComputer(String type, String ram, String hdd, String cpu){
		if("PC".equalsIgnoreCase(type)) return new PC(ram, hdd, cpu);
		else if("Server".equalsIgnoreCase(type)) return new Server(ram, hdd, cpu);
		
		return null;
	}
}

下面是工厂模式一些重要点

  1. 我们可以让工厂类保持单例,或者可以有一个静态方法来提供子类的获取。
  2. 可以看到基于不同的输入参数,可以创建不同的子类被返回。getComputer就是这儿的工厂方法

xxx.png

这儿是一个简单的测试例子,用到了上面的工厂设计模式实现

package com.journaldev.design.test;

import com.journaldev.design.factory.ComputerFactory;
import com.journaldev.design.model.Computer;

public class TestFactory {

	public static void main(String[] args) {
		Computer pc = ComputerFactory.getComputer("pc","2 GB","500 GB","2.4 GHz");
		Computer server = ComputerFactory.getComputer("server","16 GB","1 TB","2.9 GHz");
		System.out.println("Factory PC Config::"+pc);
		System.out.println("Factory Server Config::"+server);
	}

}

输出如下

Factory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz
Factory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz

工厂模式的优点

  • 工厂模式提供了一种抽象由于实现的方法
  • 工厂模式去除了由客户程序创建具体子类实现。工厂模式让我们的代码更加健壮,更少的耦合,更易于扩展。举个例子,我们可以很容易的修改PC类的实现,因为客户端程序并没有依赖PC这个类(依赖的是PC的超类Computer)
  • 工厂模式通过继承的方式在实现和客户类之间提供了抽象(指的是客户程序以来的是抽象类Computer)

工厂模式在JDK中的例子

  • java.util.Calendar, ResourceBundle and NumberFormat getInstance()方法使用了工厂模式
  • Boolean,Integer这类包装类的valueOf() 方法也是一个工厂方法

原文链接