JAVA-(單例設(shè)計(jì)模式、數(shù)組、撲克demo)


心得體會(huì)

  • 今天主要寫了關(guān)于撲克的demo,這對我來說很復(fù)雜,總而言之,就是今天上了那么久的課,課后我回想起來,在我腦海中留下的印象很少很少,整天下來我是云里霧里,剛開始,還能跟上進(jìn)度,老師講到哪,代碼敲到哪,但在最后面的一段時(shí)間,我發(fā)現(xiàn)自己錯(cuò)誤率越來越多,然后只能無奈的停下了手。老師一邊講課,我一邊跟著敲代碼,有時(shí)候會(huì)把精力放在跟著老師敲上面,往往知識(shí)點(diǎn)會(huì)聽一半漏一半,可能我不太習(xí)慣邊敲邊聽吧,應(yīng)該還有一部分原因就是自己手速太慢,我已在慢慢嘗試快捷鍵的使用,但還不太熟練,但我會(huì)努力加快自己手速的^^,今天有很多 東西都沒聽懂,所以晚上得重溫一遍 今天的課,哈哈,今天晚上任重而道遠(yuǎn)呀

技術(shù)

  • 1.單例設(shè)計(jì)模式
    ----a.單例設(shè)計(jì)模式的特點(diǎn)
    ----b.單例模式的要點(diǎn)
    ----c.餓漢式單例和懶漢式單例
  • 2.數(shù)組引用
  • 3.撲克demo
    ----a.封裝實(shí)現(xiàn)文本輸出
    ----b.創(chuàng)建Poker類
    ----c.創(chuàng)建PokerManager管理牌的操作
    ----d.優(yōu)化生成一副牌的操作
    ----e.創(chuàng)建玩家類Player
    ----f.創(chuàng)建玩家管理理器?PlayerManager 管理理玩家信息
    ----g.游戲中?心管理理游戲
    ----h.實(shí)現(xiàn)發(fā)牌

具體操作

1.單例設(shè)計(jì)模式

  • a.單例設(shè)計(jì)模式的特點(diǎn)
  • 1.單例類只能有一個(gè)實(shí)例。
  • 2.單例類必須自己創(chuàng)建自己的唯一實(shí)例。
  • 3.單例類必須給所有其他對象提供這一實(shí)例。
  • b.單例模式的要點(diǎn)
  • 1.私有的構(gòu)造方法
  • 2.指向自己實(shí)例的私有靜態(tài)引用
  • 3.以自己實(shí)例為返回值的靜態(tài)的公有的方法
  • c.單例模式根據(jù)實(shí)例化對象時(shí)機(jī)的不同分為兩種
  • 一種是餓漢式單例,一種是懶漢式單例。
  • 餓漢式單例在單例類被加載時(shí)候,就實(shí)例化一個(gè)對象交給自己用;
    懶漢式在調(diào)用取得實(shí)例方法的時(shí)候才會(huì)實(shí)例化對象。

-----------餓漢式單例

 class Poker{
        //defalt,share,Instance,manager
        //2.定義一個(gè)靜態(tài)的成員變量 記錄這個(gè)單例對象
        //餓漢式
        public static final Poker shared = new Poker();

        //1.默認(rèn)構(gòu)造函數(shù)
        private Poker() { }

        public void test() {
        }
    }
  • 步驟:1.默認(rèn)構(gòu)造方法 ----2.定義一個(gè)靜態(tài)的成員變量 記錄這個(gè)單例對象

-----------懶漢式單例

class Player { 
        public int count;
        //2.創(chuàng)建靜態(tài)變量
        private static Player shared = null;
       //1.私有化
        private Player() { }
        //3.提供給外部一個(gè)訪問的方法
        public static Player getInstance() {
            Object b = new Object();
            synchronized (b) {
                if (shared == null) {
                    //如果沒有創(chuàng)建 那么就創(chuàng)建一個(gè)
                    shared = new Player();
                }
            }
            return shared;
        }
    }

步驟:1.私有化構(gòu)造函數(shù)------2.創(chuàng)建靜態(tài)變量------ 3.提供給外部一個(gè)訪問的方法
解析:懶漢式單例先將構(gòu)造函數(shù)私有化,外部無法直接訪問,要讓外部訪問到,就必須提供提供給外部一個(gè)訪問的方法,給外部一個(gè) getInstance()方法。
懶漢式的缺點(diǎn)是:沒有考慮到線程安全,可能存在多個(gè)訪問者同時(shí)訪問,并同時(shí)構(gòu)造了多個(gè)對象的問題。之所以叫做懶漢模式,主要是因?yàn)榇朔N方法可以非常明顯的lazy loading。


