由MVC引发的对单例模式思考

1.三层架构与MVC模式的区别

三层架构简介

三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。

架构流程图

MVC简介

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

架构流程图

###2. 单例模式有哪些分类

  • 饿汉式单例模式

    饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了。

     1 //饿汉式单例
     2 public class Hungry{
     3   //可能会浪费空间
     4   private byte[] data1 = new byte[1024*1024];
     5   private byte[] data2 = new byte[1024*1024];
     6   private byte[] data3 = new byte[1024*1024];
     7   private byte[] data4 = new byte[1024*1024];
     8   private Hungry(){
     9
    10   }
    11     private final static Hungry HUNGRY =new Hungry();
    12
    13     public static Hungry getInstance(){
    14         return HUNGRY;
    15     }
    16 }
    懒汉式单列模式
  • 懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。

     1 public class LazyMan{
     2     private LazyMan(){
     3
     4     }
     5     private static LazyMan lazyMan;
     6
     7     //懒汉式单例
     8     public static LazyMan getInstance(){
     9         if(lazyMan==null){
    10             lazyMan =new LazyMan();
    11         }
    12         return lazyMan;
    13     }
    14      /*
    15      * 懒汉式的升级版常用于生产环境
    16      */
    17 }
    18 静态内部类
    19
    20 public class Holder{
    21     /*
    22     * 静态内部类绝对安全,无法被反射破解
    23     *
    24     */
    25     private Holder(){
    26     }
    27     public static Holder getInstance(){
    28         return InnerClass.HOLDER;
    29     }
    30     public static class InnerClass{
    31         private static final Holder HOLDER =new Holder()
    32     }
    33 }

3.单例模式是否真的安全

单例模式不安全,可以通过反射来破解

饿汉式和懒汉式单例的区别

1.线程安全

饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,

懒汉式本身是非线程安全的,为了实现线程安全有几种写法。

