Android 幾種創建型設計模式

目錄

​​​​​​1.單例模式 (推薦使用懶漢和DCL模式)

2.Builder模式

3.原型模式

4.工廠方法模式

5.抽象工廠模式


1.單例模式 (推薦使用懶漢和DCL模式)

//懶漢單例
public class Singleton {
    private static Singleton mInstance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (mInstance == null) {
            mInstance = new Singleton();
        }
        return mInstance;
    }
}

//DCL單例
public class Singleton {
    private volatile static Singleton mInstance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (mInstance == null) {
            synchronized (Singleton.class) {
                if (mInstance == null) {
                    mInstance = new Singleton();
                }
            }
        }
        return mInstance;
    }
}

//靜態內部類單例
public class Singleton {
    private volatile static Singleton mInstance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.mInstance;
    }
    
    private static class SingletonHolder {
        private static final Singleton mInstance = new Singleton();
    }
}

//枚舉單例
public enum SingletonEnum {
    INGLETON;
}

//使用容器實現單例
public class SingletonManager {
    private static Map<String,Object> objMap = new HashMap<>();

    private SingletonManager() {
    }
    
    public static void registerService(String key,Object instance) {
        if (!objMap.containsKey(key)) {
            objMap.put(key,instance);
        }
    }

    public static Object getService(String key) {
        return objMap.get(key);
    }
}

2.Builder模式

//女朋友配置類 避免目標類中有過多的接口
public class GirlFriendConfig {
    /**
     * 姓名 年齡 身高
     */
    String name = "未知";
    int age;
    int height = 165;

    private GirlFriendConfig() {
    }

    public static class Builder {
        String name;
        int age;
        int height;

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setAge(int age) {
            this.age = age;
            return this;
        }

        public Builder setHeight(int height) {
            this.height = height;
            return this;
        }

        private void applyConfig(GirlFriendConfig config) {
            config.name = this.name;
            config.age = this.age;
            config.height = height;
        }

        public GirlFriendConfig create() {
            GirlFriendConfig config = new GirlFriendConfig();
            applyConfig(config);
            return config;
        }
    }
}

//女朋友
public class GirlFriend {

    private final static String TAG = "GirlFriend";
    private static GirlFriend mInstance;

    private GirlFriendConfig mConfig;

    private GirlFriend() {
    }

    public static GirlFriend getInstance() {
        if (mInstance == null) {
            mInstance = new GirlFriend();
        }
        return mInstance;
    }

    public void init(GirlFriendConfig config) {
        this.mConfig = config;
    }

    public void showGirlFriend() {
        Log.w(TAG, "姓名:" + mConfig.name + "/年齡:" + mConfig.age == null ? "保密" : mConfig.age + "/身高:" + mConfig.height);
    }

    public void dissGirlFriend() {
        Log.w(TAG,"diss? 想都不要想");
    }
}
//您的女朋友
private void newGirlFriend() {
        GirlFriendConfig config = new GirlFriendConfig.Builder()
                .setName("古力娜扎")
                .setHeight(172)
                .create();
        GirlFriend.getInstance().init(config);
        GirlFriend.getInstance().showGirlFriend();
        GirlFriend.getInstance().dissGirlFriend();
}

3.原型模式

1.實際上就是對象的拷貝。原型模式多用於創建複雜的或者構造消耗時實例,在這種情況下,複製一個已經存在的實例可使程序運行更高效。
2.通過實現 Cloneable 重寫 clone()方法實現(分爲深拷貝和淺拷貝)

淺拷貝:調用 java.lang.Object的clone()方法
public class Address{
    private String city;
    private String area;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }
}


public class User implements Cloneable {

    private String name;
    private Address address;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        User user = (User) super.clone();

        return user;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public void showMessage() {
        System.out.println(name.hashCode());
        System.out.println(name);
        System.out.println(address.hashCode());
        System.out.println(address.getCity() + address.getArea());
    }
}

public class Test {

    public static void main(String[] args) throws CloneNotSupportedException {

        User originUser = new User();
        originUser.setName("小明");
        Address address = new Address();
     	address.setCity("廣州");
        address.setArea("天河區");
        originUser.setAddress(address);


        System.out.println("---------第一次原對象----------");
        originUser.showMessage();

        User copyUser = (User) originUser.clone();
        copyUser.setName("小紅");
        copyUser.getAddress().setCity("深圳");
        copyUser.getAddress().setArea("寶安區");
        System.out.println("---------複製對象----------");
        copyUser.showMessage();

        System.out.println("---------再次原對象----------");
        originUser.showMessage();

    }
}

運行打印日誌:
---------第一次原對象----------
756703
小明
791452441
廣州天河區
---------複製對象----------
762995
小紅
791452441
深圳寶安區
---------再次原對象----------
756703
小明
791452441
深圳寶安區


深拷貝:
(1)對象內部所有引用型對象都實現Cloneable重寫clone()
public class Address implements Cloneable{
    private String city;
    private String area;
    
    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class User implements Cloneable {

    private String name;
    private Address address;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        User user = (User) super.clone();
        //注意這裏
        user.address = (Address) address.clone();
        return user;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public void showMessage() {
        System.out.println(name.hashCode());
        System.out.println(name);
        System.out.println(address.hashCode());
        System.out.println(address.getCity() + address.getArea());
    }
}

運行打印日誌:
---------第一次原對象----------
756703
小明
791452441
廣州天河區
---------複製對象----------
762995
小紅
834600351
深圳寶安區
---------再次原對象----------
756703
小明
791452441
廣州天河區

(2)對象序列化
public class User implements Cloneable, Serializable {

    private String name;
    private Address address;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public User deepClone() { // 使用序列化和反序列化實現深複製
        //略
        return null;

    }
    
