简单工厂模式
抽象对象:把要生产的对象共同点抽离出来做成一个接口或者抽象类。
具体对象:继承实现抽象对象,更具体化。
简单工厂:判断要生产哪个对象,就调用哪个方法进行生产。
//抽象对象角色
abstract class Car{
String name;
long price;
public String toString(){
return "Car name = "+name+", price = "+price;
}
}
//具体对象角色
class BMW extends Car{
public BMW(String name,long price){
this.name=name;
this.price=price;
}
}
//具体对象角色
class BananaCar extends Car{
public BananaCar(String name,long price){
this.name=name;
this.price=price;
}
}
//简单工厂角色
class CarFactorBySimple{
public static Car getCar(Class<?> carClass){
if (carClass.getName().equals(BMW.class.getName()))
return new BMW("宝马",500000);
else if(carClass.getName().equals(BananaCar.class.getName()))
return new BMW("香蕉车",250);
else
return null;
}
}
简单工厂的缺陷
如果这时候我想要生产一辆卡丁车,那么我就必须去修改简单工厂角色的判断逻辑,新增生产卡丁车的判断逻辑。这不符合开闭原则。
开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
工厂方法模式
抽象对象:把要生产的对象共同点抽离出来做成一个接口或者抽象类。
具体对象:继承实现抽象对象,更具体化。
抽象工厂:把生产方法抽离出来
具体工厂:实现抽象工厂,针对不同的需求生产不同的对象
//抽象工厂角色
interface CarFactoryService{
Car getCarByFactory();
}
//具体工厂角色
class BMWFactory implements CarFactoryService{
@Override
public Car getCarByFactory() {
return new BMW("宝马",500000);
}
}
//具体工厂角色
class BananaCarFactory implements CarFactoryService{
@Override
public Car getCarByFactory() {
return new BananaCar("香蕉车",250);
}
}
工厂方法模式解决了简单工厂模式想要扩展,不得不改写工厂生产逻辑的问题。把生产不同的车交由不同的工厂来实现,当我们需要获得卡丁车,就不用去改写原有的逻辑。只需要实现抽象工厂,新增一个卡丁车工厂来生产卡丁车。
工厂方法的缺陷
如果这时候我不单单想生产车了,我还想给车配上音乐。可是这时候只有生产车的工厂,想要生产音乐,又得去修改原有的代码。
抽象工厂模式
抽象对象:把要生产的对象共同点抽离出来做成一个接口或者抽象类。
具体对象:继承实现抽象对象,更具体化。
抽象工厂:把生产方法抽离出来
具体工厂:实现抽象工厂,针对不同的需求生产不同的对象
abstract class Music{
String type;
String name;
public String toString(){
return "Music type = "+type+", name = "+name;
}
}
class RockAndRoll extends Music {
public RockAndRoll(String type,String name){
this.type=type;
this.name=name;
}
}
class Folk extends Music{
public Folk(String type,String name){
this.type=type;
this.name=name;
}
}
//在一个抽象工厂角色中包含多个生产不同类型产品的工厂方法
abstract class Factory{
public abstract Car carFactory();
public abstract Music MusicFactory();
}
//
class FactoryOne extends Factory{
@Override
public Car carFactory() {
return new BMW("宝马",3600);
}
@Override
public Music MusicFactory() {
return new RockAndRoll("Rock","Drive my car");
}
}
class FactoryTwo extends Factory{
@Override
public Car carFactory() {
return new BananaCar("香蕉车",3600);
}
@Override
public Music MusicFactory() {
return new Folk("Folk","Take me home,Country road!");
}
}
简单工厂模式------------>工厂方法模式---------------->抽象工厂模式
三个工厂模式阶段面对的是不同的需求。核心就是开闭原则,在设计之初,就应该考虑系统的扩展性,如果需求增加,要反复修改底层的代码逻辑,那样是不合适的。
当确定只生产一类的产品(车),并且不会增加子产品(卡丁车),就可以选择简单工厂模式。
不确定会不会增加子产品,选择工厂方法模式,增加一个子产品(卡丁车),就实现一个生产卡丁车的工厂。
当不仅仅要生产车这一类的产品,还要生产音乐,那么只生产车的工厂显然不够,选择抽象工厂方法,提供生产车和音乐的方法,交由下方的具体工厂,生产不同的车和音乐。