• 单件模式的陷阱【案例分析】


    案例分析:设计了一个类,里面有属性和方法,类是按照单件模式的静态初始化模式设计的。但这样,在实际的应用中,多个用户调用的属性的值是一样的。为了验证这个问题,专门写了一个测试用例,用来考证,最后得出同样的结果。
    问题:静态初始化实现了全局只有一个对象实例,这些实例的属性值应该是一样的。这样,在多个用户同时访问这个对象,并且在这个类中的方法中调用了该属性,而这个属性的值对于每个用户来说是一样的,这样就会出现错误。
    得出的结论:
        静态初始化的类,创建的方法方便使用且互不影响;切忌:不要设置其它属性并应用于自身的方法
    Singleton
    模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点。全局只能得到一个对象实例,而静态初始化只在第一次加载的时候被初始化,初始化完成后,再多次调用,对象就不会在重新初始化,任然调用的是最初初始化的值。所以单件模式,能够保证全局只有一个对象的实例,而且全局调用的是一个实例。而我们通过new获得对象实例,是类重新初始化,变量和构造函数,所以变量的值总是最初初始化的值,new就可以得到多个互不影响的对象实例。不同的是,在第一初始化时,静态变量被初始化,而在随后的调用中,静态变量不会重新初始化,依然保留上一次的值,除非通过方法将其值改变。
    本人通过简单的实例得到了上述结论。具体类的设计如下:
    using System;
    using System.Data;
    using System.Collections;

    /// <summary>
    /// Summary description for TestString
    /// </summary>

    public class TestString
    {
        
    /// <summary>
        
    /// 个人实例
        
    /// </summary>

        public static readonly TestString self = new TestString();
        
    /// <summary>
        
    ///定义一个List变量 
        
    /// </summary>

        public ArrayList UserList = new ArrayList();
        
    /// <summary>
        
    /// 初始化
        
    /// </summary>

        public TestString()
        
    {
            
    //
            
    // TODO: Add constructor logic here
            
    //
        }

        
    /// <summary>
        
    /// 得到个人实例
        
    /// </summary>
        
    /// <returns></returns>

        public static TestString getInstance()
        
    {
            
    return self;
        }

        
    /// <summary>
        
    /// 用户列表
        
    /// </summary>
        
    /// <param name="user"></param>

        public void addNew(string user)
        
    {
            UserList.Add(user);
        }

        
    /// <summary>
        
    /// 得到string
        
    /// </summary>
        
    /// <returns></returns>

        public string getString()
        
    {
            
    string str = string.Empty;
            
    for (int i = 0; i < UserList.Count; i++)
            
    {
                str 
    += UserList[i].ToString() ;
            }

            
    return str;
        }

        
    /// <summary>
        
    /// 得到用户名
        
    /// </summary>
        
    /// <param name="userName"></param>
        
    /// <returns></returns>

        public string getUserName(string userName)
        
    {
            
    return userName;
        }

    }

    测试页面,用了一个页面还有几个按钮:
    具体如下:
    测试用例

    这代码可以直接copy运行,如果你对单件模式中的静态初始化还是不了解的话,最后自己试试。这段代码,我经过了发布测试,在网络上,不同的客户端对Arraylist设置值,不同用户都可以设置ArrayList的值,但是通过getInstance()得到的ArrayList的值是一样的。这个测试用例,如果想测试,最后发布,在不同的客户端,同时访问,就会得出结论。
  • 相关阅读:
    MiniGUI
    Android-在XML和Java代码中设置背景在不同状态的效果: <selector>/StateListDrawable
    URLEncoder.encode、URLDecoder.decode、escape、encodeURI、encodeURIComponent
    getDimension,getDimensionPixelOffset和getDimensionPixelSize的一点说明
    Android获取屏幕分辨率及DisplayMetrics简介
    细说Android事件传递机制(dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent)
    Android
    Android坐标
    Android Sqlite IN, NOT IN syntax --- not int (?)
    TextView with SingleLine as true and Gravity as Center not passing the events to the ViewPager if it has a Click Event
  • 原文地址:https://www.cnblogs.com/yank/p/1102435.html
Copyright © 2020-2023  润新知