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 几种行为型设计模式通道

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