Android日积月累系列之九-设计模式-创建型模式

103 阅读8分钟

java设计模式

1.六大原则

1.1单一职责原则

1.2接口隔离原则

1.3依赖倒转原则

1.4里氏替换原则

1.5开闭原则 ocp

1.6迪米特法则

2.设计模式类型分类

2.1 创建型模式5种:

单例模式工厂模式,抽象工厂模式,原型模式,建造者模式

2.2 结构型模式七种:

适配器模式,桥接模式,装饰模式,组合模式,外观模式/门面模式,享元模式,代理模式

2.3 行为型模式11种

模板方法模式,命令模式,访问者模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式(Interpreter模式),状态模式,策略模式,职责链模式(责任链模式)

3.创建型模式

3.1单例模式 Singleton Pattern

**意图:**保证一个类仅有一个实例,并提供一个访问它的全局访问点。

**主要解决:**一个全局使用的类频繁地创建与销毁。

**何时使用:**当您想控制实例数目,节省系统资源的时候。

**如何解决:**判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

**关键代码:**构造函数是私有的。

3.1.1 饿汉式

//1.饿汉式-静态变量初始化时实例化对象
class HungryStaticProperty {

    //1. 构造器私有化, 外部不能new
    private HungryStaticProperty() {
    }

    //2.本类内部创建对象实例
    private final static HungryStaticProperty instance = new HungryStaticProperty();

    //3. 提供一个公有的静态方法,返回实例对象
    public static HungryStaticProperty getInstance() {
        return instance;
    }
}

//2.饿汉式-静态变量-静态代码块里实例化
class HungryStaticCodeBlock {

    //1. 构造器私有化, 外部能new
    private HungryStaticCodeBlock() {
    }

    //2.本类内部创建对象实例
    private static HungryStaticCodeBlock instance;

    static {
        instance = new HungryStaticCodeBlock();
    }

    //3. 提供一个公有的静态方法,返回实例对象
    public static HungryStaticCodeBlock getInstance() {
        return instance;
    }
}

3.1.2 懒汉式

//3.懒汉式-synchronized同步创建方法,缺点是每一次getInstance()都要同步,效率低
class LazySynchronized {
    private static LazySynchronized instance;

    private LazySynchronized() {}

    //提供一个静态的公有方法,加入同步处理的代码,解决线程安全问题
    //即懒汉式
    public static synchronized LazySynchronized getInstance() throws InterruptedException {
        if(instance == null) {
            instance = new LazySynchronized();
        }
        return instance;
    }
}


//4.懒汉式-双重检查,解决每次都要synchronized的问题,重点volatile,线程可见性。
class LazyDoubleCheck {
    private static volatile LazyDoubleCheck instance;

    private LazyDoubleCheck() {}

    //提供一个静态的公有方法,加入同步处理的代码,解决线程安全问题
    //即懒汉式
    public static LazyDoubleCheck getInstance() throws InterruptedException {
        if(instance == null) {
            synchronized (LazyDoubleCheck.class) {
                if(instance == null) {
                    instance = new LazyDoubleCheck();
                }
            }
        }
        return instance;
    }
}

//5.静态内部类完成, 推荐使用-
class StaticInnerClasses {
    private static volatile StaticInnerClasses instance;

    static {
        System.out.println("外部类加载");
    }

    //构造器私有化
    private StaticInnerClasses() {}

    //写一个静态内部类,该类中有一个静态属性 Singleton
    private static class SingletonInstance {
        static {
            System.out.println("静态内部类加载");
        }
        //类加载时初始化,而且由类加载器保证初始化一次。
        private static final StaticInnerClasses INSTANCE = new StaticInnerClasses();
    }