2.數(shù)組引用

class Test2{
    public static void main(String[] args){
        //泛型
        /** 數(shù)組里面保存的都是對象的引用(指針)
         * 改變數(shù)組里面對象的屬性變量
         * 原始對象的值也跟著改變
         * 因?yàn)榇蠹叶际侵赶蛲粋€(gè)內(nèi)存空間
         */
        ArrayList<Person> people=new ArrayList<>();
        //添加數(shù)據(jù)
        Person xw=new Person();
        people.add(xw);
        Person zs=new Person();
        people.add(zs);
        //訪問數(shù)據(jù)
        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<>();實(shí)現(xiàn)了動(dòng)態(tài)分布數(shù)組內(nèi)存空間

  1. Person xw=new Person();
    people.add(xw);
    Person zs=new Person();
    people.add(zs);
    這里分別創(chuàng)建了xw,zs兩個(gè)對象,并通過add()把這兩個(gè)對象加到數(shù)組里面去了

3.上圖中System.out.println(xw2.name);打印了xw2,得到結(jié)果是小王,如果換成System.out.println(xw.name);,得到結(jié)果同樣是小王
xw和xw2指向的是同一個(gè)內(nèi)容,本來xw的打印結(jié)果應(yīng)該是null的,但通過xw2將“小王”賦給了數(shù)組的第一個(gè),于是xw指向的內(nèi)容也就變成了“小王”,數(shù)組里面存的是地址


3.撲克demo

image.png

  • a.輸出語句的封裝

輸出語句:完成如下指令

  • 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":" ");
        //判斷輸出的內(nèi)容是一行還是多行
        if(contents.length==1){
            System.out.print(contents[0]);
          System.out.print(hasStar?"\n":" ");
        }else{
            //輸出帶編號(hào)的多行數(shù)據(jù)
            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.如果不需要保存數(shù)據(jù),沒有成員變量,提供靜態(tài)方法,訪問方便

2.System.out.print(hasStar?"**********************\n":" "); 這里采用三目運(yùn)算符實(shí)現(xiàn)有無分隔符的操作

  1. public static int getInput(){
    Scanner scanner=new Scanner(System.in);
    return scanner.nextInt();
    }
    這里將scanner輸入語句封裝起來

b.創(chuàng)建Poker類

  • 1.創(chuàng)建Constant類管理一些常量
用數(shù)組保存牌的點(diǎn)數(shù)
public static final String[] DOTS = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
  • 2.定義PokerType類管理理牌的花?色和id號(hào)
  • 因?yàn)閜ic和Id都是私有的,所以外部無法直接訪問,為了使外部能夠訪問數(shù)據(jù),使用了setter/getter方法
    getter方法不需要參數(shù),有返回值
    setter方法需要參數(shù),沒有返回值
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.創(chuàng)建PokerManager管理牌的操作

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

    //創(chuàng)建靜態(tài)的變量
    public static final PokerManager manager =new PokerManager();
    //私有化構(gòu)造方法
    private PokerManager(){

    }

    //定義一個(gè)方法生成一副牌
    public void deal() {
        //遍歷整個(gè)點(diǎn)數(shù)的數(shù)組
        for (int i = 0; i < Constant.DOTS.length;i++){
            String dot=Constant.DOTS[i];

            //生成4種花色
            for(int j=0 ; j<Constant.TYPES.length; j++){
                //創(chuàng)建一張牌
                Poker poker=new Poker(dot,Constant.TYPES[j]);
                //將這張牌保存起來
                pokers.add(poker);
            }
  • 2.為Poker類和PokerType類提供構(gòu)造方法


    image.png
  • 并不是所有的對象創(chuàng)建的時(shí)候都知道具體的值
    當(dāng)提供一個(gè)自定義的構(gòu)造方法時(shí),默認(rèn)的構(gòu)造方法就被屏蔽了,此時(shí)就需要自己寫一個(gè)默認(rèn)的構(gòu)造方法
  • 3.創(chuàng)建花色
            PokerType spades=new PokerType("?",4);
            PokerType hearts=new PokerType("?",3);
            PokerType clubs=new PokerType("?",2);
            PokerType diamonds=new PokerType("?",1);
    1. 創(chuàng)建四張牌
      public Poker(){}
      public Poker(String dot,PokerType type){
      this.dot=dot;
      this.type=type;
}
           //創(chuàng)建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. 將產(chǎn)?的四張牌添加到數(shù)組
           //加到數(shù)組里面去
            pokers.add(ps);
            pokers.add(ph);
            pokers.add(pc);
            pokers.add(pd);

  • d.優(yōu)化生成一副牌的操作
  • 1.在PokerType?面提供4個(gè)靜態(tài)常量對象
  • 1.靜態(tài)成員變量:把大家公有的東西抽出來,在對象沒有創(chuàng)建前,這個(gè)東西已經(jīng)有了
  • 2.此時(shí)進(jìn)行花色比較,只要比花色所對應(yīng)的id就可以了
   //靜態(tài)的常量
    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?里里?面提供數(shù)組保存這4個(gè)常量
   //保存固定的幾個(gè)花色
    public static final PokerType[] TYPES = {PokerType.SPADES, PokerType.HEARTS, PokerType.CLUBS, PokerType.DIAMONDS};

3.實(shí)現(xiàn)功能

  • Collections.shuffle(),方法,打亂順序
  //生成4種花色
            for(int j=0 ; j<Constant.TYPES.length; j++){
                //創(chuàng)建一張牌
                Poker poker=new Poker(dot,Constant.TYPES[j]);
                //將這張牌保存起來
                pokers.add(poker);
            }
        //洗牌
        Collections.shuffle(pokers);
    }

4.提供?一個(gè)方法輸出這副牌 :拼接每張牌的輸出格式

 //顯示一副牌
    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.創(chuàng)建玩家類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.創(chuàng)建玩家管理理器?PlayerManager 管理理玩家信息

  • 1.Constant里?添加常量 保存默認(rèn)提供的姓名和金幣數(shù)
    //保存默認(rèn)的玩家姓名
    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++){
            //創(chuàng)建玩家
            String  name=Constant.DEFAULT_NAMES[i];
            Player player=new Player(name,i+1,Constant.MONEY);

            //保存玩家
            players.add(player);
        }
    }
  • 3.實(shí)現(xiàn)toString?法, 方便打印
  • 當(dāng)打印一個(gè)對象的時(shí)候 就會(huì)默認(rèn)去調(diào)用對象的toString方法
  • 如果當(dāng)前里面沒有實(shí)現(xiàn)這個(gè)方法 就到父類里面去查找
  • object里面默認(rèn)實(shí)現(xiàn)就是打印對象的首地址
 public String toString() {
 return id+" 號(hào)玩家  "+name+"  籌碼:"+money+pkString;
}
  • 4.輸出玩家信息
 //輸出玩家信息
    public  void show(){
        for(Player player:players){
            System.out.println(player);
        }
    }
  • 5.使用
       Utils.showText(false, false, new String[]{"請輸入?yún)⑴c人數(shù)"});
        int count=Utils.getInput();

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

g.游戲中?心管理理游戲

1.PlayerManager和PokerManager 提供單例對象

    //創(chuàng)建靜態(tài)的變量
    public static final PokerManager manager =new PokerManager();
    //私有化構(gòu)造方法
    private PokerManager(){
    }

2.PlayerManager實(shí)現(xiàn)打底注的方法

  * 打底
     * @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(){
        //獲取當(dāng)前玩家
      return players.get(currentPlayerIndex);

    }

3.Player實(shí)現(xiàn)下注?方法

  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.實(shí)現(xiàn)發(fā)牌

  • 1.在Player類?里里?面添加Poker對象 每個(gè)?人有?一張牌


    image.png
  • 2.PokerManager類添加發(fā)牌?方法
 public void dealCards(ArrayList<Player> players){
        for(int i=0; i<players.size();i++){
            Player player=players.get(i);
            //將數(shù)組里面對應(yīng)的撲克牌給對應(yīng)玩家
            player.poker=pokers.get(i);
        }
    }
  • 3.GameCenter的start?方法調(diào)?用發(fā)牌
  System.out.println("開始發(fā)牌");      
  PokerManager.manager.dealCards(PlayerManager.manager.players);
  PokerManager.manager.show();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容