在王者荣耀角度下分析面向对象程序设计B中23种设计模式之单件模式

·

单件模式在王者荣耀中的应用

·

一、简述

今年春节王者荣耀出了一个叫做“王者快跑”的限时玩法,许多玩家都很喜欢这个游戏模式。不同于5V5的王者地图,这个地图是一个跑道中途有很多的障碍物,还有NPC玩家释放控制技能做阻拦,简单益智,只要一直跑就可以了,最终按照所有玩家到达终点的时间前后顺序获得名次。

☞在本实例中,设计了一个Champion冠军单件类,以及马超、韩信、猪八戒、李白、李元芳等五个线程,每个线程从左至右移动一个属于自己的按钮(表示玩家操纵各自英雄在全程中的位置),最先移动到终点的按钮即为冠军。
☞按照这一思路,最先到达终点的线程将负责创建出Champion单件类的唯一实例(冠军),其他将自己的按钮移动到指定位置的其他四个线程都可以看到冠军的有关信息及看到Champion单间类的唯一实例的有关属性值。

二、单件模式(Singleton Pattern)

单件模式理解:
高度概括:保证一个类有一个实例,并提供一个访问他的全局访问点。
在某些情况下,我们可能需要某个类只能创建出一个对象,即不让用户用该类实例化出多余两个的实例。
单件模式是关于怎样设计一个类,并使该类只有一个实例的成熟模式,该模式的关键是将类的构造方法设置为private权限,并提供一个返回他的唯一实例的类的方法(static方法)。

单件模式结构中的角色:
单件模式的结构非常简单,只包括一种角色,单件类,单件类只可以创建出一个实例。

单件模式的UML类图:

在王者荣耀角度下分析面向对象程序设计B中23种设计模式之单件模式_第1张图片

单件模式的设计特点:
①单件类中包含用自身声明的类变量,这个类变量是单件类唯一的实例;
②单件类的构造方法,访问权限是private,为了确保单件类种自身声明的类变量,是单件类,唯一的实例单件类必须将构造方法,访问权限设置成private,这样一来,任何其他类都无法使用单件类来创建对象;
③单件类负责创建自己唯一的实例,并提供访问该实例的类的方法,由于单件类的构造方法被设置为private,所以单件类必须自己负责,创建自身声明的实力,为了让用户使用单件类这一唯一实例,单件类必须提供一个类方法,以便其他用户使用单件类的类名就可以调用这个类方法访问使用单件类这一唯一实例。

单件模式的优缺点:
优点:

①单件类的唯一实例由单件类本身控制,所以可以很好的控制用户何时访问他(灵活性);
②实例控制,单例模式会阻止其他对象实例化气自己的单例对象的副本,从而确保所有对象都访问唯一实例。
缺点:
①每次对象请求引用时都要检查是否存在类的实例,将需要一些开销,不过可以通过静态初始化解决此问题。
②可能的开发混淆,使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不可能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。

单件模式的适用情景:
当系统需要某一类只能有一个实例

三、王者荣耀角度下实现单件模式结构图及代码

eclipse结构图

在王者荣耀角度下分析面向对象程序设计B中23种设计模式之单件模式_第2张图片

主函数【应用(Application)】
Applicayion.java

