前语:在工厂模式中常常会分不清楚(简单工厂和工厂方法,抽象工厂)三者之前的区别,在学习设计模式时也容易混淆,这里对三者进行学习;
工厂模式:顾名思义,客户希望通过工厂(一个或一系列方法)去生产(一个或者一系列产品的实例)
本质:工厂模式是创建者模式,创建对象实例;
一.简单工厂
简单工厂类(SimpleFactory)通过接受参数的形式,调用getShape()方法区得到想要创建的对象;
如图所示:

优点:简单而且粗暴的创建对象,通过参数可以创建任何实现了接口的对象
缺点:(1)当对象类过多,简单工厂就会很臃肿,不利于简单工厂的维护 (2)不符合开放封闭原则,每次增加一个产品子类,就需要修改简单工厂
简单写了一下实现代码:但是不是按照上述UML关系图
产品接口Food的代码如下
public interface Food {
void eat();
}
实现产品接口的类Apple.class
public class Apple implements Food {
@Override
public void eat() {
System.out.println("当前吃是苹果");
}
}
实现产品接口的类Pear.class
public class Pear implements Food {
@Override
public void eat() {
System.out.println("当前正在吃梨子");
}
}
实现产品接口的类Banana.class
public class Banana implements Food{
@Override
public void eat() {
System.out.println("当前正在吃香蕉");
}
}
简单工厂方法SimpleFactory.class
public class SimpleFactory {
private Food food=null;
public Food getFood(String FoodName){
if(FoodName=="" || FoodName==null){
return null;
}
switch (FoodName){
case "Banana": food =new Banana();break;
case "Apple" : food =new Apple(); break;
case "Pear" : food =new Pear();break;
default: food=null;break;
}
return food;
}
}
方法运行Main
//简单工厂
//1.对象类型 有多种子类
//2.工厂只有 一个
//3.对象的创建延迟到工厂实例中
public class Main {
public static void main(String[] args) {
//Client 客户来吃水果
Food food =null;
SimpleFactory factory =new SimpleFactory();
food=factory.getFood("Pear");
food.eat();
}
}
运行结果:

二.工厂方法
工厂方法为每一个对象提供一种产品提供一个工厂,用于该类的实例化;
如下UML所示为工厂方法。

工厂方法的实现过程代码:
Food接口
public interface Food {
void eat();
}
Factory接口
public interface Factory {
Food create();
}
Apple.class类
public class Apple implements Food {
@Override
public void eat() {
System.out.println("当前吃是苹果");
}
}
Banana.class类
public class Banana implements Food{
@Override
public void eat() {
System.out.println("当前正在吃香蕉");
}
}
与之对应的工厂
AppleFactory.class
public class AppleFactory implements Factory {
@Override
public Food create() {
return new Apple();
}
}
BananaFactory.clsss
public class BananaFactory implements Factory{
@Override
public Food create() {
return new Banana();
}
}
工厂方法调用
public static void main(String[] args) {
Food food =null;
Factory factory =null;
/****************/
String foodName="Apple";
switch (foodName){
case "Apple":factory =new AppleFactory();break;
case "Banana":factory =new BananaFactory();break;
default:factory =null;
}
/***************/
food =factory.create();
food.eat();
}
在调用方法上仍然扩展性不足,但是可以采取反射技术弥补
运行结果:

优点:(1)与简单工厂相比,提高了工厂的扩展性,符合开放封闭原则;
缺点:(2)实现起来较之于简单工厂复杂,无法生存一系列产品
三.抽象工厂
抽象工厂是对于产品系列而言
比如衣服分为帽子,T恤从种类上分,从品牌的角度分为LiNing,Nike,针对这种情况需要创建一个产品族的对象,可以采取抽象工厂的方法
以此为思路,创建的抽象工厂UML为:

优点:可以针对一系列对象
确定:只针对一系列对象
总结:
简单工厂:针对同一级别的不同对象(扩展性较差)
工厂方法:针对同一级别的固定对象(开放修改接口,扩展性好)
抽象工厂:针对不同系列的全部对象(不支持单个产品扩展,只支持产品族扩展)
使用总结:(1)工厂模式中,工厂类采取的单例模式
(2)工厂类的基类可以是接口也可以是抽象类
(3)调用工厂采取的是指针和引用