幾種常見設計模式(Java)

幾種設計模式(總共有二十多種,其他的以後慢慢了解)
(1) 創建型:工廠模式、抽象工廠模式、單例模式
(2) 結構型:適配器模式、裝飾器模式、代理模式
(3) 行爲型:策略模式、模板方法模式、觀察者模式
代碼示例
1)工廠模式
普通工廠是工廠模式的一種,就是建立一個工廠類,對實現了同一接口的一些類進行實例的創建

public interface Sender {
    public void Send();
}
public class MailSender implements Sender {
    @Override
    public void Send() {
        System.out.println("this is mailsender!");
    }
}
public class SmsSender implements Sender {
    @Override
    public void Send() {
        System.out.println("this is sms sender!");
    }
}
public class SendFactory {
    public Sender produce(String type) {
        if ("mail".equals(type)) {
            return new MailSender();
        } else if ("sms".equals(type)) {
            return new SmsSender();
        } else {
            System.out.println("請輸入正確的類型!");
            return null;
        }
    }
}
public class FactoryTest {    
    public static void main(String[] args) {  
        SendFactory factory = new SendFactory();  
        Sender sender = factory.produce("sms");  
        sender.Send();  
    }  
} 

2)抽象工廠模式
抽象工廠模式,創建多個工廠類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼,其實這個模式的好處就是,如果你現在想增加一個功能:發及時信息,則只需做一個實現類,實現Sender接口,同時做一個工廠類,實現Provider接口,就OK了,無需去改動現成的代碼。這樣做,拓展性較好!

public interface Sender {  
    public void Send();  
} 
public class MailSender implements Sender {  
    @Override  
    public void Send() {  
        System.out.println("this is mailsender!");  
    }  
}
public class SmsSender implements Sender {  

    @Override  
    public void Send() {  
        System.out.println("this is sms sender!");  
    }  
}  
public class SendMailFactory implements Provider {  

    @Override  
    public Sender produce(){  
        return new MailSender();  
    }  
} 
public class SendSmsFactory implements Provider{  

    @Override  
    public Sender produce() {  
        return new SmsSender();  
    }  
}  
public interface Provider {  
    public Sender produce();  
} 
public class Test {       
    public static void main(String[] args) {  
        Provider provider = new SendMailFactory();  
        Sender sender = provider.produce();  
        sender.Send();  
    }  
}

3)單例模式
單例對象(Singleton)是一種常用的設計模式。在Java應用中,單例對象能保證在一個JVM中,該對象只有一個實例存在。這樣的模式有幾個好處:
1、某些類創建比較頻繁,對於一些大型的對象,這是一筆很大的系統開銷。
2、省去了new操作符,降低了系統內存的使用頻率,減輕GC壓力。
3、有些類如交易所的核心交易引擎,控制着交易流程,如果該類可以創建多個的話,系統完全亂了。(比如一個軍隊出現了多個司令員同時指揮,肯定會亂成一團),所以只有使用單例模式,才能保證核心交易服務器獨立控制整個流程。

public class Singleton {    
    /* 持有私有靜態實例,防止被引用,此處賦值爲null,目的是實現延遲加載 */  
    private static Singleton instance = null;    
    /* 私有構造方法,防止被實例化 */  
    private Singleton() {  
    }    
    /* 靜態工程方法,創建實例 */  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}  

4)適配器模式
適配器模式將某個類的接口轉換成客戶端期望的另一個接口表示,目的是消除由於接口不匹配所造成的類的兼容性問題。主要分爲三類:類的適配器模式、對象的適配器模式、接口的適配器模式。
類的適配器模式:

public class Source {    
    public void method1() {  
        System.out.println("this is original method!");  
    }  
} 
public interface Targetable {     
    /* 與原類中的方法相同 */  
    public void method1();   
    /* 新類的方法 */  
    public void method2();  
} 
public class Adapter extends Source implements Targetable {  

    @Override  
    public void method2() {  
        System.out.println("this is the targetable method!");  
    }  
}  
public class AdapterTest {  

    public static void main(String[] args) {  
        Targetable target = new Adapter();  
        target.method1();  
        target.method2();  
    }  
}

5)裝飾器模式
顧名思義,裝飾模式就是給一個對象增加一些新的功能,而且是動態的,要求裝飾對象和被裝飾對象實現同一個接口,裝飾對象持有被裝飾對象的實例

public interface Sourceable {  
    public void method();  
}
public class Source implements Sourceable {  

    @Override  
    public void method() {  
        System.out.println("the original method!");  
    }  
}
public class Decorator implements Sourceable {  

    private Sourceable source;  

    public Decorator(Sourceable source){  
        super();  
        this.source = source;  
    }  
    @Override  
    public void method() {  
        System.out.println("before decorator!");  
        source.method();  
        System.out.println("after decorator!");  
    }  
} 
public class DecoratorTest {      
    public static void main(String[] args) {  
        Sourceable source = new Source();  
        Sourceable obj = new Decorator(source);  
        obj.method();  
    }  
}

裝飾器模式的應用場景:
1、需要擴展一個類的功能。
2、動態的爲一個對象增加功能,而且還能動態撤銷。(繼承不能做到這一點,繼承的功能是靜態的,不能動態增刪。)
缺點:產生過多相似的對象,不易排錯!
6)代理模式
代理模式就是多一個代理類出來,替原對象進行一些操作,比如我們在租房子的時候回去找中介,爲什麼呢?因爲你對該地區房屋的信息掌握的不夠全面,希望找一個更熟悉的人去幫你做,此處的代理就是這個意思。再如我們有的時候打官司,我們需要請律師,因爲律師在法律方面有專長,可以替我們進行操作,表達我們的想法

