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 {}
    

      

  • 相关阅读:
    开源 Serverless 里程碑:Knative 1.0 来了
    以一致的体验交付和管理云原生多集群应用
    iLogtail使用入门K8S环境日志采集到SLS
    如何在golang代码里面解析容器镜像
    mac vmware 无法复制粘贴
    使用vi编辑时上下左右方向键被转化为A、B、C、D
    left join 和 left outer join 的区别
    设计模式之 适配器模式
    设计模式之 命令模式
    设计模式学习之 策略模式
  • 原文地址:https://www.cnblogs.com/chen-mo/p/4792435.html
Copyright © 2011-2022 走看看