目录
单例模式:
饿汉式:
懒汉式:
双重校验锁(DCL):
静态内部类:
建造者模式(Builder模式):
观察者模式:
策略模式:
在Android中常用的设计模式有:单例模式,工厂模式,观察者模式等,下面根据具体案例深刻了解模式具体的表现:
单例模式存在的意义主要就是保证有且仅有一个对象,只创建一个,所有想要拿到该单例的都是同一个对象。
优点:
1).由于单例模式在内存中只有一个实例,减少了内存开销。对于那些耗内存的类,只实例化一次,大大提高性能,尤其是移动开发中。
2).单例模式可以避免对资源的多重占用,例如一个写文件时,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
3).单例模式可以在系统设置全局的访问点,优化和共享资源访问。
public class EHanSingleton {
//在类初始化时,已经自行实例化,所以是线程安全的。
private static final EHanSingleton single =new EHanSingleton();
public static EHanSingleton getInstance(){
return single;
}
}
优点:写法简单,线程安全。
public class LanHanSingleton {
private static LanHanSingleton singleton;
public static synchronized LanHanSingleton getSingleton(){
if (singleton == null){
singleton =new LanHanSingleton();
}
return singleton;
}
}
public class DoubleCheckSingleton {
private volatile static DoubleCheckSingleton singleton;
public static DoubleCheckSingleton getInstance(){
if (singleton == null){
synchronized (DoubleCheckSingleton.class){
if (singleton == null){
singleton =new DoubleCheckSingleton();
}
}
}
return singleton;
}
}
public class StaticInnerSigleton {
public static StaticInnerSigleton getInstance(){
return StaticInner.single;
}
//静态内部类
private static class StaticInner{
private static final StaticInnerSigleton single =new StaticInnerSigleton();
}
}
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
public class UserInfo {
private String name;
private int age;
private double height;
private double weight;
private UserInfo(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 UserInfo build() {
return new UserInfo(this);
}
}
}
//创建
UserInfo.Builder builder=new UserInfo.Builder();
UserInfo person=builder
.name("张三")
.age(18)
.height(178.5)
.weight(67.4)
.build();
//获取UserInfo的属性
Log.e("userinfo","name = "+person.getName());
Android中很多地方运用了Builder模式,比如常见的对话框创建/Okhttp等
AlertDialog.Builder builder=new AlertDialog.Builder(this);
AlertDialog dialog=builder.setTitle("对话框")
.setIcon(android.R.drawable.ic_dialog)
.setView(R.layout.custom_view)
.setPositiveButton(R.string.positive, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setNegativeButton(R.string.negative, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.create();
dialog.show();
Request.Builder builder=new Request.Builder();
Request request=builder.addHeader("","")
.url("")
.post(body)
定义:对象间一种一对多的依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
运用的场景:广播,EventBus等都是观察者模式
主要包括四个部分:
1. Subject被观察者。是一个接口或者是抽象类,定义被观察者必须实现的职责,它必须能偶动态地增加、取消观察者,管理观察者并通知观察者。
2. Observer观察者。观察者接收到消息后,即进行update更新操作,对接收到的信息进行处理。
3. ConcreteSubject具体的被观察者。定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
4. ConcreteObserver具体观察者。每个观察者在接收到信息后处理的方式不同,各个观察者有自己的处理逻辑。
模拟场景:天气预报,每次天气更新都会向你及时发送消息,观察者们就要更新界面。写法如下:
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 + '\'' +
'}';
}
}
然后定义我们的被观察着,我们希望它能够通用,所以定义成泛型,内部应该暴露出register和unRegister供观察者订阅和取消订阅,至于观察者的保存,我们用ArrayList即可,另外,当主题发生变化的时候,需要通知观察者来做出响应,还需要一个notifyObservers方法,具体实现如下:
public class Observable {
List> mObservers = new ArrayList>();
public void register(Observer observer) {
if (observer == null) {
throw new NullPointerException("observer == null");
}
synchronized (this) {
if (!mObservers.contains(observer))
mObservers.add(observer);
}
}
public synchronized void unregister(Observer observer) {
mObservers.remove(observer);
}
public void notifyObservers(T data) {
for (Observer observer : mObservers) {
observer.onUpdate(this, data);
}
}
}
而我们的观察者只需要实现一个观察者的接口Observer,该接口也是泛型的
public interface Observer {
void onUpdate(Observable observable,T data);
}
调用:
public class Main {
public static void main(String [] args){
Observable observable=new Observable();
Observer observer1=new Observer() {
@Override
public void onUpdate(Observable observable, Weather data) {
System.out.println("观察者1:"+data.toString());
}
};
Observer observer2=new Observer() {
@Override
public void onUpdate(Observable 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);
}
}