最稳的pk10计划iphone 北京pk10计划手机软件 北京pk10数字的规律 超神手机版pk10软件 pk10北京赛车9码技巧 pk10四期倍投计划表 pk10极速赛车论坛 北京赛车冠军怎样选5码 北京赛车系统下载安装 pk10教程视频 北京pk10选号公式 北京赛车pk10赚钱技巧 北京赛车怎么提升概率 pk10技巧北京快三 北京pk10大小计划
VB.net 2010 視頻教程 VB.net 2010 視頻教程 VB.net 2010 視頻教程
SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
當前位置:
首頁 > 編程開發 > Java教程 >
  • java教程之Java常見設計模式學習(非原創)

  • 2019-06-10 22:47 來源:未知

文章大綱

一、策略模式
二、觀察者模式
三、工廠模式
四、單例模式
五、其他模式
六、設計模式總結
七、參考文章

 

一、策略模式

現在假設我們有個“鴨子項目”,首先我們用OOP(面向對象)的角度設計這個項目,找到鴨子中共同的特性抽取在父類中并具體實現,不同的特性不實現,由子類具體實現,好下面看代碼:

public abstract class Duck {
    /**
     * 叫聲和游泳為相同的特性抽取并具體實現
     */
    public void Quack() {
        System.out.println("~~gaga~~");
    }
    public void swim() {
        System.out.println("~~im swim~~");
    }

    /**
     * 外貌為不同的特性設計為抽象的方法,有子類具體實現
     */
    public abstract void display();

}

現在我們看它的子類:

public class GreenHeadDuck extends Duck {
    @Override
    public void display() {
        System.out.println("**GreenHead**");
    }
}
public class RedHeadDuck extends Duck {
    @Override
    public void display() {
        System.out.println("**RedHead**");
    }
}

好的,現在我們可以看到使用OOP可以很好的解決目前的問題,但是我們往往是需求不斷,所以我們現在又來一個新需求:添加會飛的鴨子
好辦啊,我們只要在父類中添加一個新的方法:

public abstract class Duck {
    /**
     * 叫聲和游泳為相同的特性抽取并具體實現
     */
    public void Quack() {
        System.out.println("~~gaga~~");
    }
    public void swim() {
        System.out.println("~~im swim~~");
    }

    /**針對新需求的方法*/
    public void Fly() {
        System.out.println("~~im fly~~");
    }

    /**
     * 外貌為不同的特性設計為抽象的方法,有子類具體實現
     */
    public abstract void display();

}

問題來了,這個Fly讓所有子類都會飛了,這是不科學的。
繼承的問題:對類的局部改動,尤其超類的局部改動,會影響其他部分。影響會有溢出效應
好現在我們繼續用OOP的方式去解決,使其子類覆蓋Fly:

public class GreenHeadDuck extends Duck {
    @Override
    public void display() {
        System.out.println("**GreenHead**");
    }

    /**
     * 覆蓋
     * */
    public void Fly() {
        System.out.println("~~no fly~~");
    }
}

可以看到貌似問題是解決了,我們現在的鴨子類只有2種,如果有上百種呢,那不是都要去覆蓋。所以這不是一種好的設計模式

分析問題:
需要新的設計方式,應對項目的擴展性,降低復雜度:
1)分析項目變化與不變部分,提取變化部分,抽象成接口+實現;
2)鴨子哪些功能是會根據新需求變化的?叫聲、飛行…
我們將變化的功能設計成接口,下面看代碼:

public interface FlyBehavior {
    void fly();
}
public interface QuackBehavior {
    void quack();
}

來看看新的Duck類:

public abstract class Duck {
    /**
     * 父類定義行為出來,但是沒有具體實例化
     */
    FlyBehavior mFlyBehavior;
    QuackBehavior mQuackBehavior;

    public Duck() {
    }

    public void Fly() {
        if (mFlyBehavior!=null) {
            mFlyBehavior.fly();
        }
    }

    public void Quack() {
        if (mQuackBehavior!=null) {
            mQuackBehavior.quack();
        }
    }

    /**
     * 子類可以透過兩個行為的set方法去動態改變自己的具體行為
     */
    public void setmFlyBehavior(FlyBehavior mFlyBehavior) {
        this.mFlyBehavior = mFlyBehavior;
    }

    public void setmQuackBehavior(QuackBehavior mQuackBehavior) {
        this.mQuackBehavior = mQuackBehavior;
    }

    public abstract void display();
}

然后在去看看子類:

public class RedHeadDuck extends Duck{

    public RedHeadDuck() {
        mFlyBehavior=new GoodFlyBehavior();
        mQuackBehavior=new GaGaQuackBehavior();
    }
    @Override
    public void display() {
        System.out.println("redDuck");
    }
}
public class GreenHeadDuck extends Duck{

