zoukankan      html  css  js  c++  java
  • AS3设计模式-单例模式

    定义:在面向对象的编程中,要求一个类有且仅存在一个实例,提供一个全局的访问方法,避开构造函数,提供一种机制来实现单一实例。

    作用:比如说我在很多类都需要去引用某个类的属性 为了不在每个类里面都实例化这个要引用的类 ,那么把这个要引用的类做成单例模式  那么调用的时候就可以避免这个问题。

    在ActionScript 3.0里使用单例模式(Singleton Pattern),原来也可以如此的多姿多彩!看了《Advanced ActionScript 3 with Design Patterns》一书后,才发觉以前我所写的单例模式并不是真正的单例模式,或者说是不完美的单例模式(至少在ActionScript 3.0里不应该那样写)。所谓单例,就是在整个应用程序中有且只有一个类的实例,也就是说某个类只能被 new 一次。

    为了得到一个类的实例,你会使用 new 关键字,然后加上类名。这样会调用类的构造函数然后返回一个实例,就像这样:

    var myObject:MyClass = new MyClass();

    相信你已经对这种实例化类的方式已经非常熟悉,但这种方法无法控制类的构造,所以我们准备使用一个静态方法:getInstance()。因为它被声明为 静态(static),所以它是属于类而不是类的实例,不通过类的实例来调用它而直接使用类名来调用它。就像这样:

    public class MyClass {
            public function MyClass() {}
            public static function getInstance():MyClass {
                    return new MyClass();
            }
    }

     要得到类的实例,我们就可以使用这个静态的 getInstance() 方法:

    var myObject:MyClass = MyClass.getInstance();
    

    防止类被实例化
    只要能通过 getInstance() 方法得到实例,那所有工作都已经是按计划进行了。但我们注意到,这样始终不能防止他人通过 new 关键字来创建另一个实例。在一些语言里,可以把构造函数声明为私有(只能包内构造),这样就可以解决这个问题。但在ActionScript 3.0里这是不被支持的。这样的话,我们只能放一个大大的“public”关键字来声明构造函数为公有的,然后写上注释告诉其他人:“这个类只能被实例化一次”。那是不是就没有其 它方法来防止一个类被实例化呢?一切皆有可能,方法当然是有的。我们可以利用面向对象的游戏规则来达到目的,不正当的语法是被禁止的。
    假 如一个函数的参数没有默认值,在没有传递参数的情况下去调用这个函数,编译器就会报错。这是ActionScript 3.0的一个新特性,这个特性同样适用于构造函数。ActionScript 3.0还有一个新特性,在一个类文件里可以不只写一个类。也就是说在一个 .as 文件里可以写多个类。与文件名相同的那个类叫主类,主类只能有一个,其它类可以是任意多个,而且其它类只对包内可见,不能被外部引用。就像这样:

    package {
     
        public class MyClass {
     
            public function MyClass(enforcer:SingletonEnforcer) {}
     
            public static function getInstance():MyClass {
                return new MyClass(new SingletonEnforcer());
            }
     
        }
     
    }
     
    class SingletonEnforcer {}
    

    现在你只能通过以下语句来创建类的实例,因为你不可能在外部通过 new 关键字来创建只对包内可见的 MyClass 类实例:

    var myInstance:MyClass = MyClass.getInstance();
    

    注意:事实上,您还可以把 null 作为参数传递给构造函数来 new 出一个 MyClass 类实例。每一种语言都不可能是完美的,但以上做法在ActionScript 3.0里已经能基本解决问题了。

            直到现在为止,你还不能创建单例,当你每次调用 getInstance() 方法时,都会创建一个新实例。下面我们将会了解到如何才能做到创建单例。

    实现单例与全局变量
            我们需要怎样做才能保证 MyClass 类只实例化一次?现在,这个 getInstance() 方法可以被无限次地调用,然后无限次地 new 出很多个 MyClass 类,这无异于使用一个普通的公有构造函数。而我们只需要一个 MyClass 类型的实例,要这样的话,我们应该需要一个全局变量来保存这个唯一的实例,然后每次调用 getInstance() 方法时返回这个实例而不是重新 new 一个出来。就像这样:

    package {
     
            public class MyClass {
     
                    private static var _instance:MyClass;
     
                    public function MyClass(enforcer:SingletonEnforcer) {}
     
                    public static function getInstance():MyClass {
                            // 只有静态的私有变量 _instance 为null时才new出一个MyClass,
                            // 当第二次调用这个静态的 getInstance() 方法时,因为 _instance 不为null,
                            // 所以不再new出第二个 MyClass,而是直接返回已存在的 _instance。
                            // 这样就保证了全世界只有一个 MyClass 类型的实例
                            if(MyClass._instance == null) {
                                    MyClass._instance = new MyClass(new SingletonEnforcer());
                            }
                            return MyClass._instance;
                    }
     
            }
    }
     
    class SingletonEnforcer {}
    

      

  • 相关阅读:
    【DFS】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem D. Divisibility Game
    【二分】【三分】【计算几何】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem L. Lines and Polygon
    【线段树】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem J. Jedi Training
    【贪心】【后缀自动机】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem E. Enter the Word
    【转载】随机生成k个范围为1-n的随机数,其中有多少个不同的随机数?
    【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem H. Path or Coloring
    【枚举】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem D. Cutting Potatoes
    【找规律】【递归】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem F. Doubling
    【贪心】Codeforces Round #436 (Div. 2) D. Make a Permutation!
    【计算几何】【圆反演】计蒜客17314 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 G. Finding the Radius for an Inserted Circle
  • 原文地址:https://www.cnblogs.com/chen-mo/p/4792435.html
Copyright © 2011-2022 走看看