    //提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
    public static StaticInnerClasses getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

3.1.3 枚举实现单例

//6.使用枚举,可以实现单例, 推荐
enum EnumSingleton {
    INSTANCE; //属性
    public void sayOK() {
        System.out.println("ok~");
    }
}

3.1.4 kotlin里实现单例

object KotlinSingleton {
    fun helloWorld() {
        println("Hello world")
    }
}


class KotlinLazySingleton private constructor(var age: Int) {
    init {
        println("KotlinLazySingleton")
    }

    companion object {
        val instance: KotlinLazySingleton by lazy {
            println("KotlinLazySingleton by lazy")
            KotlinLazySingleton(10)
        }
    }
}

//构造函数带参的单例
class SingletonSecond private constructor(var age: Int = 0) {

    fun getLastAge() = age

    init {
        println("SingletonSecond init")
    }

    companion object {

        @Volatile
        private var INSTANCE: SingletonSecond? = null
        fun getInstance(): SingletonSecond {
            return INSTANCE ?: synchronized(this) {
                val instance = SingletonSecond(18)
                INSTANCE = instance
                instance
            }
        }
    }
}

3.1.4 android sdk里的单例模式

getSystemService的实现是一个单例模式

val s1 = getSystemService(Context.ACTIVITY_SERVICE)
val s2 = getSystemService(Context.ACTIVITY_SERVICE)
val s3 = getSystemService(Context.ACTIVITY_SERVICE)

跟踪代码,会发现最后是在一个静态代码块里配置好如何创建一个实例并缓存,属于懒加载。

package android.app;

final class SystemServiceRegistry {
    private static final String TAG = "SystemServiceRegistry";

    // Service registry information.
    // This information is never changed once static initialization has completed.
    private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
            new HashMap<Class<?>, String>();
    private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new HashMap<String, ServiceFetcher<?>>();
    private static int sServiceCacheSize;

    // Not instantiable.
    private SystemServiceRegistry() { }

    static {
        registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
                new CachedServiceFetcher<AccessibilityManager>() {
            @Override
            public AccessibilityManager createService(ContextImpl ctx) {
                return AccessibilityManager.getInstance(ctx);
            }});

        registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class,
                new CachedServiceFetcher<CaptioningManager>() {
            @Override
            public CaptioningManager createService(ContextImpl ctx) {
                return new CaptioningManager(ctx);
            }});

        ...略
    }

    private static <T> void registerService(String serviceName, Class<T> serviceClass,
            ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }
    
    /**
     * Gets a system service from a given context.
     */
    public static Object getSystemService(ContextImpl ctx, String name) {
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;
    }
}


static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
    private final int mCacheIndex;

    CachedServiceFetcher() {
        // Note this class must be instantiated only by the static initializer of the
        // outer class (SystemServiceRegistry), which already does the synchronization,
        // so bare access to sServiceCacheSize is okay here.
        mCacheIndex = sServiceCacheSize++;
    }

    @Override
    @SuppressWarnings("unchecked")
    public final T getService(ContextImpl ctx) {
        final Object[] cache = ctx.mServiceCache;
        final int[] gates = ctx.mServiceInitializationStateArray;

        for (;;) {
            boolean doInitialize = false;
            synchronized (cache) {
                // Return it if we already have a cached instance.
                T service = (T) cache[mCacheIndex];
                if (service != null || gates[mCacheIndex] == ContextImpl.STATE_NOT_FOUND) {
                    return service;
                }

                // If we get here, there's no cached instance.

                // Grr... if gate is STATE_READY, then this means we initialized the service
                // once but someone cleared it.
                // We start over from STATE_UNINITIALIZED.
                if (gates[mCacheIndex] == ContextImpl.STATE_READY) {
                    gates[mCacheIndex] = ContextImpl.STATE_UNINITIALIZED;
                }

                // It's possible for multiple threads to get here at the same time, so
                // use the "gate" to make sure only the first thread will call createService().

                // At this point, the gate must be either UNINITIALIZED or INITIALIZING.
                if (gates[mCacheIndex] == ContextImpl.STATE_UNINITIALIZED) {
                    doInitialize = true;
                    gates[mCacheIndex] = ContextImpl.STATE_INITIALIZING;
                }
            }

            if (doInitialize) {
                // Only the first thread gets here.

                T service = null;
                @ServiceInitializationState int newState = ContextImpl.STATE_NOT_FOUND;
                try {
                    // This thread is the first one to get here. Instantiate the service
                    // *without* the cache lock held.
                    service = createService(ctx);
                    newState = ContextImpl.STATE_READY;

                } catch (ServiceNotFoundException e) {
                    onServiceNotFound(e);

                } finally {
                    synchronized (cache) {
                        cache[mCacheIndex] = service;
                        gates[mCacheIndex] = newState;
                        cache.notifyAll();
                    }
                }
                return service;
            }
            // The other threads will wait for the first thread to call notifyAll(),
            // and go back to the top and retry.
            synchronized (cache) {
                while (gates[mCacheIndex] < ContextImpl.STATE_READY) {
                    try {
                        cache.wait();
                    } catch (InterruptedException e) {
                        Log.w(TAG, "getService() interrupted");
                        Thread.currentThread().interrupt();
                        return null;
                    }
                }
            }
        }
    }

    public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
}

