java設計模式

創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

行爲型模式,共十一種:策略模式、模板方法模式觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

策略模式:定義了算法族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化獨立於使用算法的客戶。    
    PS:即將對象的行爲抽象出來成一個接口,用一組類來實現接口的行爲,然後在對象類中使用接口來引用行爲類。

Duck類

package headfirst.strategy;

public abstract class Duck {
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;

	public Duck() {
	}

	public void swim() {
		System.out.println("Duck can swim!");
	}
	
	public void performQuack() {
		quackBehavior.quack();
	}
	
	public void performFly() {
		flyBehavior.fly();;
	}
	
	public void setFlyBehavior(FlyBehavior flyBehavior) {
		this.flyBehavior = flyBehavior;
	}

	public void setQuackBehavior(QuackBehavior quackBehavior) {
		this.quackBehavior = quackBehavior;
	}

}

接口行爲

package headfirst.strategy;

public interface QuackBehavior {
	void quack();
}


package headfirst.strategy;

public interface FlyBehavior {
	void fly();
}

接口行爲實現

package headfirst.strategy;

public class FlyWithSwing implements FlyBehavior{

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("fly");
	}

}



package headfirst.strategy;

public class Squack implements QuackBehavior{

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("zhi zhi zhi");
	}

}

package headfirst.strategy;

public class Quack implements QuackBehavior{

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("gagaga");
	}

}

 

實現的鴨子

package headfirst.strategy;
public class WhiteDuck extends Duck{
	public WhiteDuck() {
		flyBehavior = new FlyWithSwing();
		quackBehavior = new Quack();
	}
	
	public static void main(String[] args) {
		Duck model = new WhiteDuck();
		model.performFly();
		model.performQuack();
		model.setQuackBehavior(new MuteQuack());
		model.performQuack();
	}
}

 

                   被觀察對象    observer
   鬆耦合      出版者  +      訂閱者
觀察者模式:定義了對象之間一對多依賴,這樣一來,當一個對象狀態改變時,他的所有依賴者都會收到通知並更新。
    PS:出版者發生信息變化的時候會通知所有訂閱者,訂閱者和第三方類可以退訂或者訂購出版者的消息。
            Subject接口                   Observer接口
        registerObserver();                  update();
        removeObserver();                需要保存出版者的引用
        notifyObserver();                方便退訂操作
    實現類中有一個List<Observer>
    當信息改變時,循環調用所有Observer
    的update();

java內置的 Observable 類            Observer接口
                                                  update(Observable obs,Object arg);
                                                    這裏可以自定義用obs來get想要的數據
        這裏繼承後可以設置
        一個changd=false
        當狀態改變到一定時
        設置true並調用update

接口    可以在Subject中設置一個flag 然後當數據變化到一定變化時再設置爲true執行

package headfirst.observer;


public interface Observer {
    void update(double temple,double dryrate);//推數據
    void update(Subject subject,Object arg);//拉數據,可觀察者自定義拉所需要的數據
}


package headfirst.observer;

public interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObserver();
}

實現類   

package headfirst.observer;

import java.util.LinkedList;
import java.util.List;

/**
 * Created by Alen on 2018/9/28.
 */
public class WeatherData implements Subject{
    private double temple;
    private double dryrate;
    private List<Observer> observers ;

    WeatherData(){
        observers = new LinkedList<Observer>();
    }


    public double getTemple() {
        return temple;
    }


    public double getDryrate() {
        return dryrate;
    }

    public void measureChanged(){
        notifyObserver();
    }

    public void setMeasure(double temple,double dryrate){
        this.dryrate = dryrate;
        this.temple = temple;
        measureChanged();
    }

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

    @Override
    public void removeObserver(Observer o) {
        int i =observers.indexOf(o);
        if(i>=0){
            observers.remove(i);
        }
    }

    @Override
    public void notifyObserver() {
        for (Observer observer : observers) {
            observer.update( temple, dryrate);
        }
    }



}
package headfirst.observer;

