這段時(shí)間比較空閑,所以就抽出一些時(shí)間自己做了一個(gè)掃雷的小游戲。期間深有感觸,現(xiàn)總結(jié)如下:
    1、這個(gè)是我從設(shè)計(jì)開始完全采用面向?qū)ο笏枷氲某绦颍憻捔宋颐嫦驅(qū)ο蟮脑O(shè)計(jì)能力。
    2、其中對(duì)Observer Pattern、Adapter Pattern、Factory Pattern等設(shè)計(jì)模式進(jìn)行了應(yīng)用,加深了對(duì)設(shè)計(jì)模式的理解,也感受到了設(shè)計(jì)模式帶來的好處。
    3、熟悉了Java之中Swing的編程模式。
    4、理解了面向?qū)ο笤O(shè)計(jì)法則之中的開放-封閉法則(OCP)的優(yōu)點(diǎn)。
下面對(duì)其中一些感觸比較深的地方進(jìn)行敘述。
    開閉法則:
    ·開閉法則認(rèn)為我們應(yīng)該試圖是設(shè)計(jì)出永遠(yuǎn)也不需要改變的模塊。
    ·我們可以添加新代碼來擴(kuò)展系統(tǒng)的行為。我們不能對(duì)已有的代碼進(jìn)行修改。
    ·符合OCP的模塊需要滿足兩個(gè)標(biāo)準(zhǔn):
       1、可擴(kuò)展,即“對(duì)擴(kuò)展是開放的”(Open for Extension)  模塊的行為可以被擴(kuò)展,以需要滿足新的需求。
       2、不可改變,即“對(duì)更改是封閉的”(Closed for Modification)模塊的源代碼是不允許進(jìn)行改動(dòng)的。
    我們?nèi)绾稳プ瞿兀?br>    ·抽象(Abstraction)
    ·多態(tài)(Polymorphism)
    ·繼承(Inheritance)
    ·接口(Interface)   
    一個(gè)軟件系統(tǒng)的所有模塊不可能都滿足OCP,但是我們應(yīng)該努力最小化這些不滿足OCP的模塊數(shù)量。
    開閉法則是OO真正的核心。
    符合該法則便意味著最高等級(jí)的復(fù)用性(reusability)和可維護(hù)性(maintainability)。

    當(dāng)時(shí)我在考慮做雷點(diǎn)的時(shí)候,沒有多想就直接考慮swing的jbutton了,因?yàn)樗呀?jīng)設(shè)計(jì)好了事件的接受處理方法,并且可以直接調(diào)用,這個(gè)就是直接使用了開閉法則,對(duì)我們開發(fā)非常有利。
    在編制過程之中如何取得panel之中的特定位置點(diǎn)的button也是困擾我的一個(gè)問題,也是由于自己以前對(duì)swing不是很熟的原因,后來認(rèn)真看了關(guān)于swing layout方面的書之后知道了,我是用的gridlayout可以取得特定index的對(duì)象。
    之后困擾我的是,如何在button響應(yīng)事件之中作出相應(yīng)的處理,由于新new了一個(gè)nest anonymous class this對(duì)象無法獲取之上的對(duì)象。思考過后就用到了下面的Observer Pattern解決這個(gè)問題。
    Observer Pattern的所有參與者:

    ConcreteSubject(具體目標(biāo))參與者:
    ConcreteSubject參與者表示實(shí)際“被觀察的一方(目標(biāo))”的參與者。一旦狀態(tài)有變化,就會(huì)立即通知已登錄的Observer參與者。扮演這個(gè)角色的是MinePanel類。

    Observer(觀察者)參與者:
    參與者是被Subject參與者通知“狀態(tài)有變化”的參與者。通知的方法是update。扮演這個(gè)角色的是Observer接口。

    ConcreteObserver(具體觀察者)參與者

    ConcreteObserver參與者是實(shí)際的Observer。一調(diào)用update方法時(shí),既可以從該方法取得Subject的目前狀態(tài)。扮演這個(gè)角色的是SweepMineWindow類。
   
    Subject狀態(tài)有變化
    |
    通知Observer
    |
    Observer調(diào)用Subject的方法
  

    其類圖如下:



    在擴(kuò)展空點(diǎn)與信息點(diǎn)的時(shí)候,我為了避免遞歸造成的低效率和高空間,使用了一個(gè)自己想出來的水波算法,其核心思想就是,擴(kuò)展的時(shí)候以點(diǎn)擊點(diǎn)為基點(diǎn)作出類似于水波擴(kuò)展一樣的空點(diǎn)與信息點(diǎn)的判斷,這樣更加有目的性,避免了大量的時(shí)空開銷。在擴(kuò)展的時(shí)候要分出來轉(zhuǎn)角點(diǎn)與普通擴(kuò)展點(diǎn),然后再判斷是否為雷點(diǎn)。這個(gè)算法的思想不是很難但是對(duì)于邊界情況的判斷比較復(fù)雜。