3.2 简单工厂/工厂方法/抽象工厂 Factory Pattern

3.2.1 工厂方法

**意图:**定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

**主要解决:**主要解决接口选择的问题。

**何时使用:**我们明确地计划不同条件下创建不同实例时。

**如何解决:**让其子类实现工厂接口,返回的也是一个抽象的产品。

3.2.2 抽象工厂模式

**意图:**提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

**主要解决:**主要解决接口选择的问题。

**何时使用:**系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

**如何解决:**在一个产品族里面,定义多个产品。

**关键代码:**在一个工厂里聚合多个同类产品。

在实际使用中,工厂模式一般都会跟反射一起使用。

public interface Car {
   public void run();
}

//宝马汽车
public class BMCar implements Car{
   @Override
   public void run() {
      System.out.println("宝马汽车疾驰中......");
   }
}

//奔驰汽车
public class BCCar implements Car {
   @Override
   public void run() {
      System.out.println("奔驰汽车飞驰中...");
   }
}

//山寨汽车
public class UnknownCar implements Car {
   @Override
   public void run() {
      System.out.println("山寨汽车飞驰中...");
   }
}

3.2.3 简单工厂

public class CarFactory {
   public static Car productCar(String brand) throws Exception{
      if(brand.equals("BM")){
         System.out.println("汽车工厂生产宝马汽车...");
         return new BMCar();
      }else if(brand.equals("BC")){
         System.out.println("汽车工厂生产奔驰汽车...");
         return new BCCar();
      }else{
         throw new UnknownCar();
      }
   }
}

public class Client {
   public static void main(String[] args) {
      try
        {
         Car car;
         String brand = Auto.getBrandName();
         car = CarFactory.productCar(brand);
         car.run();
        }
        catch(Exception e)
        {
           System.out.println(e.getMessage());
        }
   }
}

3.2.4 简单工厂类图

classDiagram
AbstractProduct <|-- ConcreteProductA
AbstractProduct <|-- ConcreteProductB
AbstractProduct <|-- UnknownProduct
SimpleFactory ..> AbstractProduct
Client ..> SimpleFactory
Client ..> AbstractProduct

3.2.5 工厂方法

//汽车工厂接口,只有一个生产汽车的方法
public interface CarFactory {
   public Car produceCar();
}

public class BMFactory implements CarFactory {
   public Car produceCar() {
      System.out.println("宝马工厂生产宝马汽车中...");
      return new BMCar();
   }
}

public class BCFactory implements CarFactory{
   @Override
   public Car produceCar() {
      System.out.println("奔驰汽车厂生产汽车..");
      return new BCCar();
   }
}