    public GreenHeadDuck() {
        mFlyBehavior=new BadFlyBehavior();
        mQuackBehavior=new GeGeQuackBehavior();
    }
    @Override
    public void display() {
        System.out.println("greenDuck");
    }

}

再來看看接口實現類:

public class BadFlyBehavior implements FlyBehavior{

    @Override
    public void fly() {
        System.out.println("bad fly");
    }

}
public class GoodFlyBehavior implements FlyBehavior{

    @Override
    public void fly() {
        System.out.println("good fly");
    }

}
public class NoFlyBehavior implements FlyBehavior{

    @Override
    public void fly() {
        System.out.println("No fly");
    }

}
public class GaGaQuackBehavior implements QuackBehavior{

    @Override
    public void quack() {
        System.out.println("gaga quack");
    }

}
public class GeGeQuackBehavior implements QuackBehavior{

    @Override
    public void quack() {
        System.out.println("gege quack");
    }

}
public class NoQuackBehavior implements QuackBehavior{

    @Override
    public void quack() {
        System.out.println("No Quack");
    }

}

好的,現在我們來分析一下這個設計,在父類中我們定義好FlyBehavior & QuackBehavior 兩個行為接口,然后在子類構造方法中分別設定對應的具體行為
現在來測試一下:

 
 

策略模式:分別封裝行為接口,實現算法族,超類里放行為接口對象,在子類里具體設定行為對象。原則就是:分離變化部分,封裝接口,基于接口編程各種功能。此模式讓行為算法的變化獨立于算法的使用者

二、觀察者模式

現在假設我們有一個需要為A公司實時提供天氣的天氣預報接口項目,好的,首先我們還是以OOP的方式去解決問題,首先我們創建一個天氣臺對象并提供相關方法假設它可以實時為A公司提供天氣數據,下面看代碼:

public class MeteorologicalStation {
    private float pressure;
    private float temperature;
    private float humidity;
    private ACompany company;

    public MeteorologicalStation(ACompany company) {
        this.company=company;
    }

    public float getPressure() {
        return pressure;
    }

    public float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    /**
     * 實時提供天氣情況
     * */
    public void uploadData(float pressure,float temperature,float humidity){
        company.getMeteorologicalStationData(pressure, temperature, humidity);
    }

}

ACompany為A公司:

public class ACompany {
    public void getMeteorologicalStationData(float pressure, float temperature, float humidity) {
        System.out.println("pressure: "+pressure+",temperature: "+temperature+",humidity: "+humidity);
    }
}

測試

 
 

好的,到了這里我們從OOP角度已經初步解決了這個項目,假設現在B公司也需要實時獲取天氣臺提供的天氣情況,如果我們還是繼續使用OOP去設計這個項目,需要在天氣臺接口中添加BCompany,并在實時更新的函數中調用BCompany的獲取天氣的函數,這貌似可以解決這個需求,但是加入后續加入C,D,E..公司,那么天氣臺接口修改的代碼也是比較大,但是我們知道在通常實際開發中,接口一般不會隨著他人的接入而更改,所以現在我們使用觀察者模式去設計這個項目:

/**
 * 該接口相當于天氣臺管理者,誰想接入我和離開我都必須通過它去管理
 * */
public interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifObserver();
}
/**
 * 通過該接口,每個想要接入的公司實現該方法即可。
 */
public interface Observer {
    void getMeteorologicalStationData(float pressure,float temperature,float humidity);
}
public class MeteorologicalStation implements Subject {
    private float pressure;
    private float temperature;
    private float humidity;
    private ArrayList<Observer> observers;

    public MeteorologicalStation(ACompany company) {
        observers = new ArrayList<Observer>();
    }

    public float getPressure() {
        return pressure;
    }

    public float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public void uploadData(float pressure, float temperature, float humidity) {
        this.pressure = pressure;
        this.temperature = temperature;
        this.humidity = humidity;
         notifObserver();
    }

    @Override
    public void registerObserver(Observer o) {
        if (!observers.contains(o)) {
            observers.add(o);
        }
    }

    @Override
    public void removeObserver(Observer o) {
        if (observers.contains(o)) {
            observers.remove(o);
        }
    }

    @Override
    public void 
      



  
pk10赛车冠军技巧
最稳的pk10计划iphone 北京pk10计划手机软件 北京pk10数字的规律 超神手机版pk10软件 pk10北京赛车9码技巧 pk10四期倍投计划表 pk10极速赛车论坛 北京赛车冠军怎样选5码 北京赛车系统下载安装 pk10教程视频 北京pk10选号公式 北京赛车pk10赚钱技巧 北京赛车怎么提升概率 pk10技巧北京快三 北京pk10大小计划
安徽十一运夺金开奖结果 重庆时时开奖记录查询 内蒙古时时彩1019 首席理财分析师是什么 狂野飙车7 极速热力 重庆幸运农场软件 2018滴滴快车不赚钱 储蓄理财技巧 极速时时彩