JAVA-(单例设计模式、数组、扑克demo)

2019-08-10  本文已影响0人  宁晓鸯

心得体会


技术

具体操作

1.单例设计模式

  • 1.单例类只能有一个实例。
  • 2.单例类必须自己创建自己的唯一实例。
  • 3.单例类必须给所有其他对象提供这一实例。
  • 1.私有的构造方法
  • 2.指向自己实例的私有静态引用
  • 3.以自己实例为返回值的静态的公有的方法
  • 一种是饿汉式单例,一种是懒汉式单例。
  • 饿汉式单例在单例类被加载时候,就实例化一个对象交给自己用;
    懒汉式在调用取得实例方法的时候才会实例化对象。

-----------饿汉式单例

 class Poker{
        //defalt,share,Instance,manager
        //2.定义一个静态的成员变量 记录这个单例对象
        //饿汉式
        public static final Poker shared = new Poker();

        //1.默认构造函数
        private Poker() { }

        public void test() {
        }
    }
  • 步骤:1.默认构造方法 ----2.定义一个静态的成员变量 记录这个单例对象

-----------懒汉式单例

class Player { 
        public int count;
        //2.创建静态变量
        private static Player shared = null;
       //1.私有化
        private Player() { }
        //3.提供给外部一个访问的方法
        public static Player getInstance() {
            Object b = new Object();
            synchronized (b) {
                if (shared == null) {
                    //如果没有创建 那么就创建一个
                    shared = new Player();
                }
            }
            return shared;
        }
    }

步骤:1.私有化构造函数------2.创建静态变量------ 3.提供给外部一个访问的方法
解析:懒汉式单例先将构造函数私有化,外部无法直接访问,要让外部访问到,就必须提供提供给外部一个访问的方法,给外部一个 getInstance()方法。
懒汉式的缺点是:没有考虑到线程安全,可能存在多个访问者同时访问,并同时构造了多个对象的问题。之所以叫做懒汉模式,主要是因为此种方法可以非常明显的lazy loading。


2.数组引用

class Test2{
    public static void main(String[] args){
        //泛型
        /** 数组里面保存的都是对象的引用(指针)
         * 改变数组里面对象的属性变量
         * 原始对象的值也跟着改变
         * 因为大家都是指向同一个内存空间
         */
        ArrayList<Person> people=new ArrayList<>();
        //添加数据
        Person xw=new Person();
        people.add(xw);
        Person zs=new Person();
        people.add(zs);
        //访问数据
        Person xw2=people.get(0);
        xw2.name="小王";
        System.out.println(xw2.name);
    }
}
class Person{
    public String name;
}
image.png

1.上图中用ArrayList<Person> people=new ArrayList<>();实现了动态分布数组内存空间

  1. Person xw=new Person();
    people.add(xw);
    Person zs=new Person();
    people.add(zs);
    这里分别创建了xw,zs两个对象,并通过add()把这两个对象加到数组里面去了

3.上图中System.out.println(xw2.name);打印了xw2,得到结果是小王,如果换成System.out.println(xw.name);,得到结果同样是小王
xw和xw2指向的是同一个内容,本来xw的打印结果应该是null的,但通过xw2将“小王”赋给了数组的第一个,于是xw指向的内容也就变成了“小王”,数组里面存的是地址


3.扑克demo

image.png

输出语句:完成如下指令

  • 1.输出语句不换行/换行
  • 2.输出语句加分隔符/不加分隔符
  • 3.输出语句一行/多行
package Demo;
import java.util.Scanner;

public class Utils {
    public static void showText(boolean hasStar,boolean lineBreak,String...contents){
        //判断是否需要显示分割线
        System.out.print(hasStar?"**********************\n":" ");
        //判断输出的内容是一行还是多行
        if(contents.length==1){
            System.out.print(contents[0]);
          System.out.print(hasStar?"\n":" ");
        }else{
            //输出带编号的多行数据
            for(int i=0;i<contents.length;i++){
                System.out.println((i+1)+". "+contents[i]);
            }
        }
        System.out.print(hasStar?"**********************\n":" ");
        System.out.print(lineBreak?"\n":" ");
    }
    public static int getInput(){
        Scanner scanner=new Scanner(System.in);
        return scanner.nextInt();
    }
}