package angle_singletonPattern;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Application extends JFrame implements ActionListener{
       JButton  start;
       Player playerOne,playerTwo,playerThree,playerFore,playerFive;
       JButton  one,two,three,fore,five;
       JTextField showLabel;
       int width=60;
       int height=28;
       int MaxDistance=460;
       public Application(){
           setLayout(null);
           start=new JButton("开始比赛");
           start.addActionListener(this);
           add(start);
           start.setBounds(200,30,90,20);
           showLabel=new JTextField("为所有选手加油!");
           showLabel.setEditable(false);
           add(showLabel);
           showLabel.setBounds(50,30,140,20);
           showLabel.setBackground(Color.orange);
           showLabel.setFont(new Font("隶书",Font.BOLD,16));
           showLabel=new JTextField("第一名是谁让我们拭目以待!");
           showLabel.setEditable(false);
           add(showLabel);
           showLabel.setBounds(300,30,230,20);
           showLabel.setBackground(Color.orange);
           showLabel.setFont(new Font("隶书",Font.BOLD,16));
           one=new JButton("马超"); 
           one.setSize(73,30);
           one.setBackground(Color.yellow); 
           playerOne=new Player(18,2,MaxDistance,one,width,height,showLabel);
           two=new JButton("韩信"); 
           two.setSize(73,30); 
           two.setBackground(Color.cyan);
           playerTwo=new Player(18,2,MaxDistance,two,width,height,showLabel);
           three=new JButton("猪八戒");
           three.setSize(73,30);
           three.setBackground(Color.green); 
           playerThree=new Player(18,2,MaxDistance,three,width,height,showLabel);
           fore=new JButton("李白"); 
           fore.setSize(73,30); 
           fore.setBackground(Color.white);
           playerFore=new Player(18,2,MaxDistance,two,width,height,showLabel);
           five=new JButton("李元芳"); 
           five.setSize(73,30); 
           five.setBackground(Color.pink);
           playerFive=new Player(18,2,MaxDistance,two,width,height,showLabel);
           initPosition();
           setBounds(100,100,600,300);
           setVisible(true);
           setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    }
    private void  initPosition(){
            Champion.initChampion();
            showLabel.setText("为所有选手加油!");
            showLabel.setText("第一名是谁让我们拭目以待!");
            repaint();
            remove(one);
            remove(two);
            remove(three) ;
            remove(fore);
            remove(five) ;
            add(one);
            add(two);
            add(three);
            add(fore);
            add(five);
            one.setLocation(1,60);
            two.setLocation(1,60+height+2);
            three.setLocation(1,60+2*height+4);
            fore.setLocation(1,60+3*height+2);
            five.setLocation(1,60+4*height+3);
    }
    public void actionPerformed(ActionEvent e){
          boolean boo=playerOne.isAlive()||playerTwo.isAlive()||playerThree.isAlive()||playerFore.isAlive()||playerFive.isAlive();
          if(boo==false){
                 initPosition();
                 int m=(int)(Math.random()*2)+19;
                 playerOne=new Player(m,2,MaxDistance,one,width,height,showLabel);
                 m=(int)(Math.random()*3)+18;
                 playerTwo=new Player(m,2,MaxDistance,two,width,height,showLabel);
                 m=(int)(Math.random()*4)+17;
                 playerThree=new Player(m,2,MaxDistance,three,width,height,showLabel);
                 m=(int)(Math.random()*5)+16;
                 playerFore=new Player(m,2,MaxDistance,fore,width,height,showLabel);
                 m=(int)(Math.random()*6)+15;
                 playerFive=new Player(m,2,MaxDistance,five,width,height,showLabel);
          }
          try{
                  playerOne.start();
                  playerTwo.start();
                  playerThree.start();
                  playerFore.start();
                  playerFive.start();
          }
          catch(Exception exp){}
    }
    public void paint(Graphics g){
           super.paint(g);
           g.drawLine(MaxDistance,0,MaxDistance,MaxDistance);
    }
    public static void main(String args[]){
           new Application();
    }
}

Player.java

package angle_singletonPattern;

import angle_singletonPattern.Champion;

import javax.swing.JButton;
import javax.swing.JTextField;
public class Player extends Thread{
      int MaxDistance;
      int stopTime,step;
      JButton com;
      JTextField showMess;
      Champion champion;
       Player(int stopTime,int step,int MaxDistance,JButton com,int w,int h,JTextField showMess){
            this.stopTime=stopTime;
            this.step=step;
            this.MaxDistance=MaxDistance;
            this.com=com;
            this.showMess=showMess;
     }
     public void run(){
            while(true){
                int a=com.getBounds().x;
                int b=com.getBounds().y;
                if(a+com.getBounds().width>=MaxDistance){
                     champion=Champion.getChampion(com.getText());
                     showMess.setText(champion.getMess());
                     return;
                }
                a=a+step;
                com.setLocation(a,b);
               try{
                        sleep(stopTime);
               }
               catch(InterruptedException exp){}
           }
      }
}

单件类
Champion.java

package angle_singletonPattern;

import angle_singletonPattern.Champion;

public class Champion  {
    private  static Champion  uniqueChampion;
    String  message;
    private Champion(String message){
         uniqueChampion=this;
         this. message=message;
   }     
    public static synchronized Champion getChampion(String message){   //这是一个同步方法
          if(uniqueChampion==null){
                uniqueChampion=new Champion("恭喜"+message+"获得第一名");
          }
          return uniqueChampion;
    }
    public static void initChampion(){
         uniqueChampion=null;
    }
    public String getMess(){
          return message;
    }
}

运行结果截图

在王者荣耀角度下分析面向对象程序设计B中23种设计模式之单件模式_第3张图片

更多设计模式在王者荣耀中的应用请点击我的→设计模式在王者荣耀中的应用专栏。

欢迎留言,一起学习交流~

感谢阅读

END

你可能感兴趣的:(java)