Android中常见的几种设计模式

原则

设计模式的六大原则:

  • 单一职责
  • 开闭 对扩展开发;对修改关闭
  • 依赖倒置 高模块不依赖低模块 高模块和低模块都依赖抽象;抽象不依赖具体实现 具体实现依赖抽象
  • 里氏替换 子类可以替换父类;父类不一定可以替换子类
  • 迪马特法则 一个类尽可能少的知道其他类;解耦
  • 接口隔离 不依赖不需要的接口 类之间的依赖关系应该建立在最小的接口(接口尽量细化 不要有太多的方法)上;核心:依赖抽象 不依赖具体

类型

常见的设计模式分为三类:

  • 创建型 单例;工厂;建造者
  • 行为型 迭代器;观察者;策略
  • 结构型 代理;适配器;组合;装饰

分析

  • Builder
    作用:用户不知道内部构造细节的情况下 控制构造流程
    优点:良好的封装性 客户端不必知道产品内部组成细节
    场景:相同的方法 不同的执行顺序产生不同的结果 初始化的对象很复杂 参数很多
    应用:AlertDialog
    栗子:
public class Person {
    private String name;
    private int sex;

    public Person(Builder builder){
        this.name=builder.name;
        this.sex=builder.sex;
    }

    public String getName(){
        return name;
    }

    public int getSex(){
        return sex;
    }


    static class Builder {
        //Builder需要持有和Person相同的对象
        public String name;
        public int sex;

        public Builder() {
        }

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

        public Builder setSex(int sex) {
            this.sex = sex;
            return this;
        }

        // 之所以在build中才构建具体Person对象 应该是处于拓展考虑 比如再来一个student类Builder可以复用
        public Person build() {
            return new Person(this);
        }
    }
}
 public static void main(String[] args) {
        // 达到链式调用的效果
        Person person = new Person.Builder().setName("34sir").setSex(1).build();
        System.out.println("person::name=" + person.getName() + "---person::sex=" + person.getSex());
    }
  • 工厂方法
    作用:定义用于创建对象的接口 让子类决定实例化哪个类
    优点:多态性 灵活;封装性 结构清晰;拓展性;解耦
    场景:任何需要生成复杂对象的地方 new 就可以创建的对象无需使用工厂方法
    应用:Activity的onCreate
    栗子:


    工厂方法.png
//汽车抽象产品
public abstract class CarProduct {
    public abstract void born();
}
//汽车抽象工厂
public abstract class CarFactory {
    public abstract  T createProduct(Class clz);
}
//奥迪Q3
public class AodiQ3 extends CarProduct {

    @Override
    public void born() {
        System.out.println(this.getClass().getSimpleName()+"诞生了!");
    }
}
//奥迪Q5
public class AodiQ5 extends CarProduct {

    @Override
    public void born() {
        System.out.println(this.getClass().getSimpleName()+"诞生了!");
    }
}
//具体汽车工厂
public class ConcreateCarFactory extends CarFactory {

    @Override
    public  T createProduct(Class clz) {
        CarProduct product = null;
        try {
            // 利用反射+泛型灵活 不需要多个工厂实现类
            product= (CarProduct) Class.forName(clz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T)product;
    }
}
 public static void main(String [] args){
        CarFactory factory=new ConcreateCarFactory();
        //生产不同的汽车产品
        factory.createProduct(AodiQ3.class).born();
        factory.createProduct(AodiQ5.class).born();
    }
  • 策略
    作用:将算法或策略抽象出来 提供一个同一的接口 不同的算法或策略有不同的实现类 通过注入不同的实现对象来实现算法或策略的动态替换
    优点:结构化;解耦 易扩展;封装性
    场景:同一问题多种处理方式 行为的差别;同一个抽象类 多个子类 需要使用if-else来选择具体子类
    应用:属性动画的插值器

  • 迭代器
    作用:提供一种统一的方法顺序访问一个容器对象中的各个元素 不暴露对象中的内部细节
    优点:
    场景:遍历容器对象
    应用:查询数据库时使用的Cursor
    栗子:


    迭代器.png
//迭代器接口 主要的两个方法:hasNext  next();
public interface Iterator {
    boolean hasNext();
    //泛型更具灵活性
    T next();
}
//容器接口
public interface Aggregate {
    void add(T obj);

    void remove(T obj);

    Iterator interator();// 获取容器的迭代器
}
// 具体迭代器
public class ConcreteIterator implements Iterator{
    private List list=new ArrayList<>();
    private int cursor=0;

    public ConcreteIterator(List list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return cursor!=list.size();
    }

    @Override
    public T next() {
        T obj = null;
        if(this.hasNext()){
            obj=list.get(cursor++);
        }
        return obj;
    }
}
//具体容器类
public class ConcreteAggregate implements Aggregate {
    private List list = new ArrayList<>();


    @Override
    public void add(T obj) {
        list.add(obj);
    }

    @Override
    public void remove(T obj) {
        list.remove(obj);
    }

    @Override
    public Iterator interator() {
        return new ConcreteIterator<>(list);
    }
}
public static void main(String[] args) {
        //此例实际实现了对容器对迭代 实际上Iterator已经存在
        Aggregate aggregate = new ConcreteAggregate<>();
        aggregate.add("ckc");
        aggregate.add("34sir");

        Iterator iterator = aggregate.interator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
  • 代理
    作用:为某个对象提供代理 以控制对这个对象的访问
    优点:没什么缺点 强调控制 隔离
    场景:无法或者不想直接访问某个对象
    应用:ActivityManagerProxy代理ActivityManagerService
    栗子:包含静态代理和动态代理


    代理.png
//抽象主题
public interface Subject {
   void visit();
}
//真实主题
public class RealSubject implements Subject{
    @Override
    public void visit() {
        System.out.println("具体主题 具体逻辑");
    }
}
//静态代理类
public class ProxySubject implements Subject{
    RealSubject subject;

    public ProxySubject(RealSubject subject) {
        this.subject = subject;
    }

    @Override
    public void visit() {
        //调用受代理真实逻辑
        subject.visit();
    }
}
//动态代理类
public class DynamicProxySubject implements InvocationHandler{
    Subject subject;

    public DynamicProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        return method.invoke(subject,objects);
    }
}
public static void main(String[] args) {
        //静态代理
        ProxySubject proxy=new ProxySubject(new RealSubject());
        proxy.visit();

        //动态代理
        Subject subject=new RealSubject();
        DynamicProxySubject dynamicProxySubject=new DynamicProxySubject(subject);
        ClassLoader loader=subject.getClass().getClassLoader();
        //Proxy.newProxyInstance 此方法是实现动态代理的关键
        Subject subjecter= (Subject) Proxy.newProxyInstance(loader,new Class[]{Subject.class},dynamicProxySubject);
        subjecter.visit();
    }
  • 观察者
    作用:定义对象间一对多的依赖关系 使得当一个对象改变 所有依赖于他的对象都会得到通知并更新
    优点:将观察者和被观察者解耦
    场景:消息交换 订阅-发布系统 消息队列 事件总线等
    应用:Adapter#notifyDataSetChanged;BroadcastReceiver
    栗子:


    观察者.png
//抽象主题 订阅者
public interface Subject {
    void notifyData();
    void addObserver(Observer observer);
    void deleteObserver(Observer observer);
}
//抽象观察者
public interface Observer {
    void update(String msg);
}
//具体订阅者
public class ConcreteSubject implements Subject {
    // 之所有使用Vector 是因为其线程安全
    private Vector observers = new Vector<>();

    @Override
    public void notifyData() {
        Enumeration enumo = observers.elements();
        while (enumo.hasMoreElements()) {
            enumo.nextElement().update("hello world");
        }
    }

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void deleteObserver(Observer observer) {
        observers.remove(observer);
    }
}
//具体观察者
public class ConcreteObserver implements Observer{
    String msg;
    @Override
    public void update(String msg) {
        this.msg = msg;
        System.out.println("ConcreteSubject的msg更新成" + this.msg);
    }
}
 public static void main(String [] args){
        Subject subject=new ConcreteSubject();
        subject.addObserver(new ConcreteObserver());
        subject.notifyData();
    }
  • 组合
    作用:将对象组合成树形结构 以表示“部分-整体”的层次结构 使得用户对单个对象和组合对象的访问具有一致性
    优点:清楚的定义分层次的复杂对象 简化高层模块的代码 递归组合形成复杂的树形结构
    场景:一个整体中能够独立出部分模块和功能
    应用:View和ViewGroup的嵌套组合
    栗子:


    组合.png

1.安全组合

//抽象根节点
public abstract class Component {
    protected String name; //节点

    public Component(String name) {
        this.name = name;
    }

    //具体由子类实现
    public abstract void doSomething();
}
//枝干
public class Composite extends Component {
    public Composite(String name) {
        super(name); // 调用父类的方法
    }

    private List composites = new ArrayList<>();

    @Override
    public void doSomething() {
        System.out.println(name); //此句为具体实现的逻辑
        if (null != composites) {
            for (Component c : composites) {
                c.doSomething();
            }
        }
    }

    public void addChild(Component c) {
        composites.add(c);
    }

    public void remove(Component c) {
        composites.remove(c);
    }

    public Component getChild(int index) {
        return composites.get(index);
    }
}

//叶子
public class Leaf extends Component {
    public Leaf(String name) {
        super(name); // 调用父类的方法
    }

    @Override
    public void doSomething() {
        System.out.println(name);
    }
}
//叶子
public static void main(String[] args) {
        // 与透明组合模式的区别
        Composite root = new Composite("root");

        Composite branchOne = new Composite("branchone");
        Composite branchTwo = new Composite("branchtwo");

        Leaf leafOne = new Leaf("leafone");
        Leaf leafTwo = new Leaf("leaftwo");

        branchOne.addChild(leafOne);
        branchTwo.addChild(leafTwo);

        root.addChild(branchOne);
        root.addChild(branchTwo);

        root.doSomething();
    }

2.透明组合

//抽象根节点
public abstract class Component {
    protected String name; //节点

    public Component(String name) {
        this.name = name;
    }

    //具体由子类实现
    public abstract void doSomething();

    public abstract void addChild(Component c);

    public abstract void removeChild(Component c);

    public abstract Component getChild(int index);

}
//枝干
public class Composite extends Component {
    public Composite(String name) {
        super(name); // 调用父类的方法
    }

    private List composites = new ArrayList<>();

    @Override
    public void doSomething() {
        System.out.println(name); //此句为具体实现的逻辑
        if (null != composites) {
            for (Component c : composites) {
                c.doSomething();
            }
        }
    }

    public void addChild(Component c) {
        composites.add(c);
    }

    @Override
    public void removeChild(Component c) {
        composites.remove(c);
    }


    public Component getChild(int index) {
        return composites.get(index);
    }
}
//叶子
public class Leaf extends Component {
    public Leaf(String name) {
        super(name); // 调用父类的方法
    }

    @Override
    public void doSomething() {
        System.out.println(name);
    }

    @Override
    public void addChild(Component c) {
        throw new UnsupportedOperationException("叶子无法添加子节点");
    }

    @Override
    public void removeChild(Component c) {
        throw new UnsupportedOperationException("叶子没有子节点");
    }

    @Override
    public Component getChild(int index) {
        throw new UnsupportedOperationException("叶子没有子节点");
    }
}
public static void main(String[] args) {
        // 与安全组合模式的区别
        Component root=new Composite("root");

        Component branchOne=new Composite("branchone");
        Component branchTwo = new Composite("branchtwo");

        Component leafOne=new Leaf("leafone");
        Component leafTwo=new Leaf("leaftwo");

        branchOne.addChild(leafOne);
        branchTwo.addChild(leafTwo);

        root.addChild(branchOne);
        root.addChild(branchTwo);

        root.doSomething();
    }
  • 适配器
    作用:把一个类的接口变换成客户端所期待的另一个接口 将两个不兼容的类融合在一起
    优点:更好的复用性;更好的拓展性 适配的同时可以开发新功能
    场景:兼容老接口
    应用:ListView#Adapter
    栗子:


