设计模式之工厂模式

本篇博文主要翻译这篇文章:

https://www.journaldev.com/1392/factory-design-pattern-in-java

由于翻译水平有限,自认为许多地方翻译不恰当,欢迎各位给出宝贵的建议,建议大家去阅读原文。

引言

本篇博文主要用 java 介绍 工厂模式,工厂模式是一种创建型设计模式,广泛运用在 JDK 和大量的框架中,比如 Spring 和 Struts。在什么情况下我们会用到它呢?当一个超类具有多个子类,我们需要返回其中一个子类时,就可以使用工厂模式。这个设计模式负责实例化客户端指定的类,实例化的工作由工厂类完成。

了解了一些基本概念后,接下来让我们先学一下如何利用 java 实现工厂模式,然后再去探讨工厂模式的优势。最后我们还会去看一下 JDK 中使用工厂模式的例子。这里顺便提一下,工厂模式也被称为 工厂方法设计模式

父类

在工厂设计模式中,父类可以是一个接口、抽象类或者是一个普通的 java 类。在我们的工厂模式例子中,我们使用一个抽象类作为父类,为了测试的目的,我们还覆写了 toString 方法。

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 两个实现

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 类。

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;
	}
}

工厂类

现在我们已经将父类和子类准备好了,我们可以开始写工厂类了。这是我们的一个简单实现。

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))
            return new Server(ram,hdd,cpu);
        return null;
    }
} 

关于工厂模式有几个重要的点需要注意:

  1. 我们需要确保工厂类是单例的(Singleton),或者使用 static 修饰工厂方法。(这是一个疑惑的地方,为什么呢?)
  2. 根据输入参数的不同,我们返回的是不同的子类。getComputer 方法就是工厂方法。

下面是这个例子的类图:

工厂模式

这是对工厂方法的测试:

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 GC, CPU=2.4 GHz
Factory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz

工厂模式的优点

  1. 工厂模式提供的是接口而不是实现
  2. 工厂模式将类的实例从客户端中去除,这使我们的代码更加健壮,更加易于扩展。在这个例子中,我们可以很容易的改变 PC 类的实现,因为客户端完全不知道 PC 类的实现。
  3. 工厂模式通过继承提供实现和客户端类之间的抽象。

JDK 中的工厂模式

  1. java.util.Calendar、ResourceBundle 和 NumberFormat 的 getInstance 方法使用了工厂方法,具体的细节可以去看源码。

  2. 基本类型包装类的 valueOf 方法,就比如 Boolean.valueOf(boolean b )`,其实现如下,该方法会根据输入的基本类型来决定输出的实例。

    public static Boolean valueOf(boolean b){
        return (b ? TRUE : FALSE);
    }
    

以上就是对全文的翻译,水平有限,请见谅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值