美文网首页
Android开发常见的设计模式

Android开发常见的设计模式

作者: 郑在学_blog | 来源:发表于2017-10-14 11:48 被阅读0次

    单例模式

    概念:

    确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

    优点:
    • 对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中。
    • 保持程序运行的时候,始终只有一个实例存在内存中
    例子:
    public class Singleton {
        private static volatile Singleton instance = null;
    
        private Singleton(){
        }
     
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    编写单例模式,需要记住的特点:
    • 必须防止外部可以调用构造函数进行实例化,因此构造函数必须私有化。
    • 必须定义一个静态函数获得该单例getInstance();
    • 单例使用volatile修饰,volatile可以保证不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
    • 使用synchronized 进行同步处理,并且双重判断是否为null,我们看到synchronized (Singleton.class)里面又进行了是否为null的判断,这是因为一个线程进入了该代码,如果另一个线程在等待,这时候前一个线程创建了一个实例出来完毕后,另一个线程获得锁进入该同步代码,实例已经存在,没必要再次创建,因此这个判断是否是null还是必须的。

    Build模式

    概念:

    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

    优点:

    提高代码的可读性。

    例子:
    public class Person {
        private String name;
        private int age;
        private double height;
        private double weight;
    
        privatePerson(Builder builder) {
            this.name=builder.name;
            this.age=builder.age;
            this.height=builder.height;
            this.weight=builder.weight;
        }
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public double getHeight() {
            return height;
        }
    
        public void setHeight(double height) {
            this.height = height;
        }
    
        public double getWeight() {
            return weight;
        }
    
        public void setWeight(double weight) {
            this.weight = weight;
        }
    
        static class Builder{
            private String name;
            private int age;
            private double height;
            private double weight;
            public Builder name(String name){
                this.name=name;
                return this;
            }
            public Builder age(int age){
                this.age=age;
                return this;
            }
            public Builder height(double height){
                this.height=height;
                return this;
            }
    
            public Builder weight(double weight){
                this.weight=weight;
                return this;
            }
    
            public Person build(){
                return new Person(this);
            }
        }
    }
    

    编写一个Person类,里面有一个叫Builder的静态内部类,他们的属性是一样的。把Person类的构造函数私有化,参数是Builder,把Builder类中的属性对应赋值给Person类。Builder类里面有对应各个属性名的方法,有点像Setter方法,唯一不同是返回值返回的是this。Builder类里面还有build方法,返回Person对象,return new Person(this);

    然后我们就可以这样创建Person类对象了:

    Person.Builder builder=new Person.Builder();
    Person person=builder
            .name("张三")
            .age(18)
            .height(178.5)
            .weight(67.4)
            .build();
    

    Android 里面的AlertDialog,StringBuilder,StringBuffer 都有运用到Build模式。

    观察者模式

    概念:

    定义对象间的一种一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都能得到通知并被自动更新

    例子:

    天气对象:

    public class Weather {
        private String description;
    
        public Weather(String description) {
            this.description = description;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        @Override
        public String toString() {
            return "Weather{" +
                    "description='" + description + '\'' +
                    '}';
        }
    }
    

    被观察者:

    public class Observable<T> {
        List<Observer<T>> mObservers = new ArrayList<Observer<T>>();
    
        public void register(Observer<T> observer) {
            if (observer == null) {
                throw new NullPointerException("observer == null");
            }
            synchronized (this) {
                if (!mObservers.contains(observer))
                    mObservers.add(observer);
            }
        }
    
        public synchronized void unregister(Observer<T> observer) {
            mObservers.remove(observer);
        }
    
        public void notifyObservers(T data) {
            for (Observer<T> observer : mObservers) {
                observer.onUpdate(this, data);
            }
        }
    
    }
    

    观察者需要实现的接口:

    public interface Observer<T> {
        void onUpdate(Observable<T> observable,T data);
    }
    

    Main函数:

    public class Main {
        public static void main(String [] args){
            Observable<Weather> observable=new Observable<Weather>();
            Observer<Weather> observer1=new Observer<Weather>() {
                @Override
                public void onUpdate(Observable<Weather> observable, Weather data) {
                    System.out.println("观察者1:"+data.toString());
                }
            };
            Observer<Weather> observer2=new Observer<Weather>() {
                @Override
                public void onUpdate(Observable<Weather> observable, Weather data) {
                    System.out.println("观察者2:"+data.toString());
                }
            };
    
            observable.register(observer1);
            observable.register(observer2);
    
    
            Weather weather=new Weather("晴转多云");
            observable.notifyObservers(weather);
    
            Weather weather1=new Weather("多云转阴");
            observable.notifyObservers(weather1);
    
            observable.unregister(observer1);
    
            Weather weather2=new Weather("台风");
            observable.notifyObservers(weather2);
    
        }
    }
    

    Android的广播机制就是使用的观察者模式。

    原型模式

    概念:

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

    要实现原型模式,只需要按照下面的几个步骤去实现即可。

    • 实现Clone接口:
    public class Person implements Cloneable{
    
    }
    
    • 重写Object的clone方法
    @Override
    public Object clone(){
        return null;
    }
    
    • 实现clone方法中的拷贝逻辑
    @Override
    public Object clone(){
        Person person=null;
        try {
            person=(Person)super.clone();
            person.name=this.name;
            person.weight=this.weight;
            person.height=this.height;
            person.age=this.age;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return person;
    }
    
    • 测试:
    public class Main {
        public static void main(String [] args){
            Person p=new Person();
            p.setAge(18);
            p.setName("张三");
            p.setHeight(178);
            p.setWeight(65);
            System.out.println(p);
    
            Person p1= (Person) p.clone();
            System.out.println(p1);
    
            p1.setName("李四");
            System.out.println(p);
            System.out.println(p1);
        }
    }
    
    • 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。

    注意:这里的克隆是浅克隆,只是克隆引用,所以,如果要克隆ArrayList,需要再克隆一次。

    person.hobbies=(ArrayList<String>)this.hobbies.clone();
    

    策略模式

    概念:

    策略模式定义了一些列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变换。

    • 首先,需要定义一个策略接口。
    public interface Strategy {
        void travel();
    }
    
    • 然后根据不同的出行方式实行对应的接口
    public class WalkStrategy implements Strategy{
    
        @Override
        public void travel() {
            System.out.println("walk");
        }
    
    public class PlaneStrategy implements Strategy{
    
        @Override
        public void travel() {
            System.out.println("plane");
        }
    
    }
    
    public class SubwayStrategy implements Strategy{
    
        @Override
        public void travel() {
            System.out.println("subway");
        }
    
    }
    
    • 此外还需要一个包装策略的类,并调用策略接口中的方法
    public class TravelContext {
        Strategy strategy;
    
        public Strategy getStrategy() {
            return strategy;
        }
    
        public void setStrategy(Strategy strategy) {
            this.strategy = strategy;
        }
    
        public void travel() {
            if (strategy != null) {
                strategy.travel();
            }
        }
    }
    

    可以看到,应用了策略模式后,如果我们想增加新的出行方式,完全不必要修改现有的类,我们只需要实现策略接口即可,这就是面向对象中的对扩展开放准则。假设现在我们增加了一种自行车出行的方式。只需新增一个类即可。

    参考:Android开发中常见的设计模式

    相关文章

      网友评论

          本文标题:Android开发常见的设计模式

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