工厂设计模式
场景:出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。
面向接口编程,一个工厂可以“生产”多种子类。降低了实现类和应用程序之间的耦合,将创建对象的责任转移到工厂中。
创建者可以忽略具体创建对象的过程,只管使用。
工厂设计模式的三种形式:
1.静态工厂
在工厂中有一个静态方法,根据参数来决定“制造”哪种类,将创建对象的责任转移到了工厂类里。
产品接口:
public interface Product {
public void create();
}
实现接口的具体产品类:
public class Washer implements Product{
@Override
public void create() {
System.out.println("洗衣机被制造了");
}
}
public class Computer implements Product{
@Override
public void create() {
System.out.println("电脑被制造了");
}
}
产品工厂,根据参数来决定生产哪种产品:
public class ProductFactory {
public static Product createProduct(String productName) throws Exception {
if(productName.equals("洗衣机")){
return new Washer();
}else if(productName.equals("电脑")){
return new Computer();
}else {
throw new Exception("没有此产品");
}
}
}
开始生产产品:
public static void main(String[] args){
try {
Product washer = ProductFactory.createProduct("洗衣机");
washer.create();
Product computer = ProductFactory.createProduct("电脑");
computer.create();
} catch (Exception e) {
e.printStackTrace();
}
}
上面代码的核心便是 ProductFactory 工厂类,工厂类通过判断传入静态方法的参数来生产产品,只要把 产品名称 给它,就能得到我们想要的产品。
扩展性高,如果想增加产品,只需扩展工厂类即可。对于调用者来说,屏蔽了产品类的实现细节,只关心产品的接口。
缺点和局限:整个系统都依赖工厂类,一旦工厂类的某个方法出现问题,整个系统都不能工作。
想要增加一个产品,除了增加一个产品类之外,还必须修改工厂类。当有很多很多产品时,而且产品之间还存在复杂的层次逻辑,这个工厂类就必须有复杂的逻辑判断能力,不利于系统的维护。
2. 工厂方法
如果要创建的种类增多,静态方法须在工厂类中修改方法,这不符合开闭原则,即对修改关闭,对扩展开放。可以使用工厂方法来扩展工厂类。
工厂方法为工厂类定义工厂接口,通过实现多个工厂类来削弱工厂类的职能。
工厂接口:
public interface Factory {
public Product create();
}
产品接口:
public interface Product {
public void create();
}
产品实现类:
public class Washer implements Product{
@Override
public void create() {
System.out.println("洗衣机被制造了");
}
}
public class Computer implements Product{
@Override
public void create() {
System.out.println("电脑被制造了");
}
}
通过工厂接口,实现多个工厂类:
public class WasherFactory implements Factory{
@Override
public Product create() {
return new Washer();
}
}
public class ComputerFactory implements Factory{
@Override
public Product create() {
return new Computer();
}
}
通过对比发现静态工厂和工厂方法的区别:
静态工厂是将生产所有产品的功能都放在一个类里,通过静态方法来判断要生产哪种产品。而工厂方法是将不同的产品放在不同的工厂来生产,各个工厂分工明确,即使一个工厂出现问题,其他工厂也不会受影响。
以后若要增加新产品,只需增加一个工厂类,不需修改代码,不会对其他工厂造成影响。
工厂方法的局限:当每类产品有多种型号时,工厂方法就要为每类产品的每种型号都要创建一个工厂类,随着产品种类和产品型号的增多,产品类和工厂类也不断增多,不利于维护。
3.抽象工厂
工厂方法的所有产品都实现了同一个产品接口,没有分类的概念。
抽象工厂可以理解成 在工厂方法的基础上进行分类管理。
洗衣机型号:“洗衣机-A”,“洗衣机-B”,电脑型号:“电脑-A”,“电脑-B”
产品部分:
产品接口:
public interface Computer {
public void create();
}
public interface Washer {
public void create();
}
产品实现类:
public class WasherA implements Washer{
@Override
public void create() {
System.out.println("洗衣机-A 被制造了");
}
}
public class WasherB implements Washer{
@Override
public void create() {
System.out.println("洗衣机-B 被制造了");
}
}
public class ComputerA implements Computer{
@Override
public void create() {
System.out.println("电脑-A被制造了");
}
}
public class ComputerB implements Computer{
@Override
public void create() {
System.out.println("电脑-B被制造了");
}
}
工厂接口:
public interface Factory {
public Washer createWasher();
public Computer createComputer();
}
工厂实现类:
public class FactoryA implements Factory{
@Override
public Washer createWasher() {
return new WasherA();
}
@Override
public Computer createComputer() {
return new ComputerA();
}
}
public class FactoryB implements Factory{
@Override
public Washer createWasher() {
return new WasherB();
}
@Override
public Computer createComputer() {
return new ComputerB();
}
}
当产品型号过多时,可以看出,抽象工厂实现了产品的分类,根据型号的不同来划分不同工厂。