/**
 * Created by Alen on 2018/9/28.
 */
public class Display implements Observer {
    Subject subject;
    private double temple;
    private double dryrate;

    Display( Subject subject){
        this.subject=subject;
        subject.registerObserver(this);
    }

    @Override
    public void update(double temple,double dryrate) {
        this.dryrate = dryrate;
        this.temple = temple;
        display();
    }

    public void display(){
        System.out.println("this"+dryrate+","+temple);
    }

    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        Display display= new Display(weatherData);
        weatherData.setMeasure(20,20);
    }

}

 

利用Java Util包的實現

package headfirst.observer.useutil;

import java.util.Observable;

/**
 * Created by Alen on 2018/9/28.
 */
public class WeatherData extends Observable{
    private double temple;
    private double dryrate;
    WeatherData(){

    }
    public void measureChanged(){
        setChanged();
        notifyObservers();
    }
    public void setMeasure(double temple,double dryrate){
        this.dryrate = dryrate;
        this.temple = temple;
        measureChanged();
    }

    public double getTemple() {
        return temple;
    }

    public double getDryrate() {
        return dryrate;
    }
}
package headfirst.observer.useutil;


import java.util.Observable;
import java.util.Observer;

/**
 * Created by Alen on 2018/9/28.
 */
public class Display implements Observer {
    private double temple;
    private double dryrate;
    Observable observable;
    Display(Observable observable){
        this.observable = observable;
        observable.addObserver(this);
    }
    @Override
    public void update(Observable observable, Object arg) {
        if (observable instanceof Observable){
           WeatherData weatherData = (WeatherData) observable;
            this.dryrate = weatherData.getDryrate();
            this.temple = weatherData.getTemple();
            display();
        }
    }
    public void display(){
        System.out.println("this"+dryrate+","+temple);
    }

    public static void main(String[] args) {
       WeatherData weatherData = new WeatherData();
        Display display = new Display(weatherData);
        weatherData.setMeasure(1,1);
    }
}

 

裝飾者模式:動態地將責任附加到對象上,若需要擴展功能,裝飾者提供了比繼承更有彈性的替代方案
 

基礎類

package headfirst.decorator;

//飲料類
public abstract class Beverage {
    String description = "Unknown Beverage";
    public  String getDescription(){
        return description;
    }
    public abstract double cost();

}

咖啡類

package headfirst.decorator;

//濃咖啡
public class Espresso extends Beverage {
    public Espresso(){
        description = "Espresso";
    }
    @Override
    public double cost() {
        return 1.99;
    }
}


package headfirst.decorator;

//另外一種飲料
public class HouseBlend extends Beverage {
    public HouseBlend(){
        description = "HouseBlend";
    }
    @Override
    public double cost() {
        return 0.89;
    }
}

裝飾器類

package headfirst.decorator;

//調料裝飾者
public abstract class CondimentDecorator extends Beverage{
    public abstract String getDescription();
}





package headfirst.decorator;

/**
 * Created by Alen on 2018/9/28.
 */
public class Moka extends CondimentDecorator {
    Beverage beverage ;

    public Moka (Beverage beverage) {
         this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription()+",Moka";
    }

    @Override
    public double cost() {
        return 0.2+beverage.cost();
    }

    public static void main(String[] args) {
        HouseBlend houseBlend = new HouseBlend();
        Moka moka = new Moka(houseBlend);
        System.out.println(moka.getDescription()+""+moka.cost());
        Espresso espresso =new Espresso();
        Moka moka1 = new Moka(espresso );
        System.out.println(moka1.getDescription()+""+moka1.cost());
        //double moka
        Moka moka2 =new Moka(moka1);
        System.out.println(moka2.getDescription()+""+moka2.cost());

    }
}

 

 

 簡單工廠(Simple Factory)又叫做靜態工廠方法(Static Factory Method) 有一個產品接口沒有工廠接口

