(三)单例模式
单例模式应该是最常见的设计模式,作用是保证在JVM中,该对象只有一个实例存在。
优点:1、减少某些创建比较频繁的或者比较大型的对象的系统开销。
2、省去了new操作符,降低系统内存使用频率,减轻GC压力。
3、保证核心代码的唯一性,比如交易引擎。
单例模式看似是最简单的设计模式。
public class Singleton { //私有构造方法,防止实例化 private Singleton(){ } //创建类的实例的时候加载 private static Factory factory = new Factory(); //延迟加载 private static Factory factory1; public static Factory getInstans(){ if(factory1 == null){ factory1 = new Factory(); } return factory1; } }
上面是比较常见的单例模式的写法,后一种延迟加载应该是实际应用中使用比较多的方式,但是这种加载方式如果在多线程模式下就有可能出现问题。对于多线程的处理,第一个想到的就是 synchronized 线程锁。
private static Factory factory; private static Object classlock = Singleton.class; public static Factory getInstances(){ synchronized (classlock) { if(factory == null){ factory = new Factory(); } return factory; } } public static Factory getInstance(){ if(factory == null){ syncInit(); } return factory; } private static synchronized void syncInit(){ if(factory == null){ factory = new Factory(); } }以上是两种线程锁的方法,第一种是对象锁,但是因为每次调用都需要加锁,性能会有部分损失。第二种是方法锁。但是实际上,无论 synchronized 关键字加在方法上还是对象上,它取得的锁都是对象,而不是吧一段代码或函数当作锁。
单例模式是为了保证类只有一个实例,并为类提供全局访问点,单例模式最富盛名,但是最容易误用,不要让它成为创建全局变量的花哨方法。类应该只需要知道与它协作的对象,不必了解创建它需要的限制。单例模式一定要记住隐藏构造函数,也就是在类里面写一个
private 的构造函数。
(四)建造者模式
建造者模式的意图是将类的构建逻辑转移到类的实例化外部。建造者模式比抽象工厂模式又复杂一点,抽象工厂有一个 Factory 现在多一个工厂的主管 Director 他来管理工厂的生产过程。
interface Builder { void buildPartA(); void buildPartB(); void buildPartC(); Product getResult(); } interface Product { } interface Part { } class Car implements Product{ private String door; private String windows; public String getDoor() { return door; } public void setDoor(String door) { this.door = door; } public String getWindows() { return windows; } public void setWindows(String windows) { this.windows = windows; } } //具体建造工具 class ConcreteBuilder implements Builder { Part partA, partB, partC; private static Car product = new Car(); public void buildPartA() { //这里是具体如何构建partA的代码 product.setDoor("铁的"); }; public void buildPartB() { //这里是具体如何构建partB的代码 product.setWindows("玻璃的"); }; public void buildPartC() { //这里是具体如何构建partB的代码 }; public Product getResult() { return product; //返回最后组装成品结果 }; } //具体建造工具 class ConcreteBuilder2 implements Builder { Part partA, partB, partC; private static Car product = new Car(); public void buildPartA() { //这里是具体如何构建partA的代码 product.setDoor("木头的"); }; public void buildPartB() { //这里是具体如何构建partB的代码 product.setWindows("玻璃的"); }; public void buildPartC() { //这里是具体如何构建partB的代码 }; public Product getResult() { return product; //返回最后组装成品结果 }; } //建造者 class Director { private Builder builder; public Director( Builder builder ) { this.builder = builder; } public void construct() { builder.buildPartA(); builder.buildPartB(); builder.buildPartC(); } } public class BuilderPattern { public static void main(String[] args){ //获得具体的工厂 ConcreteBuilder2 builder = new ConcreteBuilder2(); //将工厂给管理者 Director director = new Director( builder ); //管理者构造出产品 director.construct(); //在工厂取得产品 Car product = (Car) builder.getResult(); System.out.println(product.getDoor()); } }不同的工厂就会生产出不同的产品,但是生产什么产品是管理者决定的,假如管理者的
construct不生产门了,那么最终的产品也就没有门了。
建造者模式可以控制中间的生产过程,比如读取 xml 时候用来判断某个值是否有数据。或者拼装 sql 语句的时候
SqlString sql = new SqlString(); if(forUpdate) { sql.selectForUpdate(db); } else { sql.select(db); } sql.from(db).where().eq(db);