1.如果不需要保存数据,没有成员变量,提供静态方法,访问方便

2.System.out.print(hasStar?"**********************\n":" "); 这里采用三目运算符实现有无分隔符的操作

  1. public static int getInput(){
    Scanner scanner=new Scanner(System.in);
    return scanner.nextInt();
    }
    这里将scanner输入语句封装起来

b.创建Poker类

  • 1.创建Constant类管理一些常量
用数组保存牌的点数
public static final String[] DOTS = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
  • 2.定义PokerType类管理理牌的花⾊色和id号
  • 因为pic和Id都是私有的,所以外部无法直接访问,为了使外部能够访问数据,使用了setter/getter方法
    getter方法不需要参数,有返回值
    setter方法需要参数,没有返回值
public class PokerType {
    private String pic;
    private int id;
 public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
  • 3.定义Poker类
    private String dot;
    private PokerType type;
    public PokerType getType() {
        return type;
    }
    public void setType(PokerType type) {
        this.type = type;
    }

    //setter/getter方法
    public void setDot(String dot){
        this.dot=dot;
    }
    public String getDot(){
        return dot;
    }
}

c.创建PokerManager管理牌的操作

  • 1.生成一副牌
  • 1.首先用ArrayList保存一副牌。
  • 2.定义一个方法生成一副牌
public class PokerManager {
    //保存一副牌
    private ArrayList<Poker> pokers = new ArrayList<>();

    //创建静态的变量
    public static final PokerManager manager =new PokerManager();
    //私有化构造方法
    private PokerManager(){

    }