package com.wenniuwuren.simplefactory;
/**
 * 工廠(Creator)角色 :簡單工廠模式的核心,它負責實現創建所有實例的內部邏輯。
 * 工廠類可以被外界直接調用,創建所需的產品對象。
 *
 */
public class SomethingCreator {
	// 靜態工廠   這就是爲什麼簡單工廠又叫靜態工廠方法
    public static Tree factory(String fruitType) throws Exception{
        if(fruitType.equals("Lemon")){
            return new LemonTree();
        }else if(fruitType.equals("Apple")){
            return new AppleTree();
        }else{
            throw new Exception("暫時不支持生產該類型產品");
        }
    }
}

工廠方法模式:定義了一個創建對象的接口,但是由子類決定要實例化哪一個類,工廠方法把讓類實例化推遲到子類。


抽象工廠模式:提供了一個接口,用於創建相關或依賴對象的家族,而不需要指定具體類

工廠方法模式
一個抽象產品類,可以派生出多個具體產品類。   
一個抽象工廠類,可以派生出多個具體工廠類。   
每個具體工廠類只能創建一個具體產品類的實例。

抽象工廠模式
多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。   
一個抽象工廠類,可以派生出多個具體工廠類。   
每個具體工廠類可以創建多個具體產品類的實例,也就是創建的是一個產品線下的多個產品。   
    
區別:
工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。   
工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。
工廠方法創建 "一種" 產品,他的着重點在於"怎麼創建",也就是說如果你開發,你的大量代碼很可能圍繞着這種產品的構造,初始化這些細節上面。也因爲如此,類似的產品之間有很多可以複用的特徵,所以會和模版方法相隨。 

抽象工廠需要創建一些列產品,着重點在於"創建哪些"產品上,也就是說,如果你開發,你的主要任務是劃分不同差異的產品線,並且儘量保持每條產品線接口一致,從而可以從同一個抽象工廠繼承。

 


單例模式:確保一個類只有一個實例,並且提供全局訪問點
 

  //  1.延遲初始化
          private volatile Resource resource;
        public Resource getResource() {
            if (resource == null) {
                synchronized (this) {
                    if (resource == null) {
                        resource = new Resource();
                    }
                }
            }
            return resource;
        }
  //  2.快速初始化
        public static Resource getResource() {//initialized   三個狀態 ,其他檢測到字段wei
            return InstanceHolder.re;  //第二個,就釋放鎖,掛起等待喚醒
        }
        private static class InstanceHolder {
            public static Resource re = new Resource(); //會使用 Class對象初始化鎖 和 state字段
        } //其中狀態有noInitialization  initializing
   // 3.同步初始化,性能差 
        public synchronized Resource getResource(){
            if(null==resource){
                resource = new Resource();
            }
        }

命令模式:將請求封裝成對象,以便使用不同的請求,隊列或者日誌來參數化其他對象。命令模式也支持可撤銷的            操作。
        PS:分隔開“發出請求的對象”與“接受和執行這些請求的對象”
    服務員   Command
    takeroder    setCommand
    orderup   客戶端
    廚師        execute
    顧客           Receiver

package headfirst.command;

public interface Command {
    public void execute();
    public void undo();
}



package headfirst.command;


public class CommandController {
    Command  oncommand;
    Command offcommand;

    public void setCommand(Command  oncommand,Command offcommand) {
        this.offcommand = offcommand;
        this.oncommand = oncommand;
    }
    public void onButtonWasPressed(){
        oncommand.execute();
    }
    public void offButtonWasPressed(){
        offcommand.execute();
    }
}



package headfirst.command;

public class LigthOnCommand implements Command {
    Light light;
    LigthOnCommand(Light light){
         this.light=light;
    }
    @Override
    public void execute() {
        light.on();
    }

    @Override
    public void undo() {
        light.off();
    }
}

package headfirst.command;

public class Light {
    void on() {
        System.out.println("on");
    }

    void off() {
        System.out.println("off");
    }
}