    image.png
//迭代器接口 主要的两个方法:hasNext  next();
public interface Iterator {
    boolean hasNext();
    //泛型更具灵活性
    T next();
}
//容器接口
public interface Aggregate {
    void add(T obj);

    void remove(T obj);

    Iterator interator();// 获取容器的迭代器
}
// 具体迭代器
public class ConcreteIterator implements Iterator{
    private List list=new ArrayList<>();
    private int cursor=0;

    public ConcreteIterator(List list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return cursor!=list.size();
    }

    @Override
    public T next() {
        T obj = null;
        if(this.hasNext()){
            obj=list.get(cursor++);
        }
        return obj;
    }
}
//具体容器类
public class ConcreteAggregate implements Aggregate {
    private List list = new ArrayList<>();


    @Override
    public void add(T obj) {
        list.add(obj);
    }

    @Override
    public void remove(T obj) {
        list.remove(obj);
    }

    @Override
    public Iterator interator() {
        return new ConcreteIterator<>(list);
    }
}
public static void main(String[] args) {
        //此例实际实现了对容器对迭代 实际上Iterator已经存在
        Aggregate aggregate = new ConcreteAggregate<>();
        aggregate.add("ckc");
        aggregate.add("34sir");

        Iterator iterator = aggregate.interator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
  • 装饰
    作用:动态的给一个对象添加一些额外的指责 继承关系的一种替代方案
    优点:动态增加类的功能
    场景:需要透明并且动态的扩展类的功能
    应用:ContextWrapper装饰ContextImpl
    栗子:


    装饰.png
// 抽象组件
public abstract class Component {
    public abstract void operate();
}
//抽象装饰者
public abstract class Decorator extends Component {
    private Component component;//持有一个组件

    public Decorator(Component component) {
        this.component = component;
    }

    @Override

    public void operate() {
        component.operate();
    }
}
// 具体组件
public class ConcreteComponent extends Component{
    @Override
    public void operate() {

    }
}
//具体装饰类
public class ConcreteDecortor extends Decorator {
    public ConcreteDecortor(Component component) {
        super(component);
    }

    @Override
    public void operate() {
        operateA(); //operateA和operateB增强组件的功能
        super.operate();
        operateB();
    }

    public void operateA() {

    }

    public void operateB() {

    }
}

public static void main(String[] arg) {
        Component component = new ConcreteComponent();
        //ConcreteDecortor装饰Component
        Decorator decorator = new ConcreteDecortor(component);
        decorator.operate();
    }
  • 享元
    作用:缓存可共享的对象 避免创建过多的对象 减少内存使用量
    场景:大量重复对象
    应用:Message#obtain
    栗子:


    享元.png
//抽象车票接口
public interface Ticket {
    public void showTicketInfo(String bunk);
}
//车票工厂
public class TicketFactory {
    // 首先选择一种容器缓存
    static Map ticketMap = new ConcurrentHashMap<>();

    public static Ticket getTicket(String from, String to) {
        String key = from + "" + to;
        if (ticketMap.containsKey(key)) {
            return ticketMap.get(key);
        } else {
            Ticket ticket = new TrainTicket(from, to);
            ticketMap.put(key, ticket);
            return ticket;
        }
    }
}
//火车票
public class TrainTicket implements Ticket {
    public String from; //始发地
    public String to; //目的地
    public int price;

    public TrainTicket(String from, String to) {
        this.from = from;
        this.to = to;
    }

    @Override
    public void showTicketInfo(String bunk) {
        price = new Random().nextInt(300);
        System.out.println("购买从" + from + "到" + to + "的" + bunk + "火车票" + ",价格:" + price);
    }
}
 public static void main(String [] args){
        Ticket ticketOne= TicketFactory.getTicket("苏州","上海");
        ticketOne.showTicketInfo("上铺");
        Ticket ticketTwo= TicketFactory.getTicket("苏州","上海");
        ticketTwo.showTicketInfo("下铺");
        Ticket ticketThree= TicketFactory.getTicket("苏州","上海");
        ticketThree.showTicketInfo("站票");
    }

你可能感兴趣的:(Android中常见的几种设计模式)