前言
以下只是我个人在学习设计模式的过程中的笔记,并不专业,各位大佬如果发现错误的话,欢迎在评论区指出。
工厂模式介绍
在Java中创建对象最简单的方法就是使用关键字new,但如果在代码中随意的使用new会导致代码变得脆弱,缺乏弹性可维护性变差。举个例子,如果你在代码中很多做了new A()这个操作,当需求变化,要把new A()改为new B(),就需要把所有的new A()都改为new B(),这样的代码耦合性很高,维护起来就会很困难,所谓开发一时爽,维护火葬场。而工厂模式就可以很好的应对这种问题。通过把对象的创建和使用分离,达到解耦和的效果。
工厂模式实现
工厂模式的实现大体上可以分为三类: 简单工厂、工厂方法,抽象工厂。
1、简单工厂
为了方便理解,先假设有一个Restaurant类和一个Food接口以及实现了Food接口的具体类,可以用这个Restaurant类来进行点餐服务,获取不同的Food。
现在我们来写Restaurant类的代码,
观察上面的代码,就会发现这种方式会导致耦合性很高,为了应付不同的Food,就需要在代码中加入大量的if判断语句,每增加一种菜品,我们就要修改我们的代码向其中加入新的判断。解决办法就是使用简单工厂,将容易发生改变的代码封装到另一个对象中,由这个对象专职创建。这个对象就叫做工厂。修改后的代码如下:
这是工厂类
这是修改后的Restaurant
可以看到Food的创建和使用已经分离了。但是有的小伙伴可能会有疑惑,这个简单工厂到底有什么用呢?只是把问题从一个地方移到了另一个地方,问题依然还在。
表面上看的确是这样,但别忘了,使用工厂的对象可能不止一个,可能有很多个。在需要改变对象的创建过程时,只需改变工厂中的代码即可。
2、工厂方法
工厂方法可以理解为是对简单工厂的一种改进,让其更加富有弹性,能面对更加复杂多样化的情况,我们还是以上面的Restaurant类和Food来举例,假设你经营有方,在各地开了分店,每个分店都和原来一摸一样。在经营过程中你发现每个地方的人的口味不一样,同样一个Food有的地方的人喜欢咸一点的,有的地方的人喜欢淡一点的。你想根据每个地方的人的口味来制作食物,如果按照原来的简单工厂,每个地方的都是一个工厂生产的,那肯定做不到,这个时候就轮到工厂方法登场了。
在工厂方法中,我们直接把Restaurant抽象成一个抽象类,提供一个抽象的制作方法,由各个Restaurant子类重写制作方法,由各个子类自己决定具体的制造流程。
代码如下:
//抽象的Restaurant类
public abstract class Restaurant {
Food food = null;
public Restaurant() {
this.food = createFood();
}
public void show(){
this.food.show();
}
public abstract Food createFood();
}
//具体实现类A
public class RestaurantA extends Restaurant{
public RestaurantA() {
this.food = createFood();
this.food.show();
}
@Override
public Food createFood() {
return new FoodB();
}
}
//具体实现类B
public class RestaurantB extends Restaurant{
public RestaurantB() {
this.food = createFood();
this.food.show();
}
@Override
public Food createFood() {
return new FoodB();
}
}
3、抽象工厂
抽象工厂其实就是在工厂方法的基础上进行了进一步的改进,有的博主说的是,抽象工厂是创建工厂的工厂,有的说是创建多种不同类型产品的工厂,我觉得这两种说法其实都对,抽象工厂的任务是定义一个创建一组不同类型产品的接口,接口内的每个抽象方法都是负责创建一种类型的产品,如果用上面的例子来说的话就是工厂不仅生产Food还生产Drinks。
可以看到,接口中每一个方法负责创建一类产品,这与工厂方法一致,所以说工厂方法其实潜伏在抽象工厂中。