public class Client {
   public static void main(String[] args) {
      Car car;
      CarFactory carFactory;
        //根据条件,创建工厂,然后工厂生产汽车。//这里面一般会用到反射?
      carFactory = (CarFactory)XMLUtil.getBean();
      car = carFactory.produceCar();
      car.run();
   }
}

3.2.6 工厂方法类图

classDiagram
AbstractProduct <|-- ConcreteProductA
AbstractProduct <|-- ConcreteProductB
AbstractProduct <|-- ConcreteProductC
AbstractProduct <|-- UnknownProduct
AbstractFactory <|-- ConcreteFactoryA
AbstractFactory <|-- ConcreteFactoryB
AbstractFactory <|-- ConcreteFactoryC
ConcreteFactoryA ..> ConcreteProductA
ConcreteFactoryB ..> ConcreteProductB
ConcreteFactoryC ..> ConcreteProductC
AbstractFactory ..> AbstractProduct
Client ..> AbstractFactory
Client ..> AbstractProduct

3.2.7 抽象工厂

如果汽车细分大巴,公交车,的士,按品牌再细分一下,宝马大巴/宝马公交车/宝马的士,奔驰大巴/奔驰公交车/奔驰的士,如果用工厂方法来做,工厂类会很多,所以有了抽象工厂,一个工厂一次可以生产多个相同品牌的产品(产品族)

public interface Factory {
   public Bus produceBus();
   public Car produceCar();
}

public class BMFactory implements Factory{
   @Override
   public Bus produceBus() {
      System.out.println("宝马汽车厂生产宝马大巴...");
      return new BMBus();
   }
   @Override
   public Car produceCar() {
      System.out.println("宝马汽车厂生产宝马轿车...");
      return new BMCar();
   }
}

public class BCFactory implements Factory{
   @Override
   public Bus produceBus() {
      System.out.println("奔驰汽车厂生产奔驰大巴...");
      return null;
   }
   @Override
   public Car produceCar() {
      System.out.println("奔驰汽车厂生产奔驰轿车...");
      return null;
   }
}

public class Client {
   public static void main(String[] args) {
      Bus bus;
      Car car;
      Factory factory = (Factory)XMLUtil.getBean();
      bus = factory.produceBus();
      bus.pull();
      car = factory.produceCar();
      car.run();
   }
}

3.2.8 抽象工厂类图

classDiagram
AbstractProductA <|-- ConcreteProductA1
AbstractProductA <|-- ConcreteProductA2
AbstractProductA <|-- ConcreteProductA3

AbstractProductB <|-- ConcreteProductB1
AbstractProductB <|-- ConcreteProductB2
AbstractProductB <|-- ConcreteProductB3

AbstracFactory <|-- ConcreteFactoryA
AbstracFactory <|-- ConcreteFactoryB

Client ..> AbstracFactory

AbstracFactory ..> AbstractProductA
AbstracFactory ..> AbstractProductB


ConcreteFactoryA ..> AbstractProductA
ConcreteFactoryB ..> AbstractProductB


class AbstracFactory {
   +createAbstractProductA() AbstractProductA
   +createAbstractProductB() AbstractProductB
}

3.3原型模式 Prototype Pattern

为了拷贝现有对象。直接new的对象,属性还需要一个一个的设置,十分麻烦,直接克隆(new+setting)一个对象,产生一个新的对象并且和被克隆对象有相同的属性。

3.3.1 Cloneable接口与Object

java 里的Object对象有一个clone方法(注意这一个方法返回的是Object),但是如果想实现克隆效果,自定义的类还需要实现Cloneable接口

/**
 * Class {@code Object} is the root of the class hierarchy.
 * Every class has {@code Object} as a superclass. All objects,
 * including arrays, implement the methods of this class.
 *
 * @author  unascribed
 * @see     java.lang.Class
 * @since   1.0
 */
public class Object {
   
