工厂的三种模式:目的都是解耦
简单工厂
工厂是一个类:生产各种各样产品;不同类实现接口;业务全部在fractory中,违反了开闭原则。
使用在业务简单的情况下。
工厂方法(如果工厂的产品全部属于同一个等级结构,则属于工厂方法。)
定义一个创建对象的工厂接口,让子类决定实例化哪一个类,将实际工作交给子类
例子:
工厂是一个接口,produceTrunk() ,实现创建不同卡车类
卡车也是一个接口,实现不同卡车类
将不同卡车的业务逻辑抽离出fractory
优点
符合开闭原则,每增加一种产品,只需要增加相应具体的产品类和工厂子类。
符合单一职责原则,每个具体工厂类只负责创建对应的产品。
缺点
在增加一个新产品时,需要增加一个产品类和一个具体的子工厂,每个工厂生产一种产品,太过单一。
抽象工厂(如果工厂的产品来自多个等级结构,则属于抽象工厂模式)
抽象工厂角色:具体工厂必须时间的接口。
具体工厂角色:和具体业务逻辑相关的代码,创建对应的具体产品的对象。
抽象工厂:producetrunk(); producesedan();
具体工厂:宝马工厂(宝马轿车、宝马卡车)奥迪工厂(奥迪轿车、奥迪卡车)
抽象产品:卡车、轿车
具体产品:宝马卡车,宝马轿车,奥迪卡车,奥迪轿车
单例模式
概念:包含一个被称为单例的特殊类。
特点:单例类只能有一个实例;单例类必须自己创建自己的唯一实例;单例类必须给所有其他对象提供这一实例。
实现:private 构造类避免了外部类对此类进行实例化
场景需求:
1.计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
2.创建的一个对象需要消耗的资源过多,比如IO与数据库的连接等。
如何选择:
饿汉式是线程安全的,但是类加载就创建对象。如果在一个工厂模式下,缓存了很多实例,就得考虑效率问题,因为这个类一加载就把所有实例一起创建了(不管用不用);懒汉式优点是延时加载,缺点是需要用同步。看实际需求选择。
优点:在内存中只有一个实例,减少了内存开销,尤其是频繁创建和销毁实例(工具类);避免对资源的多重占用(比如写文件操作)
缺点:扩展很困难(private修饰的方法无法继承,不能再扩展)
饿汉式单例
在类加载初始化时就创建好一个静态的对象供外部使用,除非系统重启,这个对象不会改变,本身是线程安全的。
package single; public class singlethon { //构造方法私有化 singlethon() {} private static singlethon single=new singlethon(); //对外提供调用 public static singlethon getinstance() { return single; } }
懒汉式单例
类加载的时候不创建对象,只有在使用的时候才创建,但是在多线程条件下,是线程不安全的。
package single; import javax.sql.rowset.spi.SyncFactory; public class single2 { private single2() {} private static single2 single=null; //同步锁,一个线程执行时,其他线程处于等待 synchronized public static single2 getinstance() { if(single==null) { //线程不安全 try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } single=new single2(); } return single; } } //多线程,CPU 交替执行有先后
可以用同步锁解决线程不安全问题,但是加锁会降低效率;为提高效率,减小代码同步范围。但是用了双重检索,也不一定是线程安全的,因为还有系统指令重拍,此时可以将对象用volatile修饰。
package single; import javax.sql.rowset.spi.SyncFactory; public class single2 { private single2() {} private static single2 single=null; //同步锁,一个线程执行时,其他线程处于等待 public static single2 getinstance() { //双重检索 if(single==null) { //线程不安全 synchronized(single2.class) { if(single==null) { single=new single2(); } } } return single; } } //多线程,CPU 交替执行有先后
静态内部类
package single; public class single3 { private single3() {} //外部类被加载,内部类没有被加载,除非主动使用 private static class insideclass { private static single3 single=new single3(); } public static single3 getinstance() { return insideclass.single; } }
来源:https://www.cnblogs.com/NeverGiveUp0/p/11113029.html