常用設計模式通俗易懂

一、簡單工廠模式

簡單工廠模式又叫靜態工廠方法模式,他定義一個具體的工廠類負責創建一些類的實例。
優點:客戶端不需要在負責對象的創建,從而明確了各個類的職責。
缺點:這個具體的工廠類要負責所有類的對象的創建,如果有新的對象增加或者某些類的創建方式不同,就需要不斷的修改這個工廠類,不利於後期的維護和擴展。
下面我們通過代碼通俗易懂的瞭解一下:

//抽象動物類
public abstract class Animal {
    public abstract void eat();
}

//狗類
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }
}

//貓類
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("貓吃魚");
    }
}

以上內容和簡單工廠方法本身沒有太大的關聯,重點在下一個動物工廠類

//動物工廠類
public class AnimalFactory {
    //構造方法私有就只能通過靜態方法創建對象了
    private AnimalFactory(){}
    public static Animal createAnimal(String type){
        if("dog".equals(type)){
            return new Dog();
        }else if("cat".equals(type)){
            return new Cat();
        }else{
            return null;
        }
    }
}
//測試類
public class Test {
    public static void main(String[] args) {
        Animal a=AnimalFactory.createAnimal("cat");
        a.eat();//貓吃魚
        a=AnimalFactory.createAnimal("dog");
        a.eat();//狗吃肉
    }
}

那麼可以看到,我們要創建狗或貓的對象,不用去找狗或者貓,找動物工廠就可以幫我們造出相應的對象,那如果我還想要獅子、老虎、鱷魚、斑馬這些動物,就要不停的改寫動物工廠類裏面createAnimal()這個方法,很顯然,這樣做非常不利於維護和擴展,不符合面向對象設計原則裏面的開閉原則。

二、工廠方法模式

工廠方法模式就是爲了彌補簡單工廠模式的不足而設計的。工廠方法模式中抽象工廠類或者工廠接口負責定義創建對象的接口,具體對象的創建工作由抽象工廠類和工廠接口的具體實現類來完成。工廠方法模式和簡單工廠模式的區別顯而易見:工廠方法模式工廠類或接口並不負責創建對象,他是一個抽象的,具體的創建工作有抽象工廠的實現類來負責,而簡單工廠模式工廠類是具體的,他要實實在在的的負責創建對象,那肯定很辛苦了,前者抽象工廠是老大,創建對象的事情小弟去做就行了。

//抽象動物類
public abstract class Animal {
    public abstract void eat();
}

//狗類
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }
}

//貓類
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("貓吃魚");
    }
}

以上內容和工廠方法模式本身沒有太大的關聯,重點在下一個抽象工廠接口

//抽象工廠
public interface Factory {
    public abstract Animal createAnimal();
}

//狗工廠
public class DogFactory implements Factory {
    @Override
    public Animal createAnimal() {
        return new Dog();
    }
}

//貓工廠
public class CatFactory implements Factory {
    @Override
    public Animal createAnimal() {
        return new Cat();
    }
}

//測試類
public class Test {
    public static void main(String[] args) {
        Factory f=new DogFactory();
        Animal a=f.createAnimal();
        a.eat();//狗吃肉

        f=new CatFactory();
        a=f.createAnimal();
        a.eat();//貓吃魚
    }
}

如果這個時候我們還想要老虎獅子等更多的動物,那就只需要增加相關的老虎工廠、獅子工廠就可以了,而不需要在改動抽象工廠。

三、單例模式

單例模式:保證類在內存中只有一個對象
如何保證類在內存中只有一個該類的對象:
(1)把構造方法私有,這樣外界就不能通過構造方法創建對象
(2)在成員位置創建一個自己的對象(私有)
(3)通過公共方法提供訪問
單例模式分爲餓漢式和懶漢式,所謂餓漢式就是指類一加載就創建對象,懶漢式是指用的時候再創建對象。
1、餓漢式單例

public class Student {
    private Student(){}//構造私有
    private static Student s=new Student();//成員位置的私有對象
    public static Student getStudent(){//對外提供公共的訪問方法
        return s;
    }
}

餓漢式單例的對象在類一加載就會創建,不存在線程安全問題,可以保證在內存中只存在一個實例。

2、懶漢式單例

public class Teacher {
    private Teacher(){}//構造私有
    private static Teacher t=null;//成員位置的對象
    public static synchronized Teacher getTeacher(){//對外提供公共訪問方法
        if(t==null){
            t=new Teacher();
        }
        return t;
    }
}

這是懶漢式單例,由於懶漢式單例在多線程環境下可能存在同步問題,所以加上synchronized關鍵字可以保證線程安全,但是如果這樣的話,每個線程需要獲取對象的時候都要獲取鎖,如果獲取不到就要阻塞,無形之間降低了併發的效率,所以我們可以嘗試降低鎖的粒度,如下:

public class Teacher {
    private Teacher(){}//構造私有
    private static Teacher t=null;//成員位置的對象
    public static  Teacher getTeacher(){//對外提供公共訪問方法
        if(t==null){
            synchronized(Teacher.class){
                t=new Teacher();
            }
        }
        return t;
    }
}

這樣如果對象已經存在的話,就不需要再進入臨界區了。

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