public class test {
    public static void main(String[] args) {
        CommandController controller = new CommandController();
        LigthOnCommand ligthOnCommand = new LigthOnCommand(new Light());
        controller.setCommand(ligthOnCommand,ligthOnCommand);
        controller.onButtonWasPressed();
    }
}

適配器模式:將一個類的接口轉換成客戶期望的另外一個接口,適配器讓原本接口不兼容的類可以合作無間
    對象適配器:通過實現接口,然後使用 組合 關聯。
    類適配器:通過繼承被適配對象,實現目標接口

// 對象適配器
// 適配器類,直接關聯被適配類,同時實現標準接口
class Adapter implements Target{
    // 直接關聯被適配類
    private Adaptee adaptee;

    // 可以通過構造函數傳入具體需要適配的被適配類對象
    public Adapter (Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    public void request() {
        // 這裏是使用委託的方式完成特殊功能
        this.adaptee.specificRequest();
    }
}

// 測試類
public class Client {
    public static void main(String[] args) {
        // 使用普通功能類
        Target concreteTarget = new ConcreteTarget();
        concreteTarget.request();

        // 使用特殊功能類,即適配類,
        // 需要先創建一個被適配類的對象作爲參數
        Target adapter = new Adapter(new Adaptee());
        adapter.request();
    }
}

---------------------
類適配器

// 已存在的、具有特殊功能、但不符合我們既有的標準接口的類
class Adaptee {
    public void specificRequest() {
        System.out.println("被適配類 具有特殊功能...");
    }
}

// 目標接口,或稱爲標準接口
interface Target {
    public void request();
}

// 具體目標類,只提供普通功能
class ConcreteTarget implements Target {
    public void request() {
        System.out.println("普通類 具有普通功能...");
    }
}

// 適配器類,繼承了被適配類,同時實現標準接口
class Adapter extends Adaptee implements Target{
    public void request() {
        super.specificRequest();
    }
}

// 測試類
public class Client {
    public static void main(String[] args) {
        // 使用普通功能類
        Target concreteTarget = new ConcreteTarget();//實例化一個普通類
        concreteTarget.request();

        // 使用特殊功能類,即適配類
        Target adapter = new Adapter();
        adapter.request();
    }
}


外觀模式:提供了一個統一的接口,用來訪問子系統中的一羣接口,外觀定義了一個高層接口,讓子系統更容易使用

class HealthOffice implements Executive{

    @Override
    public void approve() {
        System.out.println("衛生局通過審批");
    }
    
}
class RevenueOffice implements Executive{

    @Override
    public void approve() {
        System.out.println("稅務局完成登記,定時回去收稅");
    }
    
}
class SaicOffice implements Executive{

    @Override
    public void approve() {
        System.out.println("工商局完成審覈,辦法營業執照");
    }
    
}

class ApproveFacade {

    public ApproveFacade() {

    }

    public void wholeApprove() {
        new HealthOffice().approve();
        new RevenueOffice().approve();
        new SaicOffice().approve();
    }

}

public class FacadeTest {

    public static void main(String[] args) {
        System.out.println("開始辦理行政手續...");

        ApproveFacade af = new ApproveFacade();
        af.wholeApprove();
        
        System.out.println("行政手續終於辦完了");
    }

}
//避免了在main中
  //      new HealthOffice().approve();
  //      new RevenueOffice().approve();
    //    new SaicOffice().approve();

模版方法模式:在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中來實現,模版方法使得子類可以在不改變算法結構的情況下,重新定義算法中的某些步驟。

public abstract CaffeineBeverage{
    void prepare(){  //模版方法
        boilWater();
        brew();
        pourInCup();
        addCondiments();
        hook();          //鉤子,子類看情況要不要覆蓋實現
    }                
    void void boilWater(){
        dosth("");
    }
    void pourInCup(){
        dosth("");
    }
    abstract void  brew();//由子類實現
    abstract void addCondiments();//由子類實現

     void  hook(){
         //do nothing!!!!
     }
}
鉤子:1.可以讓子類實現算法中可選的部分
     2.讓子類對模版方法中即將發生的方法做出反應

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章