美文网首页
Android中常见的几种设计模式

Android中常见的几种设计模式

作者: 34sir | 来源:发表于2018-06-24 22:00 被阅读10次

    原则

    设计模式的六大原则:

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

    类型

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

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

    分析

    • 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 extends CarProduct> T createProduct(Class<T> 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 extends CarProduct> T createProduct(Class<T> 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<T> {
        boolean hasNext();
        //泛型更具灵活性
        T next();
    }
    
    //容器接口
    public interface Aggregate<T> {
        void add(T obj);
    
        void remove(T obj);
    
        Iterator<T> interator();// 获取容器的迭代器
    }
    
    // 具体迭代器
    public class ConcreteIterator<T> implements Iterator<T>{
        private List<T> list=new ArrayList<>();
        private int cursor=0;
    
        public ConcreteIterator(List<T> 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<T> implements Aggregate<T> {
        private List<T> list = new ArrayList<>();
    
    
        @Override
        public void add(T obj) {
            list.add(obj);
        }
    
        @Override
        public void remove(T obj) {
            list.remove(obj);
        }
    
        @Override
        public Iterator<T> interator() {
            return new ConcreteIterator<>(list);
        }
    }
    
    public static void main(String[] args) {
            //此例实际实现了对容器对迭代 实际上Iterator已经存在
            Aggregate<String> aggregate = new ConcreteAggregate<>();
            aggregate.add("ckc");
            aggregate.add("34sir");
    
            Iterator<String> 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<Observer> observers = new Vector<>();
    
        @Override
        public void notifyData() {
            Enumeration<Observer> 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<Component> 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<Component> 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<T> {
        boolean hasNext();
        //泛型更具灵活性
        T next();
    }
    
    //容器接口
    public interface Aggregate<T> {
        void add(T obj);
    
        void remove(T obj);
    
        Iterator<T> interator();// 获取容器的迭代器
    }
    
    // 具体迭代器
    public class ConcreteIterator<T> implements Iterator<T>{
        private List<T> list=new ArrayList<>();
        private int cursor=0;
    
        public ConcreteIterator(List<T> 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<T> implements Aggregate<T> {
        private List<T> list = new ArrayList<>();
    
    
        @Override
        public void add(T obj) {
            list.add(obj);
        }
    
        @Override
        public void remove(T obj) {
            list.remove(obj);
        }
    
        @Override
        public Iterator<T> interator() {
            return new ConcreteIterator<>(list);
        }
    }
    
    public static void main(String[] args) {
            //此例实际实现了对容器对迭代 实际上Iterator已经存在
            Aggregate<String> aggregate = new ConcreteAggregate<>();
            aggregate.add("ckc");
            aggregate.add("34sir");
    
            Iterator<String> 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<String, Ticket> 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中常见的几种设计模式

          本文链接:https://www.haomeiwen.com/subject/lalsyftx.html