创建型模式-简单工厂模式
1、简单理解
考虑一个简单应用场景:一个软件系统能够提供多种不同颜色,形状的按钮,这些按钮都源自一个基类,不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,只需要知道表示该按钮类的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象,此时,就可以使用简单工厂模式。
2、模式定义
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
3、模式结构
简单工厂模式包含以下三种角色
- Factory,工厂角色:负责实现创建所有实例的内部逻辑
- product,抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口
- ConcreteProduct:具体产品角色:具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
4、代码实例
一个表示形状的基类(product角色),包含一个描述方法
/**
- @Auther xiaoyao75
- @Date 2020/8/5 18:34
*/
public interface Shape {
void descrip();
}
一个表示圆形的类,实现了Shape基类(ConcreteProduct角色)
/**
- @Auther xiaoyao75
- @Date 2020/8/5 18:41
*/
public class Circle implements Shape {
@Override
public void descrip() {
System.out.println("circle");
}
}
一个表示方形的类,实现了Shape基类(ConcreteProduct角色)
/**
- @Auther xiaoyao75
- @Date 2020/8/17 14:34
*/
public class Squre implements Shape {
@Override
public void descrip() {
System.out.println("squre");
}
}
抽象工厂类,用来创建实例化对象(Factory角色)
/**
- @Auther xiaoyao75
- @Date 2020/8/17 14:34
*/
public class ShapeFactory {
public static Shape getShape(String name){
if (name.equals("Circle")){
return new Circle();
}else if(name.equals("Squer")){
return new Squre();
}
return null;
}
}
测试类
/**
- @Auther xiaoyao75
- @Date 2020/7/20 16:55
*/
public class Main {
public static void main(String[] args) {
Shape shape=ShapeFactory.getShape("Circle");
shape.descrip();
Shape shape1=ShapeFactory.getShape("Squer");
shape1.descrip();
}
}
5、优势
- 将具体的product角色的产品类的创建和消费进行了解耦,工厂类包含了创建的具体逻辑,在什么条件下创建什么产品,而消费者不需要考虑产品的创建过程,只是负责消费。简单工厂模式对此进行了责任上的分割
- 产品消费者是无需知道产品的具体类名的,只需要知道该产品的必要参数。
- 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
6、缺点
- 由于工厂类集合了所有的创建逻辑,如果工厂类不能正常使用,则整个系统都会受到影响
- 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
7、适用环境
- 工厂类所需要的创建的产品类型较少,这样不会造成工厂类中的逻辑过于复杂
- 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
8、应用举例
如Java中的一个工具类java.text.DateFormat,用来格式化一个本地日期
public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int style);
public final static DateFormat getDateInstance(int style,Locale
locale);
Java加密技术,通过传入参数判断使用哪种加密算法
//获取不同加密算法的秘钥生成器
KeyGenerator keyGen=KeyGenerator.getInstance("DESede");
//创建密码器
Cipher cp=Cipher.getInstance("DESede");