   ...
    /**
     * Creates and returns a copy of this object.  The precise meaning
     * of "copy" may depend on the class of the object. The general
     * intent is that, for any object {@code x}, the expression:
     * <blockquote>
     * <pre>
     * x.clone() != x</pre></blockquote>
     * will be true, and that the expression:
     * <blockquote>
     * <pre>
     * x.clone().getClass() == x.getClass()</pre></blockquote>
     * will be {@code true}, but these are not absolute requirements.
     * While it is typically the case that:
     * <blockquote>
     * <pre>
     * x.clone().equals(x)</pre></blockquote>
     * will be {@code true}, this is not an absolute requirement.
     * <p>
     * By convention, the returned object should be obtained by calling
     * {@code super.clone}.  If a class and all of its superclasses (except
     * {@code Object}) obey this convention, it will be the case that
     * {@code x.clone().getClass() == x.getClass()}.
     * <p>
     * By convention, the object returned by this method should be independent
     * of this object (which is being cloned).  To achieve this independence,
     * it may be necessary to modify one or more fields of the object returned
     * by {@code super.clone} before returning it.  Typically, this means
     * copying any mutable objects that comprise the internal "deep structure"
     * of the object being cloned and replacing the references to these
     * objects with references to the copies.  If a class contains only
     * primitive fields or references to immutable objects, then it is usually
     * the case that no fields in the object returned by {@code super.clone}
     * need to be modified.
     * <p>
     * The method {@code clone} for class {@code Object} performs a
     * specific cloning operation. First, if the class of this object does
     * not implement the interface {@code Cloneable}, then a
     * {@code CloneNotSupportedException} is thrown. Note that all arrays
     * are considered to implement the interface {@code Cloneable} and that
     * the return type of the {@code clone} method of an array type {@code T[]}
     * is {@code T[]} where T is any reference or primitive type.
     * Otherwise, this method creates a new instance of the class of this
     * object and initializes all its fields with exactly the contents of
     * the corresponding fields of this object, as if by assignment; the
     * contents of the fields are not themselves cloned. Thus, this method
     * performs a "shallow copy" of this object, not a "deep copy" operation.
     * <p>
     * The class {@code Object} does not itself implement the interface
     * {@code Cloneable}, so calling the {@code clone} method on an object
     * whose class is {@code Object} will result in throwing an
     * exception at run time.
     *
     * @return     a clone of this instance.
     * @throws  CloneNotSupportedException  if the object's class does not
     *               support the {@code Cloneable} interface. Subclasses
     *               that override the {@code clone} method can also
     *               throw this exception to indicate that an instance cannot
     *               be cloned.
     * @see java.lang.Cloneable
     */
    @HotSpotIntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;
    ...
}

java里的原型模式,必段实现 Cloneable接口。

public interface Cloneable {
}

3.3.2代码示例

public abstract class Shape implements Cloneable {
   
   private String id;
   protected String type;
   
   abstract void draw();
   
   public String getType(){
      return type;
   }
   
   public String getId() {
      return id;
   }
   
   public void setId(String id) {
      this.id = id;
   }
   
   public Object clone() {
      Object clone = null;
      try {
         clone = super.clone();
      } catch (CloneNotSupportedException e) {
         e.printStackTrace();
      }
      return clone;
   }
}

public class Rectangle extends Shape {
 
   public Rectangle(){
     type = "Rectangle";
   }
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

public class Client {

