- singleton的优缺点:
-确保全局至多只有一个对象;
-用于:构造缓慢的对象,需要统一管理的资源
-缺点:很多全局状态,不能保证线程安全性 - singleton的创建
-双重锁模式 Double checked Locking
-作为Java类的静态变量,但是会使对象创建时耗时很慢
-使用框架提供的能力,比如spring的自动注入 - 装饰者模式:使用这个方法的类尽量都不要使用继承。大家都去继承一个接口,比如下面的CodingTask类就是专门做事的类,而LoggingRunnable和TransactionalRunnable都是它的修饰类,但是这两个修饰内中需要额外声明一个接口对象,让这个对象去做事。大家各司其职,不要做多余的事情。
//真正做事的类
public class CodingTask implements Runnable{
@Override
public void run() {
System.out.println("Writing code.");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
//TaskCoding的装饰类1
public class LoggingRunnable implements Runnable{
private final Runnable innerRunnable;
public LoggingRunnable(Runnable innerRunnable) {
this.innerRunnable = innerRunnable;
}
@Override
public void run() {
long startTime = System.currentTimeMillis();
System.out.println("task started at "+ startTime);
innerRunnable.run();
System.out.println("task finished at"+ (System.currentTimeMillis()-startTime));
}
}
//TaskCoding的装饰类2
public class TransactionalRunnable implements Runnable{
private final Runnable innerRunnable;
public TransactionalRunnable(Runnable innerRunnable) {
this.innerRunnable = innerRunnable;
}
@Override
public void run() {
boolean shouldRollback = false;
try {
beginTransation();
innerRunnable.run();
}catch (Exception e){
shouldRollback = true;
throw e;
}finally {
if(shouldRollback){
rollback();
}else {
commit();
}
}
}
private void beginTransation(){
System.out.println("beginTransation");
}
private void rollback(){
System.out.println("rollback");
}
private void commit(){
System.out.println("commit");
}
}
//执行的代码
new LoggingRunnable(new TransactionalRunnable(new CodingTask())).run();
**以上的代码就实现了多个类逐层包装,特别注意的是,三个类都实现了公共接口Runnable接口。
- 使用new创建对象的缺点:
-在写代码时就必须要决定要创建哪个类的对象
-参数意义不明确,即构建对象时如果不看源码,就不知道这几个输入的参数到底是什么意义
解决办法:
-工厂模式,依赖于自动注入
-builder factory,在输入时每个参数意义一目了然