服务定位器模式
Forewrod
今天在看Spring Framework官方文档的时候,看到相关的一段描述:
本章介绍了控制反转(IoC)原理的Spring框架实现。IoC也称为依赖注入(DI)。在此过程中,对象仅通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依赖项(即,与它们一起使用的其他对象) 。然后,容器在创建bean时注入那些依赖项。此过程从根本上讲是通过使用类的直接构造或诸如
服务定位器模式
之类的方法来控制其依赖项的实例化或位置的bean本身的逆过程(因此称为Control Inversion)。
那我就先了解一下服务定位器模式,管中窥豹,多方面了解Spring IoC。
参考链接:MartinFowler.com
What
服务定位器模式(Service Locator Pattern),最主要的用途是:解耦,也就是消除对实现类的依赖。一个类可能依赖另外一个类的接口及实现,但是我们希望的是:只依赖接口,不依赖其实现。
How
我们来看一个例子:蓝牙鼠标与电池
//测试类
public class Test {
public static void main(String []args) {
BluetoothMouse bm = new BluetoothMouse();
bm.click();
}
}
//蓝牙鼠标 与 电池
//蓝牙鼠标
class BluetoothMouse {
private Battery battery;
public BluetoothMouse() {
this.battery = new NanfuBattery();
}
//鼠标按下
public void click (){
//获取电池状态
boolean batteryStatus = battery.status();
if ( batteryStatus ) {
System.out.println("click done");
} else {
System.out.println("battery lower power");
}
}
}
//电池
interface Battery {
boolean status();
}
//南孚电池
class NanfuBattery implements Battery{
@Override
public boolean status(){
return true;
}
}
注意到,初始化BluetoothMouse
类时,同时初始化了NanfuBattery
类,此时BluetoothMouse
依赖NanfuBattery
其实现。
如何解耦,我们可以设计一个BatteryLocator
类,去new NanfuBattery();
,就能实现解耦:
添加的BatteryLocator
类
class BatteryLocator{
private static BatteryLocator locator;
private static Battery battery;
public static Battery getBattery(){
return locator.battery;
}
public BatteryLocator(Battery battery){
BatteryLocator.battery = battery;
}
public static void load(BatteryLocator locator) {
BatteryLocator.locator = locator;
}
//初始化BatteryLocator并给locator赋值
static {
BatteryLocator.load(new BatteryLocator(new NanfuBattery()));
}
}
把BluetoothMouse
构造方法改为:
public BluetoothMouse() {
//修改为BatteryLocator.getBattery();
this.battery = BatteryLocator.getBattery();
}
实现BluetoothMouse只依赖NanfuBattery的接口,不依赖其实现。
上面这个还可以继续再优化,请看上面给出的链接:MartinFowler.com
When & Where
慎用
others
spring IoC也用到了这种模式,但很复制。其次,说了Service Locator Pattern是消除依赖的一种设计模式,处了这种以外,还有接口注入/设值方法注入/构造函数注入可以消除依赖。
结束语:优秀是一种习惯