   public static void main(String[] args) {
      System.out.println("原型模式完成对象的创建");
      Rectangle rectangle = Rectangle();
        rectangle.setId("101010101");
        Rectangle rectangle2 =  rectangle.clone();
   }
}

3.3.3 UML图

classDiagram
Prototype <|-- ConcretePrototypeA
Prototype <|-- ConcretePrototypeB

Cloneable <|-- Prototype

Client ..> Prototype
Client ..> newPrototype : 参过克隆创建了一个新的对象并且设置好了相应属性

class Prototype {
   +clone() Prototype
}

class ConcretePrototypeA {
   +clone() Prototype
}

class ConcretePrototypeB {
   +clone() Prototype
}

class Cloneable {
   +clone() Object
}
<<interface>> Cloneable

3.4.3 深拷贝与浅拷贝

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

深复制方案:

1.自定义的成员属性都要实现cloneable接口,

2.ObjectOutputStreamObjectInputStream和序列化,例如toJsonfromJson

3.4.4安卓sdk中 Cloneable的子类

package android.os;
public final class Bundle extends BaseBundle implements Cloneable, Parcelable {}

package android.animation;
public abstract class Animator implements Cloneable {}

package android.util;
public class SparseLongArray implements Cloneable {}

package android.util;
public class SparseArray<E> implements Cloneable {}

package java.util;
public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {}

package android.content;
public class Intent implements Parcelable, Cloneable {}

package java.util;
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{}
省略省略

3.4 建造者模式 Builder Pattern

**意图:**将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

**主要解决:**主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

Builder里的方法一般是返回this,然后可以链式调用。

3.4.1 类图

classDiagram
AbstractBuilder  <|-- ConcreteBuilder
Director ..> AbstractBuilder
Director ..> Product

class AbstractBuilder {
   +setPropertyA() AbstractBuilder
   +setPropertyB() AbstractBuilder
   +setPropertyC() AbstractBuilder
   +setPropertyD() AbstractBuilder
   +build() Product
}

建造者模式的四个角色

1) Product(产品角色): 一个具体的产品对象。

2) Builder(抽象建造者):创建一个Product对象的各个部件指定的 接口/抽象类

3) ConcreteBuilder(具体建造者): 实现接口,构建和装配各个部件。

4) Director(指挥者): 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,

一是:隔离了客户与对象的生产过程,

二是:负责控制产品对象的生产过程。

以安卓sdk里的源码为例

GestureDescription与Builder

classDiagram
direction BT
class Builder {
  + Builder() 
  - List~StrokeDescription~ mStrokes
  - int mDisplayId
  + addStroke(StrokeDescription) Builder
  + setDisplayId(int) Builder
  + build() GestureDescription
}


public final class GestureDescription {
   ...

    private GestureDescription() {
       this(new ArrayList<>());
    }

    private GestureDescription(List<StrokeDescription> strokes) {
        this(strokes, Display.DEFAULT_DISPLAY);
    }

    private GestureDescription(List<StrokeDescription> strokes, int displayId) {
        mStrokes.addAll(strokes);
        mDisplayId = displayId;
    }

    ......

    /**
     * Builder for a {@code GestureDescription}
     */
    public static class Builder {

        private final List<StrokeDescription> mStrokes = new ArrayList<>();
        private int mDisplayId = Display.DEFAULT_DISPLAY;

        /**
         * Adds a stroke to the gesture description. Up to
         * {@link GestureDescription#getMaxStrokeCount()} paths may be
         * added to a gesture, and the total gesture duration (earliest path start time to latest
         * path end time) may not exceed {@link GestureDescription#getMaxGestureDuration()}.
         *
         * @param strokeDescription the stroke to add.
         *
         * @return this
         */
        public Builder addStroke(@NonNull StrokeDescription strokeDescription) {
            if (mStrokes.size() >= MAX_STROKE_COUNT) {
                throw new IllegalStateException(
                        "Attempting to add too many strokes to a gesture. Maximum is "
                                + MAX_STROKE_COUNT
                                + ", got "
                                + mStrokes.size());
            }

            mStrokes.add(strokeDescription);

            if (getTotalDuration(mStrokes) > MAX_GESTURE_DURATION_MS) {
                mStrokes.remove(strokeDescription);
                throw new IllegalStateException(
                        "Gesture would exceed maximum duration with new stroke");
            }
            return this;
        }

        /**
         * Sets the id of the display to dispatch gestures.
         *
         * @param displayId The logical display id
         *
         * @return this
         */
        public @NonNull Builder setDisplayId(int displayId) {
            mDisplayId = displayId;
            return this;
        }

