Bootstrap

Android开发之——SOLID基础设计原则(掌握23种设计模式)其实开发之路如此简单

我们想要进阶Android 开发必须要掌握的就是SOLID,看这5个字母是不是挺唬人的,那么我们就来详细的展开讲讲到底什么是SOLID 以Android(JAVA语言)进行解读 SOLID

一、什么是SOLID

SOLID 是面向对象设计五大重要原则的首字母缩写,分别是
(S) Single Responsibility Principle(SRP):单一职责原则
一个类或者一个模块只做一件事。让一个类或者一个模块专注于单一的功能,减少功能之间的耦合程度。这样做在需要修改某个功能时,就不会影响到其他的功能。

(O) Open Closed Principle(OCP):开闭原则
对扩展开放,对修改关闭。一个类独立之后就不应该去修改它,而是以扩展的方式适应新需求。

(L) Liskov Substitution Principle(LSP):里氏替换原则
所有基类出现的地方都可以用派生类替换而不会让程序产生错误,派生类可以扩展基类的功能,但不能改变基类原有的功能。

(I) Interface Segregation Principle(ISP):接口隔离原则
一个接口应该拥有尽可能少的行为,使其精简单一。对于不同的功能的模块分别使用不同接口,而不是使用同一个通用的接口。

(D) Dependence Inversion Principle(DIP):依赖倒置原则
高级模块不应该依赖低级模块,而是依赖抽象接口,通过抽象接口使用对应的低级模块。

SOLID的23种设计模式

SOLID 有23种设计模式,23种设计模式又分为三种类型,创建型模式结构型模式行为型模式
创建型就是怎么创建对象的
结构型就是对象与对象的关系,变成更大的结构
行为型就是运行时复杂流程控制

1.创建型模式(1)——(12)

(1)单例模式(Singleton Pattern)

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象,也就是说不能使用new关键字来创建对象。
单例设计模式分类两种:
饿汉式:类加载就会导致该单实例对象被创建。
​ 懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建。
饿汉式

public class LoginBase {
   
 
   //创建 LoginBase 的一个对象
   private static LoginBase instance = new LoginBase();
 
   //让构造函数为 private,这样该类就不会被实例化
   private LoginBase(){
   }
 
   //获取唯一可用的对象
   public static LoginBase getInstance(){
   
      return instance;
   }

   public void showMessage(String message){
   
      Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
   }
}

懒汉式

public class LoginBase {
   
 
   //声明LoginBase 的一个对象
   private static LoginBase instance;
 
   //让构造函数为 private,这样该类就不会被实例化
   private LoginBase(){
   }
 
   //获取唯一可用的对象
   public static LoginBase getInstance(){
   
      if(instance==null){
   //双重锁定保证线程安全
            synchronized(LoginBase.class){
   
                if(instance==null)
                    instance=new Singleton();
            }
        }
      return instance;
   }

   public void showMessage(String message){
   
      Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
   }
}

(2)工厂模式(Factory Pattern)

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,它提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。
工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。
通过使用工厂模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。
下面是一个水果工厂类的演示

public class Apple implements FruitsInterFace{
   
    private String name = "";
    public Apple(String n){
   
        name = n;
    }

    @Override
    public void getFruits() {
   
        Log.v("Fruits","Apple");
    }
}
public class Banana implements FruitsInterFace{
   
    private String name = "";
    public Banana(String n){
   
        name = n;
    }

    @Override
    public void getFruits() {
   
        Log.v("Fruits","Banana");
    }
}
public class Orange implements FruitsInterFace{
   
    private String name = "";
    public Orange(String n){
   
        name = n;
    }

    @Override
    public void getFruits() {
   
        Log.v("Fruits","Orange");
    }
}

public interface FruitsInterFace {
   
    void getFruits();
}


public class FruitsFactory {
   
    public FruitsInterFace getFruits(String name){
   
        if(name == null){
   
            return null;
        }
        switch (name){
   
            case "Apple":
               return new Apple(name);
            case "Banana":
                return new Banana(name);
            case "Orange":
                return new Orange(name);
            default:
                return null;
        }
    }

}

调用

  		FruitsFactory fruitsFactory = new FruitsFactory();
        Apple apple = (Apple) fruitsFactory.getFruits("Apple");
        apple.getFruits();

(3)抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。

/**
 * X公司下有两个工厂,分别别是水果工厂和服装工厂
 */
public abstract class XCompanyFactory {
   