public interface Sourceable {  
    public void method();  
} 
public class Source implements Sourceable {  

    @Override  
    public void method() {  
        System.out.println("the original method!");  
    }  
} 
public class Proxy implements Sourceable {  

    private Source source;  
    public Proxy(){  
        super();  
        this.source = new Source();  
    }  
    @Override  
    public void method() {  
        before();  
        source.method();  
        atfer();  
    }  
    private void atfer() {  
        System.out.println("after proxy!");  
    }  
    private void before() {  
        System.out.println("before proxy!");  
    }  
}
public class ProxyTest {      
    public static void main(String[] args) {  
        Sourceable source = new Proxy();  
        source.method();  
    }    
}

7)策略模式
策略模式定義了一系列算法,並將每個算法封裝起來,使他們可以相互替換,且算法的變化不會影響到使用算法的客戶。需要設計一個接口,爲一系列實現類提供統一的方法,多個實現類實現該接口,設計一個抽象類(可有可無,屬於輔助類),提供輔助函數

public interface ICalculator {  
    public int calculate(String exp);  
} 
public abstract class AbstractCalculator {      
    public int[] split(String exp,String opt){  
        String array[] = exp.split(opt);  
        int arrayInt[] = new int[2];  
        arrayInt[0] = Integer.parseInt(array[0]);  
        arrayInt[1] = Integer.parseInt(array[1]);  
        return arrayInt;  
    }  
}  
public class Plus extends AbstractCalculator implements ICalculator {     
    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"\\+");  
        return arrayInt[0]+arrayInt[1];  
    }  
} 
public class Minus extends AbstractCalculator implements ICalculator {  

    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"-");  
        return arrayInt[0]-arrayInt[1];  
    }    
}
public class Multiply extends AbstractCalculator implements ICalculator {  

    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"\\*");  
        return arrayInt[0]*arrayInt[1];  
    }  
} 
public class StrategyTest {       
    public static void main(String[] args) {  
        String exp = "2+8";  
        ICalculator cal = new Plus();  
        int result = cal.calculate(exp);  
        System.out.println(result);  
    }  
}

8)模板方法模式
模板方法模式,就是指:一個抽象類中,有一個主方法,再定義1…n個方法,可以是抽象的,也可以是實際的方法,定義一個類,繼承該抽象類,重寫抽象方法,通過調用抽象類,實現對子類的調用

public abstract class AbstractCalculator {  

    /*主方法,實現對本類其它方法的調用*/  
    public final int calculate(String exp,String opt){  
        int array[] = split(exp,opt);  
        return calculate(array[0],array[1]);  
    }  

    /*被子類重寫的方法*/  
    abstract public int calculate(int num1,int num2);  

    public int[] split(String exp,String opt){  
        String array[] = exp.split(opt);  
        int arrayInt[] = new int[2];  
        arrayInt[0] = Integer.parseInt(array[0]);  
        arrayInt[1] = Integer.parseInt(array[1]);  
        return arrayInt;  
    }  
}  
public class Plus extends AbstractCalculator {  

    @Override  
    public int calculate(int num1,int num2) {  
        return num1 + num2;  
    }  
} 
public class StrategyTest {  

    public static void main(String[] args) {  
        String exp = "8+8";  
        AbstractCalculator cal = new Plus();  
        int result = cal.calculate(exp, "\\+");  
        System.out.println(result);  
    }  
}  

9)觀察者模式
觀察者模式很好理解,類似於郵件訂閱和RSS訂閱,當我們瀏覽一些博客或wiki時,經常會看到RSS圖標,就這的意思是,當你訂閱了該文章,如果後續有更新,會及時通知你。其實,簡單來講就一句話:當一個對象變化時,其它依賴該對象的對象都會收到通知,並且隨着變化!對象之間是一種一對多的關係

public interface Observer {  
    public void update();  
} 
public class Observer1 implements Observer {  

    @Override  
    public void update() {  
        System.out.println("observer1 has received!");  
    }  
}
public class Observer2 implements Observer {  

    @Override  
    public void update() {  
        System.out.println("observer2 has received!");  
    }  

} 
public interface Subject {  

    /*增加觀察者*/  
    public void add(Observer observer);  

    /*刪除觀察者*/  
    public void del(Observer observer);  

    /*通知所有的觀察者*/  
    public void notifyObservers();  

    /*自身的操作*/  
    public void operation();  
} 
public abstract class AbstractSubject implements Subject {  

    private Vector<Observer> vector = new Vector<Observer>();  
    @Override  
    public void add(Observer observer) {  
        vector.add(observer);  
    }  

    @Override  
    public void del(Observer observer) {  
        vector.remove(observer);  
    }  

    @Override  
    public void notifyObservers() {  
        Enumeration<Observer> enumo = vector.elements();  
        while(enumo.hasMoreElements()){  
            enumo.nextElement().update();  
        }  
    }  
} 
public class MySubject extends AbstractSubject {  

    @Override  
    public void operation() {  
        System.out.println("update self!");  
        notifyObservers();  
    }  

}  
public class ObserverTest {  

    public static void main(String[] args) {  
        Subject sub = new MySubject();  
        sub.add(new Observer1());  
        sub.add(new Observer2());           
        sub.operation();  
    }  

}  

資料來源:
http://blog.csdn.net/zhangerqing/article/details/8194653
http://blog.csdn.net/zhangerqing/article/details/8239539
http://blog.csdn.net/zhangerqing/article/details/8243942
http://blog.csdn.net/zhangerqing/article/details/8245537

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