单例模式
enum A {
INSTANCE;
public int doA() {
B.INSTANCE.doB();
return 0;
}
public static void main(String[] args) {
A.INSTANCE.doA();
}
}
DI依赖注入
public class A{
setter&&getter;
}
public class Platform{//外部平台
private Map map = new HashMap()
public static void put(String name,A a){
map.put(name,a)
}
public static A get(String name,A a){
return map.get(name);
}
public static void main(String[] arg){
A a=new A();
//增加属性
Platform.put("a",a);
Platform.get("a");
}
}
静态Map代替单例模式
DI利用的特性
- Map (容器) 的动态性 (对象唯一性)
- 全局静态变量 (调用入口)
- 对象的重复性
而单例模式只有以下特性
- 全局静态变量 (对象唯一性)
总结 : 由于没有对象的重复性, 所以单例模式是一种不能抽象的模式 (反模式)
深入探讨
从语言的角度上看
为了达到灵活性(可重复), 我们需要对象的可复制性
为了达到 唯一性, 我们需要 类的唯一性
类是对象的抽象,而对象是类的具体实例.
也就是说类是唯一, 对象是多个,可重复.
倘若我们要达到 可重复性+唯一性 , 就可以从类和对象来尝试解决
对象角度
前提
- 对象具有可重复性
需求
- 使对象唯一(达到单例模式的效果)
解决方案
- 将对象存储到 唯一容器 即可. 也就是 静态变量+容器
类的角度
前提
- 类本身具有唯一性
需求
- 修改标识(类名) , 因为这是调用方法的入口, 必须唯一
解决方案
- 使用 “元编程” 进行修改.(不知道可行否)
然而, 真正的问题是: 如何调用? 静态语言对 “元编程” 生成的代码无法进行支持. 也就是说, 即便修改成功, 我们还是要用字符串进行调用.
静态语言的特性没有得到发挥 , 对静态相当不友好
单例模式用于
- 环境搭建
DI用于
- 工程编写 ( 于环境搭建之后 ) , 因为其有可重复性.
- 有助于生命周期的控制 (需要初始化操作, 单例模式的初始化是类加载器进行的,无法控制)
常见的单例模式
enum A {
INSTANCE;
private B b = new B() //(1) 初始化放置于内部, 在初始化时候被执行.
public int doA() {
B.INSTANCE.doB();
return 0;
}
public static void main(String[] args) {
A.INSTANCE.doA();
}
}
常见的单例模式 代码(1)处, 反映了单例模式的耦合性强.
耦合性强意味着
- 连锁多, 可能会产生 “环路” ,比如环境没搭建好, 却被调用了
- 不利于编写测试
- 其他的就是, DI的好处.