        public GestureDescription build() {
            if (mStrokes.size() == 0) {
                throw new IllegalStateException("Gestures must have at least one stroke");
            }
            return new GestureDescription(mStrokes, mDisplayId);
        }
    }
}

AlertDialog.Builder

classDiagram
direction BT
class Builder {
  + Builder(Context) 
  + Builder(Context, int) 
  + setIcon(Drawable) Builder
  + setTitle(int) Builder
  + setOnItemSelectedListener(OnItemSelectedListener) Builder
  + setSingleChoiceItems(CharSequence[], int, OnClickListener) Builder
  + setView(View) Builder
  + setNeutralButton(int, OnClickListener) Builder
  + setNegativeButton(int, OnClickListener) Builder
  + setSingleChoiceItems(ListAdapter, int, OnClickListener) Builder
  + setItems(int, OnClickListener) Builder
  + setIcon(int) Builder
  + setView(int) Builder
  + setSingleChoiceItems(Cursor, int, String, OnClickListener) Builder
  + setPositiveButton(CharSequence, OnClickListener) Builder
  + setInverseBackgroundForced(boolean) Builder
  + setPositiveButton(int, OnClickListener) Builder
  + setOnCancelListener(OnCancelListener) Builder
  + setCursor(Cursor, OnClickListener, String) Builder
  + setMultiChoiceItems(Cursor, String, String, OnMultiChoiceClickListener) Builder
  + setNeutralButton(CharSequence, OnClickListener) Builder
  + setTitle(CharSequence) Builder
  + setCancelable(boolean) Builder
  + setOnDismissListener(OnDismissListener) Builder
  + setIconAttribute(int) Builder
  + getContext() Context
  + setOnKeyListener(OnKeyListener) Builder
  + setMessage(CharSequence) Builder
  + setMultiChoiceItems(int, boolean[], OnMultiChoiceClickListener) Builder
  + setMessage(int) Builder
  + setCustomTitle(View) Builder
  + setAdapter(ListAdapter, OnClickListener) Builder
  + setMultiChoiceItems(CharSequence[], boolean[], OnMultiChoiceClickListener) Builder
  + setItems(CharSequence[], OnClickListener) Builder
  + setSingleChoiceItems(int, int, OnClickListener) Builder
  + setView(View, int, int, int, int) Builder
  + show() AlertDialog
  + setRecycleOnMeasureEnabled(boolean) Builder
  + create() AlertDialog
  + setNegativeButton(CharSequence, OnClickListener) Builder
}

public class AlertDialog extends Dialog implements DialogInterface {
   
   ......
    protected AlertDialog(Context context) {
        this(context, 0);
    }

    protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        this(context, 0);

        setCancelable(cancelable);
        setOnCancelListener(cancelListener);
    }

  
    protected AlertDialog(Context context, @StyleRes int themeResId) {
        this(context, themeResId, true);
    }

    AlertDialog(Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
        super(context, createContextThemeWrapper ? resolveDialogTheme(context, themeResId) : 0,
                createContextThemeWrapper);

        mWindow.alwaysReadCloseOnTouchAttr();
        mAlert = AlertController.create(getContext(), this, getWindow());
    }

   ......
    public static class Builder {


        public Builder(Context context) {
            this(context, resolveDialogTheme(context, Resources.ID_NULL));
        }

        public Builder(Context context, int themeResId) {
            P = new AlertController.AlertParams(new ContextThemeWrapper(
                    context, resolveDialogTheme(context, themeResId)));
        }

       ......

        public Builder setView(View view) {
            P.mView = view;
            P.mViewLayoutResId = 0;
            P.mViewSpacingSpecified = false;
            return this;
        }

        public AlertDialog create() {
           ...
           return dialog;
        }

        public AlertDialog show() {
            final AlertDialog dialog = create();
            dialog.show();
            return dialog;
        }
    }
}