简单工厂模式不能说是一个设计模式,说它是一种编程习惯可能更恰当些。用动画的角度来说,就叫ova(原创动画)吧!
一、模式结构
简单工厂模式包含如下角色:
Factory:工厂角色
Product:抽象产品角色
ConcreteProduct:具体产品角色
工厂角色(Creator) |
是简单工厂模式的核心,它负责实现创建所有具体产品类的实例。工厂类可以被外界直接调用,创建所需的产品对象。 |
抽象产品角色(Product) |
是所有具体产品角色的父类,它负责描述所有实例所共有的公共接口。 |
具体产品角色(Concrete Product) |
继承自抽象产品角色,一般为多个,是简单工厂模式的创建目标。工厂类返回的都是该角色的某一具体产品。 |
二、结构栗子
(1)、工厂角色-水果农场
(2)、抽象产品角色-水果Fruit
(3)、具体产品角色-苹果Apple、香蕉Banana
三、简单工厂模式优缺点
1、优点
- 实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责,但是其最大的缺点在于工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
- 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
2、缺点
- 违背“开放 - 关闭原则”(ocp),一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
- 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
- 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
四、栗子
如图:
1、抽象产品角色
package com.SimpleFactoryMode_01;
/**
* @description: 抽象产品角色-水果
* @author: ziHeng
* @create: 2018-08-02 14:31
**/
public interface Fruit {
void get();
}
2、具体产品角色-苹果和香蕉
package com.SimpleFactoryMode_01;
/**
* @description: 具体产品角色-苹果
* @author: ziHeng
* @create: 2018-08-02 14:30
**/
public class Apple implements Fruit{
public void get(){
System.out.println("得到苹果");
}
}
package com.SimpleFactoryMode_01;
/**
* @description: 具体产品角色-香蕉
* @author: ziHeng
* @create: 2018-08-02 14:31
**/
public class Banana implements Fruit{
public void get(){
System.out.println("得到香蕉");
}
}
3、工厂角色-可通过反射返回具体产品实例
package com.SimpleFactoryMode_01;
/**
* @description: 工厂角色-水果工厂
* @author: ziHeng
* @create: 2018-08-02 14:32
**/
public class FruitFactory {
public static Fruit getFruit(String type) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//降低扩展性,但增加了容错率适用性,例如复杂类名
/*if("Apple".equalsIgnoreCase(type)){
return Apple.class.newInstance();
}else if("Banana".equalsIgnoreCase(type)){
return Banana.class.newInstance();
}else {
System.out.println("没有实例");
return null;
}*/
//增加新的具体产品,不用修改工厂代码,但类名需对应,类名容错率低
//具体包名+类名
return (Fruit) Class.forName("com.SimpleFactoryMode_01."+type).newInstance();
}
}
调用Test:
package com.SimpleFactoryMode_01;
/**
* @description: 调用者
* @author: ziHeng
* @create: 2018-08-02 14:35
**/
public class Test {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
Fruit apple = FruitFactory.getFruit("Apple");
Fruit banana = FruitFactory.getFruit("Banana");
apple.get();
banana.get();
}
}