简介
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。常用的设计模式之一。
涉及角色
- creator
抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何在模式中创建对象的工厂类必须实现这个接口。不使用new关键字来生成实例,而是调用生成市里的专用方法来生成实例,这样就可以防止父类与其他具体类的耦合。 - ConcreteCreator
具体工厂角色:担任这个角色的是实现了抽象工厂接口的具体Java类,具体工厂角色含有与应用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。 - Product
抽象产品角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。 - ConcreteProduct
具体产品角色:这个角色实现了抽象产品角色所申明的接口。工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。
UML
使用场景
出现了大量的对象需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建对象。
优点
- 可以使代码结构清晰,有效地封装变化
- 对调用者屏蔽具体类,只需要关心对应的接口
- 降低耦合度
- 多态性,与特定应用无关,适用于任何实体类
缺点
- 每增加一个产品,相应的也要增加一个子工厂,加大了额外的开发量
- 工厂类集中了所有创建逻辑,若异常,影响整个系统运行
代码示例
如:车间主要是生产容器的,车间内存在数条产品线,分别生产瓶子、水杯、罐头盒等,用工厂类实现
定义容器接口
package com.designpattern.factory;
public interface Container {
public void getName();
public void getShap();
public void getColor();
}
具体产品实现Container接口
package com.designpattern.factory;
public class Bottle implements Container {
@Override
public void getName() {
// TODO Auto-generated method stub
System.err.println("bottle name:bottle");
}
@Override
public void getShap() {
// TODO Auto-generated method stub
System.err.println("bottle shap:cylinder");
}
@Override
public void getColor() {
// TODO Auto-generated method stub
System.err.println("bottle Color:black");
}
}
package com.designpattern.factory;
public class Cup implements Container {
@Override
public void getName() {
// TODO Auto-generated method stub
System.err.println("Cup name:Cup");
}
@Override
public void getShap() {
// TODO Auto-generated method stub
System.err.println("Cup shap:cylinder");
}
@Override
public void getColor() {
// TODO Auto-generated method stub
System.err.println("Cup Color:white");
}
}
package com.designpattern.factory;
public class Can implements Container {
@Override
public void getName() {
// TODO Auto-generated method stub
System.err.println("can name:can");
}
@Override
public void getShap() {
// TODO Auto-generated method stub
System.err.println("can shap:cycle");
}
@Override
public void getColor() {
// TODO Auto-generated method stub
System.err.println("can color:green");
}
}
创建一个生产容器的工厂,有一下几种方式
- 普通工厂方式,即简单工厂
package com.designpattern.factory;
public class Factory {
public Container getProduct(String productType) {
if (productType.equalsIgnoreCase("cup")) {
return new Cup();
} else if (productType.equalsIgnoreCase("can")) {
return new Can();
}else if (productType.equalsIgnoreCase("bottle")) {
return new Bottle();
} else {
return null;
}
}
}
简单工厂缺点很明显,需要显式传入控制变量,如果传入有误,则不能正确创建需要的对象
- 多工厂方法
package com.designpattern.factory;
public class MulitFactoryMethod {
public Container getCup() {
return new Cup();
}
public Container getBottle() {
return new Bottle();
}
public Container getCan() {
return new Can();
}
}
- 静态工厂
package com.designpattern.factory;
public class StaticFactory {
public static Container getCup() {
return new Cup();
}
public static Container getBottle() {
return new Bottle();
}
public static Container getCan() {
return new Can();
}
}
建立测试类
package com.designpattern.factory;
public class TestMain {
public static void main(String[] args) {
//测试普通工厂创建对象
Factory factory = new Factory();
factory.getProduct("cup").getName();
//测试多工厂创建对象
MulitFactoryMethod mulitFactoryMethod = new MulitFactoryMethod();
mulitFactoryMethod.getCan().getName();
//测试静态工厂创建对象
StaticFactory.getBottle().getName();
}
}
Cup name:Cup
can name:can
bottle name:bottle