创建型
单例模式
单例对象能节约系统资源,一个对象的创建和消亡的开销可能很小。但是日常的服务接口,就算是一般小公司也有十几万的QPS吧。每一次的功能运转都创建新的对象来响应请求,十几万对象的创建和销毁,想想就是一笔大开销,所以 spring 管理构造的 bean 对象一般都是单例。而且单例模式可以更好的解决并发的问题,方便实现数据的同步性
- 优点
- 在内存中只有一个对象,节省内存空间
- 避免频繁的创建销毁对象,可以提高性能
- 避免对共享资源的多重占用,简化访问
- 为整个系统提供一个全局访问点
- 缺点
- 不适用于变化频繁的对象
//饿汉式 private static Singleton singleton = new Singleton();
//懒汉式 private static Singleton singleton; public static Singleton getSingleton(){ if (singleton == null) { singleton = new Singleton(); //被动创建,在真正需要使用时才去创建 } return singleton; }
//双重判断加锁机制 private volatile static Singleton instance; //程序运行时创建一个静态只读的进程辅助对象 public static Singleton GetInstance() { //先判断是否存在,不存在再加锁处理 if (instance == null){ synchronized (Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; }
//静态初始化 private static readonly Singleton instance= new Singleton(); public static Singleton GetInstance(){ return instance; }
工厂模式
使用者不关心对象的实例化过程,只关心对象的获取。工厂模式使得产品的实例化过程和消费者解耦
- 优点
- 一个调用者想创建一个对象,只需通过其名称或其他唯一键值在工厂获取
- 扩展性高,如果想增加生产一种类型对象,只要扩展工厂类就可以
- 缺点
- 工厂类不太理想,因为每增加一产品,都要在工厂类中增加相应的生产判断逻辑,这是违背开闭原则的
public interface Sender{ public void send(); } public class MailSender implements Sender { @Override public void send() { System.out.println("this is mailsender!"); } } public class SmsSender implements Sender { @Override public void send() { System.out.println("this is sms sender!"); } } public class SendFactory { public Sender produce(String type) { if ("mail".equals(type)) { return new MailSender(); } else if ("sms".equals(type)) { return new SmsSender(); } else { return null; } } //若还有其他产品 则在工厂里加对应的 produce 方法 }
建造者模式
主要解决在软件系统中一个复杂对象的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定
- 优点
- 扩展性好,对象每一个属性的构建相互独立,有利于解耦。
- 建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险
- 缺点
- 如果对象建造者发生变化,则建造者也要同步修改,后期维护成本较大
- 一种建造者对应一种类型建造,一个建造者基本很难建造多种类型对象
@Data class Product { private String name; private String price; // Product 的建造者 Builder public static class Builder{ public static Builder builder(){ Builder builder = Builder(); } private Product product = new Product(); public Builder name(String name){ product.name = name; return this;} public Builder price(String