心得體會(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;
}

1.上圖中用
ArrayList<Person> people=new ArrayList<>();實(shí)現(xiàn)了動(dòng)態(tài)分布數(shù)組內(nèi)存空間
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

- 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)有無分隔符的操作
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);
- 創(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);
- 將產(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={"張三","李四","王二","麻子"};
- 初始化玩家信息
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é)果

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();