    //定义一个方法生成一副牌
    public void deal() {
        //遍历整个点数的数组
        for (int i = 0; i < Constant.DOTS.length;i++){
            String dot=Constant.DOTS[i];

            //生成4种花色
            for(int j=0 ; j<Constant.TYPES.length; j++){
                //创建一张牌
                Poker poker=new Poker(dot,Constant.TYPES[j]);
                //将这张牌保存起来
                pokers.add(poker);
            }
  • 2.为Poker类和PokerType类提供构造方法


    image.png
  • 并不是所有的对象创建的时候都知道具体的值
    当提供一个自定义的构造方法时,默认的构造方法就被屏蔽了,此时就需要自己写一个默认的构造方法
  • 3.创建花色
            PokerType spades=new PokerType("♠",4);
            PokerType hearts=new PokerType("♥",3);
            PokerType clubs=new PokerType("♣",2);
            PokerType diamonds=new PokerType("♦",1);
    1. 创建四张牌
      public Poker(){}
      public Poker(String dot,PokerType type){
      this.dot=dot;
      this.type=type;
}
           //创建4张牌
           // Poker ps=new Poker();
           // ps.setDot(dot);
           // ps.setType(spades);
            Poker ps=new Poker(dot,spades);
            Poker ph=new Poker(dot,hearts);
            Poker pc=new Poker(dot,clubs);
            Poker pd=new Poker(dot,diamonds);
    1. 将产⽣的四张牌添加到数组
           //加到数组里面去
            pokers.add(ps);
            pokers.add(ph);
            pokers.add(pc);
            pokers.add(pd);

  • 1.在PokerType⾥面提供4个静态常量对象
  • 1.静态成员变量:把大家公有的东西抽出来,在对象没有创建前,这个东西已经有了
  • 2.此时进行花色比较,只要比花色所对应的id就可以了
   //静态的常量
    public  static final PokerType SPADES=new PokerType("♠",4);
    public  static final PokerType HEARTS=new PokerType("♥",3);
    public  static final PokerType CLUBS=new PokerType("♣",2);
    public  static final PokerType DIAMONDS=new PokerType("♦",1);
  • 2.在Constant⾥里里⾯面提供数组保存这4个常量
   //保存固定的几个花色
    public static final PokerType[] TYPES = {PokerType.SPADES, PokerType.HEARTS, PokerType.CLUBS, PokerType.DIAMONDS};

3.实现功能

  • Collections.shuffle(),方法,打乱顺序
  //生成4种花色
            for(int j=0 ; j<Constant.TYPES.length; j++){
                //创建一张牌
                Poker poker=new Poker(dot,Constant.TYPES[j]);
                //将这张牌保存起来
                pokers.add(poker);
            }
        //洗牌
        Collections.shuffle(pokers);
    }

4.提供⼀一个方法输出这副牌 :拼接每张牌的输出格式

 //显示一副牌
    public void  show(){
        for(Poker poker:pokers){
            System.out.print(poker.getDot()+poker.getType().getPic()+" ");
        }
        System.out.println();
    }

5.使⽤

       //生成一副牌
        PokerManager.manager.deal();
        //显示一副牌
        PokerManager.manager.show();

image.png

e.创建玩家类Player

    public class Player {
        public String name;
        public int id;
        public int money;
    public Player(){}
    public Player(String name, int id, int money){
        this.name=name;
        this.money=money;
        this.id=id;
        }

f.创建玩家管理理器器PlayerManager 管理理玩家信息

  • 1.Constant里⾯添加常量 保存默认提供的姓名和金币数
    //保存默认的玩家姓名
    public static final  String[] DEFAULT_NAMES={"张三","李四","王二","麻子"};
    1. 初始化玩家信息
   public class PlayerManager {
      public ArrayList<Player> players = new ArrayList<>();
      public void initPlayer(int count){
        for(int i=0; i<count; i++){
            //创建玩家
            String  name=Constant.DEFAULT_NAMES[i];
            Player player=new Player(name,i+1,Constant.MONEY);

            //保存玩家
            players.add(player);
        }
    }
  • 3.实现toString⽅法, 方便打印
  • 当打印一个对象的时候 就会默认去调用对象的toString方法
  • 如果当前里面没有实现这个方法 就到父类里面去查找
  • object里面默认实现就是打印对象的首地址
 public String toString() {
 return id+" 号玩家  "+name+"  筹码:"+money+pkString;
}
  • 4.输出玩家信息
 //输出玩家信息
    public  void show(){
        for(Player player:players){
            System.out.println(player);
        }
    }
  • 5.使用
       Utils.showText(false, false, new String[]{"请输入参与人数"});
        int count=Utils.getInput();

        //初始化玩家
        PlayerManager.manager.initPlayer(count);
        PlayerManager.manager.show();
  • 6.结果
image.png

g.游戏中⼼心管理理游戏

1.PlayerManager和PokerManager 提供单例对象

    //创建静态的变量
    public static final PokerManager manager =new PokerManager();
    //私有化构造方法
    private PokerManager(){
    }

2.PlayerManager实现打底注的方法

  * 打底
     * @param count 每局消耗的金币
     * @return -1:失败 >0 成功
     */
    public int betAll(int count){
        int total=0;
        for(Player player:players){
            player.bet(count);
            int result =player.bet(count);
            if(result==-1){
                return -1;
            }
        }
        return count * players.size();
    }
    public Player currentPlayer(){
        //获取当前玩家
      return players.get(currentPlayerIndex);

    }

3.Player实现下注⽅方法

  public int bet(int count){
        //判断自己的金币是否大于下注金额
        if(money>= count){
           money -=count;
            return count;
        }else{
            return -1;
        }
    }
}

4.Gamecenter 开始游戏

 public void start(){
        //扣除底注
        System.out.println("游戏开始,请打底:");
        PlayerManager.manager.betAll(Constant.BASE);
        PlayerManager.manager.show();
    }

h.实现发牌

  • 1.在Player类⾥里里⾯面添加Poker对象 每个⼈人有⼀一张牌


    image.png
  • 2.PokerManager类添加发牌⽅方法
 public void dealCards(ArrayList<Player> players){
        for(int i=0; i<players.size();i++){
            Player player=players.get(i);
            //将数组里面对应的扑克牌给对应玩家
            player.poker=pokers.get(i);
        }
    }
  • 3.GameCenter的start⽅方法调⽤用发牌
  System.out.println("开始发牌");      
  PokerManager.manager.dealCards(PlayerManager.manager.players);
  PokerManager.manager.show();

上一篇 下一篇

猜你喜欢

热点阅读