1. <wbr id="m8vu6"></wbr>

      <del id="m8vu6"><center id="m8vu6"><source id="m8vu6"></source></center></del>
        <p id="m8vu6"><sub id="m8vu6"></sub></p>

        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 
              
        
        
        
          
        免费看成年人视频大全_免费看成年人视频在线观看