例如:

 1 import com.sun.corba.se.impl.orbutil.CorbaResourceUtil;
 2 import java.lang.reflect.Constructor;
 3 import java.lang.reflect.Field;
 4 //懒汉式升级单例
 5 public class LazyManPlus{
 6
 7     private LazyManPlus(){
 8         synchronized (LazyMan.class){
 9             if (LMJ == false){
10                 LMJ = true;
11             }else {
12                 throw new RuntimeException("不要试图使用反射破坏异常");
13             }
14     }
15     }
16     //volatile  保证可见性,保证原子有序性,避免指令重排,不保证原子性
17     private  volatile  static LazyManPlus lazyManPlus;
18     private static LazyManPlus getInstance(){
19    if (lazyMan==null){
20        synchronized (LazyMan.class){
21            if (lazyMan==null){
22            lazyMan = new LazyMan(); // 不是一个原子性操作 } }
23             }
24        }
25         return lazyManPlus;
26     }
27     //反射!
28     public static void main(String[] args){
29
30         Field LMJ = LazyManPlus.class.getDeclaredField("LMJ");//自定义一个名字,监测
31         LMJ.setAccessible(true);//将私有类打开,破解成功
32         Constructor<LazyMan> declaredConstructor =                                            LazyMan.class.getDeclaredConstructor(null);                                         declaredConstructor.setAccessible(true);
33         LazyMan instance = declaredConstructor.newInstance();
34         LMJ.set(instance,false);
35         LazyMan instance2 = declaredConstructor.newInstance();
36         System.out.println(instance);
37         System.out.println(instance2);
38     }
39 }

2.资源加载和性能

饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成。

而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。

注:单例模式能够被反射破解,枚举类不能被破解

1 import java.lang.reflect.Constructor;
2 import java.lang.reflect.InvocationTargetException;
3 // enum 是一个什么? 本身也是一个Class类
4 public enum EnumSingle
5 {  INSTANCE;
6  public EnumSingle getInstance(){
7      return INSTANCE;
8  }
9 }

4.java中的反射

简单理解

Java编写的程序,一次编译,到处运行。这也是Java程序为什么是无关平台的所在,原因在于,java的源代码会被编译成.class文件字节码,只要装有Java虚拟机JVM的地方(Java提供了各种不同平台上的虚拟机制,第一步由Java IDE进行源代码编译,得到相应类的字节码.class文件,第二步,Java字节码由JVM执行解释给目标计算机,第三步,目标计算机将结果呈现给我们计算机用户;因此,Java并不是编译机制,而是解释机制),.class文件畅通无阻。主要操作.class文件

Java的反射机制,操作的就是这个.class文件,首先加载相应类的字节码(运行eclipse的时候,.class文件的字节码会加载到内存中),随后解剖(反射 reflect)出字节码中的构造函数、方法以及变量(字段),或者说是取出

5.三层架构是如何体现高内聚、低耦合的开发思想

1.封装每一层的接口,采用面向对象的接口封装思想

2.分层调用接口,每一层的接口互不联系,达到低耦合的思想

3.每个接口具有一个实现类,体现高内聚,即对高内聚

4.对外只开发一个接口

6.java中的泛型的作用

泛型定义的语法如下:

[访问修饰符] class 类名称 <T>

代码演示

 1 public class Base<T> {
 2   T m;
 3   Base(T t) {
 4     m = t;
 5   }
 6   public T getM(){
 7     return m;
 8   }
 9   public void print() {
10     System.out.println("base print : " + m);
11   }
12   public static void main(String[] args) {
13     Base<String> base=new Base<String>("base class is general");
14     System.out.println(base.getM());
15     base.print();
16   }
17 }

T可以用任何一种引用类型,但是不允许使用基本类型,如int、double、char、boolean等是不允许的。泛型类定义时,可以使用T来定义其成员变量和成员方法的返回值和参数。

泛型方法主要用于容器类,Java中任何方法,包括静态的(注意,泛型类不允许在静态环境中使用)和非静态的,均可以用泛型来定义,而且和所在类是否是泛型没有关系。

使用泛型方法时,至少返回值或参数有一个是泛型定义的,而且应该保持一致,否则可能会受到各种限制,因此,这里建议保持一致。

7.JQuery中的$.ajax语法

$.ajax({
   type: "POST",
   url: "some.php",
   data: "name=John&location=Boston",
   success: function(msg){
     alert( "Data Saved: " + msg );
   }
});

String serialize() 函数

序列表表格内容为字符串,用户Ajax请求。将JSON数据转化为String类型

例如:HTML代码

 1 <p id="results"><b>Results: </b> </p>
 2 <form>
 3   <select name="single">
 4     <option>Single</option>
 5     <option>Single2</option>
 6   </select>
 7   <select name="multiple" multiple="multiple">
 8     <option selected="selected">Multiple</option>
 9     <option>Multiple2</option>
10     <option selected="selected">Multiple3</option>
11   </select><br/>
12   <input type="checkbox" name="check" value="check1"/> check1
13   <input type="checkbox" name="check" value="check2" checked="checked"/> check2
14   <input type="radio" name="radio" value="radio1" checked="checked"/> radio1
15   <input type="radio" name="radio" value="radio2"/> radio2
16 </form>
//JQuery代码
$("#results").append( "<tt>" + $("form").serialize() + "</tt>" );
 

原文地址:https://www.cnblogs.com/blogger-Li/p/12424886.html

时间: 2024-11-02 06:25:26

由MVC引发的对单例模式思考的相关文章

网络公开课《八一建军节引发的Oracle数据库思考:虚拟私有数据库》

课程内容介绍: ■ Oracle Virtual Private Database(VPD)允许在行和列级别创建安全策略 ■ 它的本质是对应用了VPD安全策略的数据库表.视图.同义词上执行的SQL语句添加了动态的WHERE子句 ■ VPD可以在更细的粒度上强制实现安全策略,它直接作用于表.视图和同义词 ■ 当用户直接或间接地访问受VPD保护的表.视图和同义词时,Oracle会动态地修改用户的SQL语句 ■ 这种修改通过安全策略函数返回一个WHERE条件(即一个谓词),并应用到用户执行的SQL语句

拼多多“薅羊毛”事件引发测试工作的思考

前言 2017年我有幸负责公司DevOps治理和落地项目,在整个DevOps落地工作中,深感测试环节在持续交付工作中的弱态及重要.实践是检验真理的唯一标准,没有实践就没有发言权.为求深入理解,我亲身投入了测试岗位的一线工作.从测试用例的编写.宣讲.测试.复测.上线.回归等一些列实际工作,再到带领测试团队.提炼测试经验,推动测试变化的一系列行为,让我对测试工作有了深刻的认识.在测试岗位一年多的工作经验中,补全了我Devops治理工作中测试环节的内容,为我Devops的工作提供了丰富的经验.我也借这

关于iOS中MVC和MVVM的一些思考

事情从一般开发中一个massive viewController说起,一个巨大的vc一般少则上千行代码,多则上万行. 这中情况下对代码的维护有致命性的障碍,个人亲身体验. 当你试着从6000行的代码中去找到一个网络请求,找到相关的实现逻辑,这已经能够让你眼花缭乱的. 更进一步,如果你打算对某个逻辑,某个场景进行测试,那事情的困难程度非常大. 再者,如果你想重用某一部分的场景逻辑,那几乎不可能,因为所有的代码都耦合在一个vc中了. 为什么会造成一个vc的代码这么多,这么复杂呢? 一般有以下原因:

由企业邮箱培训引发的一些小思考

我公司之所以打造好邮网这么个平台,是缘于团队在企业邮箱这个行业的多年积累和沉淀,希望通过这些优势,能从比较中立的角度,帮助客户挑选最为合适的邮箱产品.因此整合了多个企业邮箱系统的优势品牌.这也让我们有幸参加到各企业邮箱品牌的一些内部培训中,各家培训会议的主题大多相同:产品讲解.常见问题分析.市场前景展望.在培训中,为了激发代理商的销售士气,突出自家产品才是最棒的,通常都会列举一些竞品没有的.或做得不好的功能或服务,让我们记住,以便更有利的游说客户,但对竞品实实在在的分析很少,而且都是比较过旧或片

理论篇 前端MVC、MVP、MVVM思考2

MVC设计模式从代码分离的角度来考虑软件的架构和组织,最初源于SmallTalk语言,后来在GoF中有了深入的讲解: SmallTalk时的MVC架构有如下特点: M 代表业务数据的来源: P Presentation展现由View和Controller同时维护,缺一不可:对于每一个Model都有相对应的VC对,因此VC没有真正的分离: C Controller处理用户的输入,并执行相应的业务逻辑: O Observer pattern观察者模式被使用到,因为每当Model变化时,需要通知对应的

MySQL-Front 建表引发的一点小思考(数据表格模版)

我们建表的时候,有一些字段总是会常用到的.也就是每一张表都会有这些字段. 我用mysql有一点时间了,今天(2016-02-27 21:53:38)在用mysql-front建表的时候,感觉有点点不太舒服. 就是某些表格中的字段,基本上每一张表都会用到.我的做法是 从 某张建好的表格上复制过来.每次都需要点开已经 新建好的数据表来复制,粘贴字段.感觉有点点不方便. 然后我在想,如果可以提供一种类似 Visual studio 那种建项目的项目模板就好了.于是,查阅了下资料,在 github 上找

你从前面右转的第二排架上就有啊——由”随便走“引发的用户体验思考

关于半岛铁盒的寻找,周董也是须要在"最后的一公里"问店里的小妹妹,才干真正找到那锈迹斑斑的半岛铁盒.而在O2O火爆的今天,谁才是我们身边那个能够咨询的前台小妹妹呢? 相信大家身边都有路痴,女友就是典型的一个.推荐过好用的地图导航app给她,即便功能多强大,对她来说,都一样:一张大地图上分不清上下左右东南西北.即便是地图中的定位点标明了当前的方向,她也不会去理会.仅仅会说:看不懂!这便是非常明显的用户思维.我仅仅是个用户,无论你功能多强大,还是一教就会使用,但是对不起,你带不给我新鲜,我

由数据库某字段存数组引发的json_encode/serialize思考

导火索场景: 原来:mysql中 result表 img字段原存储字符串,内容为某图片链接: 现在:该字段需要存储多张图片链接,1-3个元素行程的数组: google得到的普遍建议有两种:https://stackoverflow.com/questions/3413291/how-to-store-an-array-into-mysql 建议一:根据具体场景构建多张表,通过主键外键形成关联. 优点:支持针对数组中某个字段的查询等:缺点:需要结合具体场景 建议二:序列化数组,php提供内置方法支

Function.__proto__ === Function.prototype 引发了我胡乱的哲学思考

前两天我又试图顺着__proto__和prototype寻找JavaScript宇宙的本源,最后还是不出意料的疯了. 我没疯,经过无数次的测试,我偶然发现了这样一个令人奇怪的现象: 在chrome控制台中, Function.__proto__ === Function.prototype返回的是true,这就引发了我的思考. 思考了两三天,又刷了一遍MDN相关部分,有了新的收获. Function,从小往大说,应该是:构造函数--函数--对象. 1.Function是一个构造函数,通过new调