【单件模式】只有一个角色的模式

       单件模式是关于怎样设计一个类,并使得该类只有一个实例的成熟模式,该模式的关键是将类的构造方法设置为private权限,并提供一个返回它的唯一实例的类方法。

       在某些情况下,我们可能需要某个类只能创建出一个对象,即不让用户用该类实例化出多于两个的实例。

      例如:在一个公文管理系统中,公文类的实例“公文文件”,需要将公章类的实例作为自己的一个成员,且公章类只有一个实例。

      优点:单件类的唯一实例由单件类本身来控制,所以可以很好地控制用户何时访问它。

角色:

      单件类(Singleton):单件类只可以创建出一个实例

      单件类(Singleton)的UML图

单件类在设计上的特点:

      单件类中包含用自身声明的类变量,这个类变量是单件类唯一的实例。
      单件类的构造方法访问权限是private。为了确保单件类中自身声明的类变量是单件类唯一的实例,单件类必须将构造方法的访问权限设置为private。其他类无法使用单件类创建对象。
      单件类负责创建自己唯一的实例,并提供访问该实例的类方法,以便其他用户使用单件类的类名就可以调用这个类方法访问使用单件类这个唯一实例 。

设计单件类的两种方法:

1.在JVM加载单件类时创建它的唯一实例

    对于单件类中声明的类变量,即该单件类的唯一实例,在单件类被JVM加载到内存时就会被分配空间,该内存空间用于存放该实例的引用,因此,可以在声明类变量的同时就初始化它,即创建该实例。

public class Singleton{
  private static Singleton uniqueInstance=new Singleton();
  //JVM 加载Singleton时创建uniqueInstance
  private Singleton(){ }  //构造方法是private权限
  public  static Singleton getInstance(){  //返回唯一实例的类方法
       return  uniqueInstance;
  }
}

2.在单件类提供的类方法中创建这个唯一实例

    如果程序希望用户需要时再创建单件类的唯一实例,即用户调用单件类提供的类方法时再创建它,那么为了防止多线程在调用这个类方法时创建多个单件类的实例,可以将类方法设置为同步方法。

public  class  Singleton{
  private  static  Singleton  uniqueInstance; 
  private  Singleton( ) {   }  //构造方法是private权限
  public static synchronized  Singleton  getInstance( ) {
    if (uniqueInstance==null){
           uniqueInstance=new Singleton( );
    } 
    return  uniqueInstance;
  }
}

实例:

创建唯一的月亮。单件模式的类图是所有模式中最简练的,只涉及一个角色:单件类。

该实例的UML图:

Moon.java

在JVM加载单类时创建的Moon.Java

public class Moon{
      private static Moon uniqueMoon=new Moon();
      double radius=1738;
      double distanceToEarth=363300;
      private Moon(){}  
      public static synchronized Moon getMoon(){   
      return   uniqueMoon; 
        }
      public String show(){
           String s="月亮的半径是"+radius+"km,距地球是"+distanceToEarth+"km";
           return s;
     }
}

在单间类提供的类方法中创建的Moon.Java

public class Moon{
      private static Moon  uniqueMoon;
      double radius;
      double distanceToEarth;
      private Moon(){
           uniqueMoon=this;
           radius=1738;
           distanceToEarth=363300;
      }     
      public static synchronized Moon getMoon(){   
            if(uniqueMoon==null){
                  uniqueMoon=new Moon();
            }
            return uniqueMoon;
      }
      public String show(){
           String s="月亮的半径是"+radius+"km,距地球是"+distanceToEarth+"km";
           return s;
      }
}

应用程序

import javax.swing.*;
import java.awt.*;
public class Application{
    public static void main(String args[]){
          MyFrame f1=new MyFrame("张三看月亮");
          MyFrame f2=new MyFrame( "李四看月亮");
          f1.setBounds(100,100,760,550);
          f2.setBounds(370,100,760,550);
          f1.validate();
          f2.validate();
          }
    }
class  MyFrame extends JFrame{
    String str;
    MyFrame(String title){
        setTitle(title);
        Moon moon=Moon.getMoon();  
        str=moon.show();
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setVisible(true);
        repaint();
       } 
    public void paint(Graphics g){  
          super.paint(g);
          g.setFont(new Font("黑体",Font.BOLD,34));
          g.drawString(str,5,100);}
}

运行结果:

单件类的唯一实例由单件类本身来控制,所以可以很好地控制用户何时访问它。 

这里是不吃香菜也可做香菜头子。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值