前言
工厂模式属于创建型模式,它很好的解耦了对象的创建依赖。什么是对象的依赖呢? 在java中如果在一个类里new
创建了一个对象, 就说明这个类依赖了被创建的对象的类。
工厂模式主要关注如何创建对象,在简单工厂模式下我们传入所需要创建类的关键字就可以得到我们需要的对像,在工厂方法中我们可以通过一个个单独的工厂创建不同的对象(一个面包工厂可以生产面包对象,一个披萨工厂可以生产披萨对象),而在抽象工厂中一个工厂具有了多个功能,相比于工厂方法模式它的工厂既可以生产面包对象又可以生产披萨对象。
在自己动手实践后,我们可以清晰的发现,简单工厂就像一个杂货铺,你只要给“物品”贴一个标签(key),就可以在这个“杂货铺”售卖它了,这个杂货铺有什么东西,我们需要自己看有哪些标签(不像工厂方法和抽象工厂,对象的创建有具体的方法和接口),这也就说明通过简单工厂创建对像时他有可能不存在(传入key对象可能为null);对于工厂方法,它是比较专一的工厂——他只生产它相关的对象(面包工厂只专注生产面包,披萨工厂只专注生产披萨);抽象工厂可以认为是一个超级工厂,我既可以生产这个也可以生产哪个,抽象工厂的抽象体现在工厂继承抽象工厂类或实现抽象工厂接口(这个顶层的抽象定义了工厂可以生产的产品),这个“超级工厂”对比简单工厂"杂货铺"并不乱,这方面要归功于接口。
下面让我们结合代码和类的结构来看一下。
简单工厂
类图
在这个类关系图中BlackBreak和HoneyBread继承了BreadMaker,在BreadFactory中创建BlackBread、HoneyBread对象。这里的BreadMaker可以使用接口代替,因为BreadMaker只是实现了制作面包的功能,在面向对象中功能最好使用接口来定义,可以更好的解耦依赖。
BreadMaker
public abstract class BreadMaker {
public abstract void getBread();
}
BlackBread
public class BlackBread extends BreadMaker {
// 重写
@Override
public void getBread() {
System.out.println("考出黑面包");
}
}
HoneyBread
public class HoneyBread extends BreadMaker {
@Override
public void getBread() {
System.out.println("烤出蜂蜜面包");
}
}
BreadFactory
public class BreadFactory {
public static BreadMaker makeBread(int breadType) {
switch (breadType) {
case 0:
return new BlackBread();
case 1:
return new HoneyBread();
default: {
// 当用户输入一个不存在的breadType, 工厂不能创建对象, 将返回null对象
System.out.println("工厂没有这种类型的面包");
return null;
}
}
}
}
Main 客户端
public class Main {
public static void main(String[] args) {
BreadMaker breadMaker;
breadMaker = BreadFactory.makeBread(0);
breadMaker.getBread();
breadMaker = BreadFactory.makeBread(1);
breadMaker.getBread();
}
}
output:
考出黑面包
烤出蜂蜜面包
有的人说简单工厂模式并不算一种工厂方法, 这里不反驳也不赞同, 使用一种设计模式最重要的是适合自己业务, 适合是最重要的! 回想想一下spring中的IOC, 通过key来创建一个对象或者拿到对象的引用也是很好的设计.
工厂方法
工厂方法 – 我只生产我专注产品! 这是工厂方法的优点, 但是有时候确实没有必要为一个简单的对象创建再写一个工厂类, 这是生产的"产品"简单的时候。
HoneyBreadFactory和BlackBreadFactory都实现了IFactory接口, 二者生产的目标不一样, HoneyBreadFactory专注于生产蜂蜜面包, 而BlackBread专注于生产烤面包. 图中中间部分, BlackBread和HoneyBread继承BreadMaker是为了统一接收对象(工厂方法返回对象统一使用BreadMaker接收).
IFactory
public interface IFactory {
BreadMaker creatMaker();
}
HoneyBreadFactory
public class HoneyBreadFactory implements IFactory {
@Override
public BreadMaker creatMaker() {
return new HoneyBread();
}
}
BlackBreadFactory
public class BlackBreadFactory implements IFactory{
@Override
public BreadMaker creatMaker() {
return new BlackBread();
}
}
BreadMaker
public abstract class BreadMaker {
public