工厂模式主要分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。
一、简单工厂模式
模式定义:
简单工厂模式又称之为静态工厂方法,属于创建型模式。在简单工厂模式中,可以根据传递的参数不同,返回不同类的实例。简单工厂模式定义了一个类,这个类专门用于创建其他类的实例,这些被创建的类都有一个共同的父类。
模式结构:
模式实现:
public class SimpleFactory {
/**
* 测试类
*/
@Test
public void simpleFactoryTest() {
Computer computer = ComputerFactory.createComputer("microsoft");
if (null != computer) {
computer.calculate();
}
}
}
/**
* 抽象产品类
*/
abstract class Computer {
/**
* 名称
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 抽象方法
*/
abstract void calculate();
}
/**
* mac
*/
class Mac extends Computer {
@Override
void calculate() {
setName("Mac");
System.out.println("mac calculate");
}
}
/**
* windows
*/
class Microsoft extends Computer {
@Override
void calculate() {
setName("Microsoft");
System.out.println("windows calculate");
}
}
/**
* 电脑工厂
*/
class ComputerFactory {
/**
* 根据类型生产产品
*
* @param type
* @return
*/
public static Computer createComputer(String type) {
Computer computer = null;
if ("mac".equals(type)) {
computer = new Mac();
} else if ("microsoft".equals(type)) {
computer = new Microsoft();
}
return computer;
}
}
模式优点:
1、简单工厂模式实现了对责任的分割,提供了专门的工厂类用于创建对象
2、客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量
3、通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性
模式缺点:
1、由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
2、使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度
3、系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护
使用场景:
1、工厂类负责创建的对象比较少
2、客户端只知道传入工厂类的参数,对于如何创建对象不关心
二、工厂方法模式
模式定义:
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让实例化推迟到子类
模式结构:
模式实现:
public class SimpleFactory {
/**
* 测试类
*/
@Test
public void factoryMethodTest() {
ComputerFactory factory = new MacFactory();
//如需更改,只需增加一行代码即可
factory = new MicrosoftFactory();
Computer computer = factory.createComputer();
if (null != computer) {
computer.calculate();
}
}
}
/**
* 抽象产品类
*/
abstract class Computer {
/**
* 名称
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 抽象方法
*/
abstract void calculate();
}
/**
* mac
*/
class Mac extends Computer {
@Override
void calculate() {
setName("Mac");
System.out.println("mac calculate");
}
}
/**
* windows
*/
class Microsoft extends Computer {
@Override
void calculate() {
setName("Microsoft");
System.out.println("windows calculate");
}
}
/**
* 抽象工厂
*/
abstract class ComputerFactory {
public abstract Computer createComputer();
}
/**
* mac电脑制造工厂
*/
class MacFactory extends ComputerFactory {
@Override
public Computer createComputer() {
return new Mac();
}
}
/**
* windows电脑制造工厂
*/
class MicrosoftFactory extends ComputerFactory {
@Override
public Computer createComputer() {
return new Microsoft();
}
}
模式优点:
1、在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名
2、在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”
模式缺点:
1、每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事
使用场景:
1、一个类不知道它所需要的对象的类。在工厂方法模式中,我们不需要具体产品的类名,我们只需要知道创建它的具体工厂即可
2、将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定
三、抽象工厂模式
模式定义:
抽象工厂模式提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。
在讲解抽象工厂模式之前,我们需要理解两个概念:
产品等级结构。产品的等级结构也就是产品的继承结构。例如一个为空调的抽象类,它有海尔空调、格力空调、美的空调等一系列的子类,那么这个抽象类空调和他的子类就构成了一个产品等级结构。
产品族。产品族是在抽象工厂模式中的。在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,海尔工厂生产海尔空调。海尔冰箱,那么海尔空调则位于空调产品族中。
模式结构:
模式实现:
public class SimpleFactory {
/**
* 测试类
*/
@Test
public void abstractFactoryTest() {
ComputerFactory factory = new MacFactory();
//如需更改,只需增加一行代码即可
factory = new MicrosoftFactory();
Computer computer = factory.createComputer();
Earphone earphone = factory.createEarphone();
computer.calculate();
earphone.listenMusic();
}
}
/**
* 抽象电脑类
*/
abstract class Computer {
/**
* 名称
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 抽象方法
*/
abstract void calculate();
}
/**
* mac
*/
class Mac extends Computer {
@Override
void calculate() {
setName("Mac");
System.out.println("mac calculate");
}
}
/**
* windows
*/
class Microsoft extends Computer {
@Override
void calculate() {
setName("Microsoft");
System.out.println("windows calculate");
}
}
/**
* 抽象耳机类
*/
abstract class Earphone {
/**
* 抽象方法
*/
abstract void listenMusic();
}
/**
* mac耳机
*/
class MacEarphone extends Earphone {
@Override
void listenMusic() {
System.out.println("mac listen music");
}
}
/**
* windows耳机
*/
class MicroEarphone extends Earphone {
@Override
void listenMusic() {
System.out.println("windows listen music");
}
}
/**
* 抽象工厂
*/
abstract class ComputerFactory {
public abstract Computer createComputer();
public abstract Earphone createEarphone();
}
/**
* mac电脑制造工厂
*/
class MacFactory extends ComputerFactory {
@Override
public Computer createComputer() {
return new Mac();
}
@Override
public Earphone createEarphone() {
return new MacEarphone();
}
}
/**
* windows电脑制造工厂
*/
class MicrosoftFactory extends ComputerFactory {
@Override
public Computer createComputer() {
return new Microsoft();
}
@Override
public Earphone createEarphone() {
return new MicroEarphone();
}
}
1、抽象工厂隔离了具体类的生成,是的客户端不需要知道什么被创建。所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为
2、当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象
模式缺点:
1、添加新的行为时比较麻烦。如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦
使用场景:
1、系统中有多于一个的产品族,而每次只使用其中某一产品族
2、属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来
3、系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
总结:
简单工厂模式:
1、简单工厂模式的要点就在于当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节
2、简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,但是如果产品过多时,会导致工厂代码非常复杂
工厂方法模式:
1、工厂方法模式完全符合“开闭原则”
2、工厂方法允许类将实例化延伸到子类进行
3、工厂方法让子类决定要实例化的类时哪一个。在这里我们要明白这并不是工厂来决定生成哪种产品,而是在编写创建者类时,不需要知道实际创建的产品是哪个,选择了使用哪个子类,就已经决定了实际创建的产品时哪个了
抽象工厂模式:
1、 抽象工厂模式中主要的优点在于具体类的隔离,是的客户端不需要知道什么被创建了。其缺点在于增加新的等级产品结构比较复杂,需要修改接口及其所有子类