工厂模式分为三种 :简单工厂模式 、工厂方法模式 、抽象工厂模式 。
目录
简单工厂模式
简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法);简单工厂模式可以理解为负责生产对象的一个类,称为“工厂类”。
简单工厂模式属于创建型模式 。
UML图
简单工厂模式角色说明:
- Product(抽象产品类):要创建的复杂对象,定义对象的公共接口。
- ConcreteProduct(具体产品类):实现Product接口。
- Factory(工厂类):返回ConcreteProduct实例。
总结:一个抽像产品类,可以派生出多个具体产品类 。一个具体工厂类,通过往此工厂的static 方法中传入不同参数,产出不同的具体产品类的实例 。
实现
(1) 创建抽象产品类,定义公共接口:
public interface Product {
void show();
}
(2) 创建具体的产品类,实现Proudct类:
public class ProductA implements Product{
@Override
public void show() {
System.out.println("我是产品A");
}
}
public class ProductB implements Product{
@Override
public void show() {
System.out.println("我是产品B");
}
}
(3) 创建工厂类,生产出具体的产品:
public class ProductFactory {
public static Product createProduct(String productName){
Product product=null;
switch (productName){
case "A":
product=new ProductA();
break;
case "B":
product=new ProductB();
break;
}
return product;
}
}
(4)测试
public static void main(String[] args){
ProductFactory.createProduct("A").show();
}
使用场景:
- 工厂类负责常见的"产品"对象比较少,且工厂类功能稳定,不需要扩展;
- 客户端只需传入工厂类的参数就能获得对应的产品对象,而无需关心创建对象的具体逻辑。
- 生成复杂对象时,确定只有一个工厂类的时候
优点 :
代码解耦,创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建
缺点:
违背开放封闭原则,若需添加新产品必须修改工厂类逻辑,会造成工厂逻辑过于复杂。
简单工厂模式使用了静态工厂方法,因此静态方法不能被继承和重写。
工厂类包含了所有实例(产品)的创建逻辑,若工厂类出错,则会造成整个系统都会受到影响。
工厂方法模式
定义: 定义一个用于创建对象的接口,让子类决定实例化哪个类 ,工厂方法使一个类的实例化延迟到其子类
概括:Concrete Product 具有共同的父类Product ,Concrete Factory也具有共同的父类Factory。每个具体的子类Concrete Factory 产出一个对应的Concrete Product。
UML图
总结 :一个抽象产品类,可以派生出多个具体产品类 。一个抽象工厂类 ,可以派生出多个具体工厂类 ,每个具体工厂类只能创建一个具体产品类的实例。
实现
(1)、创建抽象产品
public interface Product {
void show();
}
(2)、创建具体的产品,实现Product类
public class ProductA implements Product{
@Override
public void show() {
System.out.println("我是产品A");
}
}
public class ProductB implements Product{
@Override
public void show() {
System.out.println("我是产品B");
}
}
(3)、创建抽象工厂
public interface Factory {
<T extends Product> T createProduct();
}
(4) 、创建具体的工厂
public class FactoryImpl implements Factory{
@Override
public <T extends Product> T createProduct(Class<T> cls) {
Product product=null;
try{
product= (Product) Class.forName(cls.getName()).newInstance();
}catch (Exception e){
}
return (T)product;
}
}
(5)测试
public static void main(String[] args){
FactoryImpl factory=new FactoryImpl();
Product productA=factory.createProduct(ProductA.class);
productA.show();
}
使用场景:
- 工厂类负责常见的"产品"对象比较多,且工厂类功能不稳定,需要扩展;
- 客户端只需传入产品类的参数就能获得对应的产品对象,而无需关心创建对象的具体逻辑。
- 生成复杂对象时,确定只有多个工厂类的时候
优点:
1、更符合开放封闭原则
新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可,而简单工厂模式需要修改工厂类的判断逻辑
2、符合单一职责原则
每个具体工厂类只负责创建对应的产品,而简单工厂中的工厂类存在复杂的switch逻辑判断
3、不使用静态工厂方法,可以形成基于继承的等级结构,而简单工厂模式的工厂类使用静态工厂方法
总结:工厂模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。
缺点:
1、添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
2、由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
3、虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;
4、一个具体工厂只能创建一种具体产品
抽象工厂模式
定义:为创建一组相关或者相互依赖的对象提供一个接口,而无需指定它们具体的类。
介绍:
抽象工厂模式属于创建型模式。
工厂方法模式每个工厂只能创建一种类型的产品,而抽象工厂模式则能够创建多种类型的产品。
例如:硬盘工厂只生产硬盘这种产品,而电脑工厂则组合不同的硬盘、内存、CPU等生产出电脑来。
UML图
角色说明:
AbstractProduct(抽象产品类):定义产品的公共接口。
ConcreteProduct(具体产品类):定义产品的具体对象,实现抽象产品类中的接口。
AbstractFactory(抽象工厂类):定义工厂中用来创建不同产品的方法。
ConcreteFactory(具体工厂类):实现抽象工厂中定义的创建产品的方。
实现:
(1)抽象产品类
//抽象产品类-- CPU
public abstract class CPU {
public abstract void showCPU();
}
//抽象产品类-- 内存
public abstract class Memory {
public abstract void showMemory();
}
//抽象产品类-- 硬盘
public abstract class HD {
public abstract void showHD();
}
(2)创建具体产品类
//具体产品类-- Intet CPU
public class IntelCPU extends CPU {
@Override
public void showCPU() {
System.out.println("Intet CPU");
}
}
//具体产品类-- AMD CPU
public class AmdCPU extends CPU {
@Override
public void showCPU() {
System.out.println("AMD CPU");
}
}
//具体产品类-- 三星 内存
public class SamsungMemory extends Memory {
@Override
public void showMemory() {
System.out.println("三星 内存");
}
}
//具体产品类-- 金士顿 内存
public class KingstonMemory extends Memory {
@Override
public void showMemory() {
System.out.println("金士顿 内存");
}
}
//具体产品类-- 希捷 硬盘
public class SeagateHD extends HD {
@Override
public void showHD() {
System.out.println("希捷 硬盘");
}
}
//具体产品类-- 西部数据 硬盘
public class WdHD extends HD {
@Override
public void showHD() {
System.out.println("西部数据 硬盘");
}
}
(3) 创建抽象工厂类
//抽象工厂类,电脑工厂类
public abstract class ComputerFactory {
public abstract CPU createCPU();
public abstract Memory createMemory();
public abstract HD createHD();
}
(4)创建具体工厂类
//具体工厂类--联想电脑
public class LenovoComputerFactory extends ComputerFactory {
@Override
public CPU createCPU() {
return new IntelCPU();
}
@Override
public Memory createMemory() {
return new SamsungMemory();
}
@Override
public HD createHD() {
return new SeagateHD();
}
}
//具体工厂类--华硕电脑
public class AsusComputerFactory extends ComputerFactory {
@Override
public CPU createCPU() {
return new AmdCPU();
}
@Override
public Memory createMemory() {
return new KingstonMemory();
}
@Override
public HD createHD() {
return new WdHD();
}
}
//具体工厂类--惠普电脑
public class HpComputerFactory extends ComputerFactory {
@Override
public CPU createCPU() {
return new IntelCPU();
}
@Override
public Memory createMemory() {
return new KingstonMemory();
}
@Override
public HD createHD() {
return new WdHD();
}
}
public static void main(String[] args){
System.out.println("--------------------生产联想电脑-----------------------");
ComputerFactory lenovoComputerFactory = new LenovoComputerFactory();
lenovoComputerFactory.createCPU().showCPU();
lenovoComputerFactory.createMemory().showMemory();
lenovoComputerFactory.createHD().showHD();
System.out.println("--------------------生产华硕电脑-----------------------");
ComputerFactory asusComputerFactory = new AsusComputerFactory();
asusComputerFactory.createCPU().showCPU();
asusComputerFactory.createMemory().showMemory();
asusComputerFactory.createHD().showHD();
System.out.println("--------------------生产惠普电脑-----------------------");
ComputerFactory hpComputerFactory = new HpComputerFactory();
hpComputerFactory.createCPU().showCPU();
hpComputerFactory.createMemory().showMemory();
hpComputerFactory.createHD().showHD();
}
场景:
生产多个产品组合对象时。
优点:
代码解耦 ,创建实例工作与使用实例的工作分开 ,使用者不用担心类对象如何创建。
缺点:
如果增加新的产品,则修改抽象工厂和所有的具体工厂,违反了开放封闭原则
工厂方法模式与抽象工厂模式比较
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性。
抽象工厂模式则可以提供多个产品对象,而不是单一的产品对象。
总结:
单一产品对象,产品内不包含其他产品,多个产品对象,一个产品要其他许多配件产品组成的
1.单一产品对象并且不涉及到扩展的话,用简单工厂模式
2.单一产品对象并且涉及到扩展的话,用工厂方法模式
3.多个产品对象用抽象工厂模式
参考文章: