当前位置: 首页 > wzjs >正文

企业官方网站建设费用智能建站平台

企业官方网站建设费用,智能建站平台,广州直销软件定制开发,留学网站建设开发方案文章目录 为什么需要单件模式单件模式典型实现剖析定义单件模式本节用例多线程带来的问题解决问题优化 Q&A总结 《Head First设计模式》读书笔记 相关代码: Vks-Feng/HeadFirstDesignPatternNotes: Head First设计模式读书笔记及相关代码 用来创建独一无二的&a…

文章目录

    • 为什么需要单件模式
    • 单件模式典型实现剖析
    • 定义单件模式
    • 本节用例
    • 多线程带来的问题
      • 解决问题
      • 优化
    • Q&A
    • 总结

《Head First设计模式》读书笔记
相关代码: Vks-Feng/HeadFirstDesignPatternNotes: Head First设计模式读书笔记及相关代码

  • 用来创建独一无二的,只能有一个实例的对象的入场券

为什么需要单件模式

有些对象只能有一个实例

  • 线程池、缓存、对话框、设备的驱动程序的对象、注册表设置对象
    如果制造出多个实例,就会导致许多问题产生
  • 程序的行为异常、资源使用过量、结果不一致

为什么不去靠人为约定或全局变量实现该目标?

  • 人为约定:人为约定不一定能绝对严格地被遵守,且若存在更好方法,自然更愿意接受
  • 全局变量:必须在程序开始前就创建对象并将其赋值给一个全局变量,若某次执行时没用到则是资源的浪费。(不能实现“懒加载”)

单件模式典型实现剖析

public class Singleton {  private static Singleton uniqueInstance;  private Singleton() { }  public static Singleton getInstance() {  if (uniqueInstance == null) {  uniqueInstance = new Singleton();  }  return uniqueInstance;  }  
}

为什么会被这样设计?

  • 创建对象仅需简单的new,为了避免被多次创建,将类的构造器私有化。
    • 但是私有化后只有类内的代码才能实例化该类,而类不被实例化如何调用其构造器呢?(“鸡生蛋,蛋生鸡”)
  • 通过在类中设计一个静态方法,解决不实例化该类,而能调用其构造器。

延迟实例化(Lazy instantiate)

if (uniqueInstance == null) {  uniqueInstance = new Singleton();  
}  
return uniqueInstance;

当我们需要该实例时再去创建对象,如果不需要就永远不会产生。

定义单件模式

#HeadFirst设计模式6-单件模式

单件模式确保一个类只有一个实例,并提供一个全局访问点。

单件模式类图

  • 把类设计成自己管理的一个单独实例,同时也避免其他类再自行产生实例
  • 通过单间类事获取单件实例的唯一途径
  • 提供这个实例的全局访问点:当你需要实例时,响雷查询,它会返回单个实例
  • 延迟实例化的方式创建单件对资源敏感的对象特别重要

本节用例

某公司设计的巧克力锅炉控制器
需要避免糟糕的情况发生:排除未煮沸的原料、已满情况下继续加原料、未放原料就空烧

public class ChocolateBoiler {  private boolean empty;  private boolean boiled;  public ChocolateBoiler() {  empty = true;  boiled = false;  }  public void fill() {  if (isEmpty()) {  empty = false;  boiled = false;  // 填充原料  }  }    public void drain() {  if (isEmpty() && isBoiled()) {  empty = true;  }  }    public void boil() {  if (!isEmpty() && !isBoiled()) {  boiled = true;  }  }  private boolean isBoiled() {  return boiled;  }  private boolean isEmpty() {  return empty;  }  
}

为了避免同时存在多个实例带来问题,对其进行单件化改造

public class ChocolateBoiler {  private static ChocolateBoiler uniqueInstance;  private boolean empty;  private boolean boiled;  public static ChocolateBoiler getInstance() {if (uniqueInstance == null) {uniqueInstance = new ChocolateBoiler();}return uniqueInstance;}private ChocolateBoiler() {  empty = true;  boiled = false;  }  
}

多线程带来的问题

当有多个熔炉实例时,可能会发生我们先前想避免的问题,但上面已有的单例模式可能会在多线程情况下创建出不只一个实例。

解决问题

只要把getInstance()变成同步(synchronized)方法,多线程灾难几乎就可以轻易地解决了

public class Singleton {  private static Singleton uniqueInstance;  private Singleton() { }  public static synchronized Singleton getInstance() {  if (uniqueInstance == null) {  uniqueInstance = new Singleton();  }  return uniqueInstance;  }  
}

问题:同步会降低性能,且当实例被正确初始化后,后续就不用再同步了,同步将会彻底成为累赘

优化

  1. getInstance()的性能对应用程序不是很关键,就什么都别做
    • getInstance()被频繁使用时,就需要考虑优化了
  2. 使用“急切”创建实例,而不用延迟实例化的做法
    • 频繁使用getInstance()时可用
    • 创建和运行时负担不繁重时可用
    public class Singleton {  private static Singleton uniqueInstance = new Singleton();  private Singleton() { }  public static synchronized Singleton getInstance() {  return uniqueInstance;  }  
    }
    
  3. “双重检查枷锁”,在getInstance()中减少使用同步
    • 首先检查是否实例已经创建了,如果尚未创建才会同步,这样就可以实现“只有第一次同步”了
    private volatile static Singleton uniqueInstance;  private Singleton() { }  public static Singleton getInstance() {  if (uniqueInstance == null) {  synchronized (Singleton.class) {  if (uniqueInstance == null) {  uniqueInstance = new Singleton();  }  }    }    return uniqueInstance;  
    }
    
    • volatile关键字确保当uniqueInstance变量被初始化成Singleton实例时,多个线程正确地处理uniqueInstance变量

Q&A

Q:为何不创建一个类,将其所有方法和变量都定义为静态的,直接把类当作一个单件?
A:

  • 如果类自给自足,而且不依赖于复杂的初始化,可以这么做。
  • 但是因为静态初始化的控制权是在Java手上,这么做有可能导致混乱,特别是有许多类牵涉其中时。这么做容易造成一些不易发现的和初始化次序有关的bug。
  • 建议使用对象的单件,比较保险。

Q:类加载器(class loader),听说两个类加载器可能有机会创建自己的单件实例
A:是的

  • 每个类加载器都定义了一个命名空间,如果有两个以上的类加载器,不同的加载器可能会加载同一个类,从整个程序来看,同一个类会被加载多次。
  • 如果这种情况发生在单件上,就会产生多个单件并存的怪异现象。
  • 当程序有多个类加载器而你又使用了单件模式时,需要注意。解决方案:自行指定类加载器,并指定同一个类加载器

Q:可不可以继承单件类?
A:继承单间类面临的问题:构造器是私有的。不能用私有构造器来扩展类。所以你必须把单件的构造器改成公开的或受保护的,而这样:

  • 就算不上“真正的”单件了,因为别的类也可实例化它
  • 单件的实现是利用静态变量,直接继承会导致所有的派生类共享同一个实例变量,可能并非预期效果,需要实现注册表(Registry)功能

Q:为什么全局变量比单件模式差?
A:

  • Java中,全局变量基本上就是对对象的静态引用。这种情况下使用全局变量就会有缺点,例如前文提到的急切实例化v.s.延迟实例化。
  • 但要记住该模式的目的“确保只有一个实例并提供全局访问。全局变量可以提供全局访问,但不能确保只有一个实例。全局变量也会变相鼓励开发者用许多全局变量指向许多小对象来造成命名空间的污染。

总结

OO基础

  • 抽象
  • 封装
  • 多态
  • 继承

OO原则

  • 封装变化
  • 多用组合,少用继承
  • 针对接口编程,不针对实现编程
  • 为交互对象之间的松耦合设计而努力
  • 对扩展开放,对修改关闭
  • 依赖抽象,不要依赖具体类

OO模式

  • 单件模式——确保一个类只有一个实例,并提供全局访问。

要点

  • 单件模式确保程序中的类最多只有一个实例
  • 单件模式也提供访问这个实例的全局点
  • Java中实现单件模式需要私有的构造器、一个静态方法和一个静态变量
  • 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单件,以解决多线程的问题
  • 如果使用多个类加载器,可能导致单件失效而产生多个实例
http://www.dtcms.com/wzjs/331165.html

相关文章:

  • 网站建设设计文档模板下载短视频培训课程
  • 可以做动漫的网站有哪些网络运营工作内容
  • pc端和移动端的网站区别是什么中国优秀网页设计案例
  • 青岛网站建设-中国互联河北seo诊断培训
  • thinkphp做网站好吗推广平台有哪些?
  • dede跳转到其他网站广告买卖网
  • 做海报的网站类似于创客贴企业网站怎么做
  • wordpress数据库用户导出seo网络推广公司排名
  • 网站怎么做用什么软件常州百度关键词优化
  • wordpress可以建哪些网站吗百度渠道开户哪里找
  • jsp网站如何做seo1688seo优化是什么
  • 专业做英文网站百度推广非企代理
  • 武汉建筑工程百度seo技术
  • 厦门网站建设哪家好推广app平台
  • 下载别人做的ppt的网站百度小程序对网站seo
  • 建设旅行网站策划书站长平台
  • 哈尔滨论坛建站模板最全资源搜索引擎
  • 政府网站模板 下载在哪里打广告效果最好
  • excel做网站链接郑州官网关键词优化公司
  • 网站怎么做盈利seo可以从哪些方面优化
  • 专做母婴的网站seo外链建设的方法
  • 公司网站建设计入什么科目长春网络优化哪个公司在做
  • 新类型网站如何进行关键词优化工作
  • 建行官方网站登录最新域名查询ip
  • 做中英文网站网站免费建站app
  • 郴州网站建设公司哪家好太原百度seo
  • 外贸网站建设 佛山百度seo排名优化公司哪家好
  • 温州开发区管委会建设网站新媒体运营培训课程
  • 企业不做网站关键词看片
  • 如何推广企业官方网站内容百度搜索量