    //获取水果工厂
    public abstract FruitsInterFace getFruits(String name);

    //获取浮窗工厂
    public abstract ClothingFactory getClothing(String name);
}

public class XCompany extends XCompanyFactory{
   

    @Override
    public FruitsInterFace getFruits(String name) {
   
        switch (name){
   
            case "Apple":
                return new Apple(name);
            case "Banana":
                return new Banana(name);
            case "Orange":
                return new Orange(name);
            default:
                return null;
        }
    }

    @Override
    public ClothingFactory getClothing(String name) {
   
        return null;
    }
}
		XCompany xCompany = new XCompany();
        Banana banana = (Banana)xCompany.getFruits("Banana");
        banana.getFruits();

(4)原型模式(Prototype Pattern)

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
用原型实例指定要创建对象的种类,并通过拷贝这些原型创建新的对象。
其实主要就是实现了Cloneable 接口
实战


public abstract class Fruits implements Cloneable {
   
    private String id;
    private String type;

    public String getId() {
   
        return id;
    }

    public void setId(String id) {
   
        this.id = id;
    }

    public String getType() {
   
        return type;
    }

    public void setType(String type) {
   
        this.type = type;
    }

    public Object clone(){
   
        Object clone = null;
        try {
   
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
   
            e.printStackTrace();
        }
        return clone;
    }
}

public class Apple extends Fruits implements FruitsInterFace{
   
    private String name = "";
    public Apple(String n){
   
        name = n;
    }

    @Override
    public void getFruits() {
   
        Log.v("Fruits","Apple");
    }
}

public class Banana extends Fruits implements FruitsInterFace{
   
    private String name = "";
    public Banana(String n){
   
        name = n;
    }

    @Override
    public void getFruits() {
   
        Log.v("Fruits","Banana");
    }
}

public class Orange extends Fruits implements FruitsInterFace{
   
    private String name = "";
    public Orange(String n){
   
        name = n;
    }

    @Override
    public void getFruits() {
   
        Log.v("Fruits","Orange");
    }
}


public class FruitsCache {
   
    private static Hashtable<String,Fruits> shareMap = new Hashtable<>();

    public static Fruits getFruits(String fruitId){
   
        Fruits cachedFruit = shareMap.get(fruitId);
        return (Fruits) cachedFruit.clone();
    }

    // 对每种形状都运行数据库查询,并创建该形状
    // shapeMap.put(shapeKey, shape);
    // 例如,我们要添加三种形状
    public static void loadCache() {
   
        Apple apple = new Apple("Apple");
        apple.setId("1");
        shareMap.put(apple.getId(),apple);

        Banana banana = new Banana("Banana");
        banana.setId("2");
        shareMap.put(banana.getId(),banana);

        Orange orange = new Orange("Orange");
        orange.setId("3");
        shareMap.put(orange.getId(),orange);
    }
}
FruitsCache.loadCache();
Apple apple1 = (Apple) FruitsCache.getFruits("1");
apple1.getFruits();
Apple apple2 = (Apple) FruitsCache.getFruits("1");
apple2.getFruits();
apple1.setName("大苹果");
apple2.setName("小苹果");
Log.v("apple1",apple1.getName());
Log.v("apple2",apple2.getName());

输出如下
在这里插入图片描述

(5)建造者模式(Builder Pattern)

建造者模式是一种创建型设计模式,它允许你创建复杂对象的步骤与表示方式相分离。
建造者模式是一种创建型设计模式,它的主要目的是将一个复杂对象的构建过程与其表示相分离,从而可以创建具有不同表示形式的对象。
使用场景
相同的方法,不同的执行顺序,产生不同的事件结果时;
多个部件或者零件,都可以装配到一个对象中,但产生的运行结果又不相同时;
产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用时;
当初始化一个对象特别复杂,比如参数多,且有很多参数具有默认值时;
举个例子吧


public class Student {
   
    private String name;
    private String age;
    private String sex;
    private Student(Builder builder){
   
        name = builder.name;
        age = builder.age;
        sex = builder.sex;
    }
    public static final class Builder{
   
        public String name;
        public String age;
        public String sex;

        public Student build(){
   
            return new Student(this);
        }

        public Student.Builder addName(String v){
   
            name = v;
            return this;
        }

        public Student.Builder addAge(String v){
   
            age = v;
            return this;
        }
        
        public Student.Builder addSex(String v
;