乐趣区

关于android:Android常用设计模式

因为我的项目变更的频繁性,作为一名程序员,咱们须要把握设计模式的必要性,就显而易见~~,上面就是一些我本人学习的设计模式总结。接下来,次要是针对几个比拟罕用模式进行解说,次要是以下几种:

观察者模式
适配器模式
代理模式
工厂模式
单例模式
命令模式

1. 观察者模式(Observer Pattern)

释义:
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会告诉所有观察者对象,使他们可能自动更新本人。

故事了解:
观察者想晓得公司所有 MM 的状况,只有退出公司的 MM 情报邮件组就行了,tom 负责搜集情报,当发现新情报时,不必一个一个告诉咱们,间接公布给邮件组,咱们作为订阅者(观察者)就能够及时收到情报啦。

常见实例:
BaseAdapter.registerDataSetObserver 和 BaseAdapter.unregisterDataSetObserver 两办法来向 BaseAdater 注册、登记一个 DataSetObserver ;
应用 ContentObserver 去监听数据库变动。
实用场景:
当对一个对象的扭转须要同时扭转其余对象,而不晓得具体有多少对象有待扭转;
当一个对象必须告诉其它对象,而它又不能假设其它对象是谁.
观察者模式次要有观察者和被观察者 2 个对象,在该模式中,Observable 示意被观察者,这个对象是一个抽象类,只能被继承。Observer 示意观察者,他是一个接口,所以观察者能够有多个,实现了该接口的类都是属于观察者。这是网上一个活泼粗疏的 demo:
被观察者:

public class MyPerson extends Observable {

    private int age;
    private String name;
    private String sax;

    public int getAge() {return age;}

    public void setAge(int age) {
        this.age = age;
        setChanged();
        notifyObservers();}

    public String getName() {return name;}

    public void setName(String name) {
        this.name = name;
        setChanged();
        notifyObservers();}

    public String getSax() {return sax;}

    public void setSax(String sax) {this.sax = sax;}

    @Override public String toString() {return "MyPerson [age=" + age + ", name=" + name + ", sax=" + sax + "]";
    }
}

MyPerson 是被观察者,类中调用了 setChange()以及 notifyObservers()两个办法,前者是告知数据扭转,后者是发送信号告诉观察者。

观察者:

public class MyObserver implements Observer {

    private int i;
    private MyPerson myPerson; // 察看的对象
    public MyObserver(int i) {System.out.println("我是观察者 ---->" + i);
        this.i = i;
    }

    public int getI() {return i;}

    public void setI(int i) {this.i = i;}

    public MyPerson getMyPerson() {return myPerson;}

    public void setMyPerson(MyPerson myPerson) {this.myPerson = myPerson;}

    @Override public void update(Observable observable, Object data) {System.out.println("观察者 ---->" + i + "失去更新!");
        this.myPerson = (MyPerson) observable;
        System.out.println(((MyPerson) observable).toString());
    }

}

观察者须要实现 Observer 接口,其中只有一个 update 办法,当观察者收到(被观察者)的告诉信号,就会执行该动作。

2. 适配器模式(Adapter Pattern)

释义:
把一个类的接口变换成客户端所期待的另一种接口,从而使本来因接口起因不匹配而无奈一起工作的两个类可能一起工作。适配类能够依据参数返还一个适合的实例给客户端。

故事了解:
在敌人团聚上碰到了一个美女 Sarah,从香港来的,可我不会说粤语,她不会说普通话,只好求助于我的敌人 kent 了,他作为我和 Sarah 之间的 Adapter,让我和 Sarah 能够互相交谈了(也不晓得他会不会耍我)。

常见实例:
ListView 用于显示列表数据,然而作为列表数据汇合有很多模式,有 Array,有 Cursor,咱们须要对应的适配器作为桥梁,解决相应的数据(并能造成 ListView 所须要的视图)。

实用场景:
业务的接口与工作的类不兼容,(比方:类中短少实现接口的某些办法)但又须要两者一起工作;
在现有接口和类的根底上为新的业务需要提供接口。
适配器模式分为类适配器模式和对象适配器模式。对于类适配模式,因为 java 的单继承,所以在已继承一个类时,另外的只能是接口,须要手动实现相应的办法,这样在客户端就能够创立任一种合乎需要的子类,来实现具体性能。而另外一种对象适配器,它不是应用继承再实现的形式,而是应用间接关联,或者称为委托的形式,具体可见该博客具体介绍适配器模式(Adapter):类适配器、对象适配器

接下来就以 ListView 与 ArrayAdapter 来解说下
ListAdapter:

public interface ListAdapter {public int getCount();
    Object getItem(int position);
    long getItemId(int position);
    View getView(int position, View convertView, ViewGroup parent);
    boolean isEmpty();}

ListView 作为一个客户端,所须要的指标接口就是 ListAdapter, 蕴含 getCount(),getItem(),getView()等几个办法,为了兼容 List< T > 数据类型的数据源,专门定义了 ArrayAdapter 适配器,说白了,就是针对指标接口对数据源进行兼容润饰。
抽象类 BaseAdapter,省略了其余代码,这里只列出两个办法:

public abstract class BaseAdapter implements ListAdapter,SpinnerAdapter {
    // ... ...
    public View getDropDownView(int position, View convertView, ViewGroup parent) {return getView(position, convertView, parent);
    }
    public boolean isEmpty() {return getCount() == 0;
    }
}

ArrayAdapter 对 List< T > 进行封装成 ListAdapter 的实现,满足 ListView 的调用:

public class ArrayAdapter < T > extends BaseAdapter implements Filterable {
    private List < T > mObjects;
    // 我只列出这一个构造函数,大家懂这个意思就行
    public ArrayAdapter(Context context, int textViewResourceId, T[] objects) {init(context, textViewResourceId, 0, Arrays.asList(objects));
    }

    private void init(Context context, int resource, int textViewResourceId, List < T > objects) {
        mContext = context;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mResource = mDropDownResource = resource;
        mObjects = objects; // 援用对象,也是表白了组合优于继承的意思
        mFieldId = textViewResourceId;
    }
    public int getCount() {return mObjects.size();
    }

    public T getItem(int position) {return mObjects.get(position);
    }

    public View getView(int position, View convertView, ViewGroup parent) {return createViewFromResource(position, convertView, parent, mResource);
    }
    // ... ...
}

咱们就如此胜利的把 List< T > 作为数据源以 ListView 想要的指标接口的样子传给了 ListView。这其实也是对象适配器的一种。

3. 代理模式(Proxy Pattern)

释义:
通过引入一个新的对象来实现对实在对象的操作或将新的对象作为实在对象的一个替身, 这样的实现机制是代理模式(为其余对象提供一种代理以管制对这个对象的拜访).

故事了解:
校园代理是为他对应的下属作代理,而这个校园代理的工作就是拜访校园中的学生,例如对学生进行问卷之类的事。学生就是官网说法中的其余对象,校园代理的下属就通过管制这个校园代理来管制对学生的拜访。

常见实例:
ActivityManagerProxy 类就是一个代理,它是 ActivityManagerNative 的代理,也就是说 ActivityManagerProxy 是所说的 Proxy 类,而 ActivityManagerNative 就相当于“下属角色“类,它们都有一个共有的接口 IActivityManager。ActivityManager,它相当于代理模式的 client。在这个类中,能够看到大量的 getxxx 函数,这些函数,都会调用到 ActivityManagerNative 类的 getDefault()办法,而该办法会取得一个共用的单例的 IActivityManager 援用,而后通过多态来调用代理中的实现

实用场景:
代理模式的利用场合分几种: 近程代理,虚构代理,平安代理等,具体可见为他人做嫁衣 —- 代理模式请看上面一张结构图(网上看到的一个粗疏活泼的例子):

Subject 类:定义了 RealSubject 和 Proxy 的共用接口,这样就能够在任何 应用 RealSubject 的中央都能够用 Proxy。
RealSubject 类:定义 Proxy 所代表的实在实体。
Proxy 类:保留一个援用使得代理能够拜访实体,并提供一个与 Subject 的接口雷同的接口,这样代理就能够用来代替实体。
接下来,咱们来实现该模式:

1`
.Subject 类:Image.java

/**

  • Subject 类
    */

public abstract class Image {

public abstract void displayImage();

}

2.RealSubject 类:RealImage.java

import com.andyidea.patterns.subject.Image;

/**

  • RealSubject 类
    */

public class RealImage extends Image {

private String filename;
public RealImage(String filename) {
    this.filename = filename;
    loadImageFromDisk();}

private void loadImageFromDisk() {System.out.println("Loading" + filename);
}

@Override public void displayImage() {System.out.println("Displaying" + filename);
}

}

3.proxy 类:ProxyImage.java

import com.andyidea.patterns.realsubject.RealImage;
import com.andyidea.patterns.subject.Image;

/**

  • Proxy 类
    */

public class ProxyImage extends Image {

private String filename;
private Image image;

public ProxyImage(String filename) {this.filename = filename;}

@Override public void displayImage() {if (image == null) {image = new RealImage(filename);
    }
    image.displayImage();}

}

4. 客户端测试类:ProxyClient.java

import com.andyidea.patterns.proxy.ProxyImage;
import com.andyidea.patterns.subject.Image;

/**

  • 代理模式客户端测试类
    */

public class ProxyClient {

public static void main(String[] args) {System.out.println("Welcome to my Blog!" + "\n" + "Proxy Patterns." + "\n" + "-------------------------------");

    Image mImage1 = new ProxyImage("My.Image1");
    Image mImage2 = new ProxyImage("My.Image2");

    mImage1.displayImage();
    mImage2.displayImage();}

}

运行后果如下:

Welcome to my Blog!

Proxy Patterns

Loading My.Image1
Displaying My.Image1
Loading My.Image2
Displaying My.Image2

总结来说,代理类就是对实体保留一个援用,同时也实现了实体一样的接口办法,这样,就能够代替实体了!!

以上就是观察者模式,适配器模式,代理模式的意识

如果感觉此文不错,麻烦帮我点下“喜爱”。么么哒!

退出移动版