有了基本的语法学习,和一定编码能力之后,需要在思想上提升自己,尝试着自己去架构一个项目,设计一个项目。那么对设计模式的了解学习,以及对优秀开源框架和jdk源码中所涉及到的设计模式的研究,都是很有意义的事情。站在巨人的肩膀上,我们可以走的更远。
本节主要介绍一下简单工厂方法模式,大致思路如下:
1)给出具体的实现代码
2)分析代码
3)对简单工厂模式中涉及到的角色,进行分析
4)对简单工厂方法模式进行总结
1、首先定义一个接口类Fruit,将所有水果具有的功能抽象成一个接口,具体的实现功能由子类来完成。
public interface Fruit {
/*
* 采摘功能
*/
void pickFruit();
}
2、定义两个具体的实现
public class Apple implements Fruit{
@Override
public void pickFruit() {
System.out.println("pick apple...");
}
}
public class DragonFruit implements Fruit{
@Override
public void pickFruit() {
System.out.println("pick dragon fruit...");
}
}
3、创建一个能生产所有水果对象的工厂类
public class FruitFactory {
public static Fruit getFruit(String fruitType) {
if (fruitType.equalsIgnoreCase("apple")) {
return new Apple();
} else if (fruitType.equalsIgnoreCase("dragon")) {
return new DragonFruit();
} else {
System.out.println("sorry,there is not the result that you want...");
return null;
}
}
}
4、创建测试代码
public static void main(String[] args) {
Fruit apple = FruitFactory.getFruit("apple");
Fruit dragon = FruitFactory.getFruit("dragon");
apple.pickFruit();
dragon.pickFruit();
}
5、运行结果
pick apple...
pick dragon fruit...
6、整个过程的思路分析:
1)创建一个Fruit接口类,定义一个采摘功能的方法pickFruit(),所有的Fruit对象都具有这个功能。
2)定义一个Apple和DragonFruit去实现Fruit接口。到现在为止,还没有和工厂方法模式有任何的关系。此时再建立FruitFactory这个类的意义在哪?下面这种方式来实现,不是更简单?
public static void main(String[] args) { Fruit apple = new Apple(); Fruit dragon = new DragonFruit(); apple.pickFruit(); dragon.pickFruit(); }
首先,FruitFactory这个类的真正意义在这个场景下,不能体现出这个它的真正意义,这里的目的很简单,去了解简单工厂模式的基本实现。
简要解释一下FruitFactory存在意义:
设想Apple类、DragonFruit类在初始化的时候要加载一些信息,比如Apple类、DragonFruit类的供应商信息等,它们具有相同的供应商信息,客户端在使用的时候,如果在没有FruitFactory这个对象存在的情况下,Apple、DragonFruit都需要自己去实现,现在交给FruitFactory就可以了。
7、简单工厂方法模式中的概念分析:
*角色:
工厂角色:FruitFactory,简单工厂方法模式中的核心。它负责创建所有实例的内部逻辑,工厂类可以直接被外界直接调用,创建所需的具体产品对象。
抽象角色:Fruit,这更多的是面向对象,面向接口编程的一种体现。简单工厂FruitFactory所创建对象的基类(父类),负责规定所有实例对象的公共接口。
具体产品:Apple、DragonFruit,简单工厂所创建的具体实例对象。
8、简单工厂模式的优缺点分析:
优点:
客户端(用户)在使用简单工厂类,进行创建对象时,不需要关注这些对象如何创建和组织,忽略其初始化的细节,减轻客户端的压力,有利于整个软件结构的优化。
缺点:
1)在本例中,客户端想要创建一个对象时,必须要知道工厂类参数的形式(可以考虑将这个参数维护在一个枚举类中),当系统中产品类很多时,对客户端来说,压力比较大。
2)将所有对象的创建逻辑都在FruitFactory中进行定义,如果我要增加一个GrapeFruit类,需要将FruitFactory工厂类的创建逻辑进行修改,违背了OCP原则(开闭原则,在程序进行扩展的时候,不能去修改原有的,而是扩展原有的代码)