读书笔记——《Android进阶之光》

Android进阶之光——设计模式(设计模式的分类、创建型设计模

2021-08-25  本文已影响0人  So_ProbuING

设计模式六大原则

设计模式分类

创建型设计模式

单例模式

单例模式的6种写法

/**
 * 单例模式 
 * 饿汉模式
 */
class SingletonHungry{
    private static SingletonHungry instance = new SingletonHungry();
    private SingletonHungry(){}
    public static SingletonHungry getInstance(){
        return instance;
    }
}

这种方式在类加载时就完成了初始化,所以类加载比较慢。但是这种方式基于类加载机制,避免了多线程同步问题。在类加载的时候就完成实例化,没有达到懒加载的效果。会造成内存的浪费

class SingletonLazyNoSafe(){
    private static SingletonLazyNoSafe instance;

    private SingletonLazyNoSafe() {
        
    }

    public static SingletonLazyNoSafe getInstance() {
        if (instance == null) {
            instance = new SingletonLazyNoSafe();
        }
        return instance;
    }
}

懒汉式声明了一个静态对象,在用户第一次调用时初始化,节约了资源,但第一次加载时需要实例化。而且在存在线程安全问题

class SingletonLazySafe {
    private static SingletonLazySafe instance = null;
    private SingletonLazySafe(){}

    public static SingletonLazySafe getInstance() {
        if (instance == null) {
            synchronized (instance) {
                if (instance == null) {
                instance = new SingletonLazySafe();
                }
            }
        }
        return instance;
    }
}

这种写法在getInstance种对Singleton实例进行了两次判空:第一次是为了不必要的同步第二次是在Singleton等于null的时候才创建实例。这里使用volatile会或多或少地影响性能。DCL的优点是资源利用率高,效率高。缺点是第一次加载时反应慢,DCL在某些情况下会出现失效的问题,也就是DCL失效。

class SingletonInner {
    private static SingletonInner instance = null;
    private SingletonInner() {
        
    }

    public static SingletonInner getInstance() {
        return SingletonInner.Holder.holderInstance;
    }

    private static class Holder {
        public static SingletonInner holderInstance = new SingletonInner();
          }
}

第一次加载Singleton类时并不会初始化holderInstance,只有第一次调用getInstance方法时虚拟机加载SingletonHolder并初始化holderInstance,因此比较推荐使用静态内部类的单例模式


enum SingletonEnum {
    INSTANCE;
    public void someMethod() {
    }
}

单例模式的使用场景

简单工厂模式

简单工厂模式(静态工厂方法模式)

简单工厂模式的实现

假设有一个计算机的代工生产商,它目前已经可以代工生产联想计算机了。随着业务的拓展,这个代工生产商还要生产惠普和华硕的计算机。 这样我们就需要用一个单独的类来专门生产计算机,这就用到了简单工厂模式。

/**
 * 简单工厂模式
 */
public class SimpleFactoryType {
    public static void main(String[] args) {
        ComputerFactory.createComputer("hp").start();
    }
}

/**
 * 抽象产品类
 */
abstract class Computer {
    /**
     * 产品抽象方法,启动计算机
     */
    abstract void start();
}

/**
 * 具体产品类
 */
class LenvooComputer extends Computer {

    @Override
    void start() {
        System.out.println("lenovo start");
    }
}

class HPComputer extends Computer {

    @Override
    void start() {
        System.out.println("HP start");
    }
}

class ASUSComputer extends Computer {

    @Override
    void start() {
        System.out.println("ASUS start");
    }
}

class ComputerFactory {
    public static Computer createComputer(String type) {
        Computer mComputer = null;
        switch (type) {
            case "lenovo":
                mComputer = new LenvooComputer();
                break;
            case "hp":
                mComputer = new HPComputer();
                break;
            case "asus":
                mComputer = new ASUSComputer();
                break;
        }
        return mComputer;
    }
}

简单工厂模式的使用场景

优点

用户可以根据参数获得对应的类实例。避免直接实例化类,降低了耦合性

缺点

可实例化的类型在编译期间就已经被确定。如果增加新类型,则需要修改工厂,违背了开放封闭原则。简单工厂需要知道所有的要生产的类型

工厂方法模式

在工厂方法模式种有如下角色:

/**
 * 工厂方法模式
 */
public class FactoryMethodType {
    public static void main(String[] args) {
        GDComputerFactor computerFactor = new GDComputerFactor();
        computerFactor.createComputerABS(HPComputerABS.class).start();
    }
}
/**
 * 抽象产品类
 */
abstract class ComputerABS {
    /**
     * 产品抽象方法,启动计算机
     */
    abstract void start();
}
/**
 * 具体产品类
 */
class LenvooComputerABS extends ComputerABS {

    @Override
    void start() {
        System.out.println("lenovo start");
    }
}

class HPComputerABS extends ComputerABS {

    @Override
    void start() {
        System.out.println("HP start");
    }
}

class ASUSComputerABS extends ComputerABS {

    @Override
    void start() {
        System.out.println("ASUS start");
    }
}

/**
 * 抽象工厂,返回抽象的产品
 */
abstract class  ComputerFactoryABS{
    public abstract <T extends ComputerABS> T createComputerABS(Class<T> cls);
}

class GDComputerFactor extends ComputerFactoryABS {

    @Override
    public <T extends ComputerABS> T createComputerABS(Class<T> cls) {
        ComputerABS computerABS = null;
        String clsName = cls.getName();
        try {
            computerABS = ((ComputerABS) Class.forName(clsName).newInstance());
        } catch (IllegalAccessException | InstantiationException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) computerABS;
    }
}

建造者模式

建造者模式也被称为生成器模式,它是创建一个复杂对象的创建型模式,其将构建复杂对象的过程和它的部件解耦。使得构建过程和部件表示分离开来。例如我们要 DIY 一台台式计
算机。 我们找到 DIY 商家。这时我们可以要求这台计算机的 CPU、 主板或者其他部件都是什么牌子的、 什么配置的,这些部件是我们可以根据自己的需求来变化的。 但是这些部件组装成计算机的过程是一样的,我们无须知道这些部件是怎样组装成计算机的,我们只需要提供相关部件的牌子和配置就可以了。对于这种情况我们就可以采用建造者模式,将部件和组装过程分离,使得构建过程和部件都可以自由拓展,两者之间的耦合也降到最低。

建造者模式的简单实现

public class BuilderTypeLSN {
    public static void main(String[] args) {
        ApplePhoneBuilder phoneBuilder = new ApplePhoneBuilder();
        Director director = new Director(phoneBuilder);
        Phone phone = director.createPhone("aaa", "b", "c");
    }
}

class Phone {
    private String mCPU;
    private String mMainboard;
    private String mRam;

    public void setmCPU(String mCPU) {
        this.mCPU = mCPU;
    }

    public void setmMainboard(String mMainboard) {
        this.mMainboard = mMainboard;
    }

    public void setmRam(String mRam) {
        this.mRam = mRam;
    }
}

abstract class Builder{
    abstract void buildCPU(String cpuName);

    abstract void buildMainboard(String boardName);

    abstract void buildRam(String ram);

    abstract Phone createPhone();
}

class ApplePhoneBuilder extends Builder {
    Phone phone = new Phone();
    @Override
    void buildCPU(String cpuName) {
        phone.setmCPU(cpuName);
    }

    @Override
    void buildMainboard(String boardName) {
        phone.setmMainboard(boardName);
    }

    @Override
    void buildRam(String ram) {
        phone.setmRam(ram);
    }

    @Override
    Phone createPhone() {
        return phone;
    }
}

class Director {
    Builder mBuilder = null;

    public Director(Builder mBuilder) {
        this.mBuilder = mBuilder;
    }

    public Phone createPhone(String cpu, String board, String ram) {
        mBuilder.buildCPU(cpu);
        mBuilder.buildMainboard(board);
        mBuilder.buildRam(ram);
        return mBuilder.createPhone();
    }
    
}

使用建造者的场景和优缺点

上一篇下一篇

猜你喜欢

热点阅读