    public void showMessage() {
        System.out.println(name.hashCode());
        System.out.println(name);
        System.out.println(address.hashCode());
        System.out.println(address.getCity() + address.getArea());
    }
}

運行打印日誌:
---------第一次原對象----------
756703
小明
791452441
廣州天河區
---------複製對象----------
762995
小紅
834600351
深圳寶安區
---------再次原對象----------
756703
小明
791452441
廣州天河區

3.用途,例如:
(1)循環體內產生大量對象
(2)保護性拷貝,如不允許修改的登錄後的用戶信息
(3)其他

4.注意:通過clone拷貝的對象不會執行構造方法。

4.工廠方法模式

(1)簡單工廠模式

//抽象產品類 - 朋友
public abstract class Friend {

    /**
     * 產品類的抽象方法
     * 具體由產品類去實現 
     */
    public abstract void message();
}

//具體產品類 男朋友
public class BoyFriend extends Friend {
    
    @Override
    public void message() {
        System.out.println("我是男朋友");
    }
}

//具體產品類 女朋友
public class GirlFriend extends Friend{

    @Override
    public void message() {
        System.out.println("我是女朋友");
    }
}

//抽象工廠類 
public abstract class Factory {

    /**
     * 抽象工廠方法
     * 具體生產什麼由子類去實現 
     * @return 具體的產品對象
     */
    public abstract Friend createFriend();
}

//具體工廠類
public class FriendFactory extends Factory {

    @Override
    public Friend createFriend() {
        //需要什麼朋友就new什麼朋友
        return new GirlFriend();
        //return new BoyFriend();
    }

}

//生產使用
public void newFriend() {
    Factory factory = new FriendFactory();
    Friend friend = factory.createFriend();
    friend.message();
}

(2)多工廠模式 (爲每一個產品都定義一個具體的工廠)

//生產男朋友的工廠
public class BoyFriendFactory extends Factory{

    @Override
    public Friend createFriend() {
        return new BoyFriend();
    }
}

//生產女朋友的工廠
public class GirlFriendFactory extends Factory{

    @Override
    public Friend createFriend() {
        return new GirlFriend();
    }
}

//生產使用
public static void newFriend() {
    Factory girlFriendFactory = new GirlFriendFactory();
    Friend girlFriend = girlFriendFactory.createFriend();
    girlFriend.message();

    Factory boyFriendFactory = new BoyFriendFactory();
    Friend boyFriend = boyFriendFactory.createFriend();
    boyFriend.message();
}

(3)利用反射的方式更簡潔地生產具體產品對象

public abstract class Factory {

    public abstract <T extends Friend>  T createFriend(Class<T> clz);
}

public class FriendFactory extends Factory {

    @Override
    public <T extends Friend> T createFriend(Class<T> clz) {
        Friend friend = null;
        try {
            friend = (Friend) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) friend;
    }
}

//生產使用
public void newFriend() {
    Factory factory = new FriendFactory();
    Friend friend = factory.createFriend(GirlFriend.class);
    friend.message();
}

(4)如果可以確定工廠類只有一個,那麼可以選擇簡化掉抽象類,只需把工廠方法改爲靜態方法

public class Factory {
    
    public static Friend createFriend();
}

5.抽象工廠模式

爲創建一組相關或者相互依賴的對象提供一個接口,而不需要指定它們的具體類。

//男朋友相關類
public interface IBoyFriend {

    void showBoyFriend();
}

//具體產品類A款男朋友
public class BoyFriendA implements IBoyFriend {

    @Override
    public void showBoyFriend() {
        System.out.println("A款男朋友");
    }
}

//具體產品類B款男朋友
public class BoyFriendB implements IBoyFriend {

    @Override
    public void showBoyFriend() {
        System.out.println("B款男朋友");
    }
}

//女朋友相關類
public interface IGirlFriend {

    void showGirlFriend();
}

//具體產品類A款女朋友
public class GirlFriendA implements IGirlFriend{

    @Override
    public void showGirlFriend() {
        System.out.println("A款女朋友");
    }
}

//具體產品類B款女朋友
public class GirlFriendB implements IGirlFriend{

    @Override
    public void showGirlFriend() {
        System.out.println("B款女朋友");
    }
}

//抽象工廠類 - 能夠生產男朋友和女朋友
public abstract class Factory {

    public abstract IBoyFriend createBoyFriend();

    public abstract IGirlFriend createGirlFriend();
}

//具體工廠類1 看需求生產男女朋友款式
public class FriendFactory1 extends Factory{
    @Override
    public IBoyFriend createBoyFriend() {
        return new BoyFriendA();
    }

    @Override
    public IGirlFriend createGirlFriend() {
        return new GirlFriendA();
    }
}

//具體工廠類2 看需求生產男女朋友款式
public class FriendFactory2 extends Factory{
    @Override
    public IBoyFriend createBoyFriend() {
        return new BoyFriendA();
    }

    @Override
    public IGirlFriend createGirlFriend() {
        return new GirlFriendB();
    }
}

//使用生產
public static void newFriend() {
    //讓工廠1生產他們的男朋友和女朋友
    System.out.println("工廠1 生產:");
    Factory factory1 = new FriendFactory1();
    factory1.createBoyFriend().showBoyFriend();
    factory1.createGirlFriend().showGirlFriend();

    //讓工廠2生產他們的男朋友和女朋友
    System.out.println("工廠2 生產:");
    Factory factory2 = new FriendFactory2();
    factory2.createBoyFriend().showBoyFriend();
    factory2.createGirlFriend().showGirlFriend();
}

打印日誌:
工廠1 生產:
A款男朋友
A款女朋友
工廠2 生產:
A款男朋友
B款女朋友

PS :Android 幾種行爲型設計模式通道

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