您的位置:首页 > 编程语言 > Java开发

粗浅例子解释MVP实际应用

2017-05-17 11:37 323 查看
  接口 类似于抽象类,但是在接口里,方法是没有方法体的,都是抽象方法。但是在抽象类中,只要有抽象方法的类就是抽象类,也就是可以有方法体的。传说中的MVP,其实也就是如此了。

  接口是用来处理C++中多继承的情况的。Java中是没有多继承的,只有单继承。

  自己总结了一下接口的特性:

  a. 接口的访问修饰符可以是public 或者是默认修饰符default,只能是这两种

  b. 在接口中可以声明变量,但是这些变量时隐式的被声明为public static final(静态常量)的,且必须赋予定值。

  c. 接口可以扩展,如interface A extends B。

  d. 相比于抽象类,使用接口可以更大的降低耦合度且增加扩展性。这也是本篇要讲的重点。

  注意:一般情况下,当有相同特性或操作的事物时,可以声明接口用来抽象化这些事物,这样做能够大大增加代码的美感。

  

  好了,开始我自己的例子吧:

  背景:获取多个不同的传感器数据,一般包括初始化–>运行–>停止释放

1) 首先,声明接口:

  

/**
* 提供要初始化和运行的设备,字段包括:
* TYPE_MAGNETIC_FIELD 电磁
* //TYPE_ACCELEROMETER 加速度1
* TYPE_LINEAR_ACCELERATION 加速度2
* TYPE_GYROSCOPE 陀螺仪
* LOCATION_SERVICE GPS
* TYPE_MULTIMEDIA 多媒体
* 调用步骤为 initFacility--> startRun -->  release
*/
public interface IFacility {
String TYPE_MAGNETIC_FIELD = "TYPE_MAGNETIC_FIELD";
//    String TYPE_ACCELEROMETER = "TYPE_ACCELEROMETER";
String TYPE_LINEAR_ACCELERATION = "TYPE_LINEAR_ACCELERATION";
String TYPE_GYROSCOPE = "TYPE_GYROSCOPE";
String LOCATION_SERVICE = "LOCATION_SERVICE";
String TYPE_MULTIMEDIA = "TYPE_MULTIMEDIA";

void initFacility(String facilityName, Handler handler);

boolean startRun();

void release();

int getMinTime();

void setMinTime(int minTime);
}


2) 实现接口,可以有多个设备:

public class GPSFacility implements IFacility {
private static String TAG = "GPSFacility";
private static int minTime = 1000 / 3;
public GPSFacility(Context context) {
this.context = context;
}
...
@Override
public void initFacility(String ffacilityName, final Handler fhandler) {
...
}

@Override
public boolean startRun() {
...
}

@Override
public void release() {
...
}

@Override
public int getMinTime() {
return minTime;
}
}


3) 声明设备初始化管理工厂:

/**
*
* 接口中的字段目的是提供设备字典,用来后面判断传出的数据是哪个设备的。
* 这样的好处是,设备相关类可以被隐藏,而是通过工厂中字典来判断。工厂类使用接口,考虑到扩展性。
*/
public interface IFactory {
String TYPE_MAGNETIC_FIELD = "TYPE_MAGNETIC_FIELD";
String TYPE_ACCELEROMETER = "TYPE_ACCELEROMETER";
String TYPE_LINEAR_ACCELERATION = "TYPE_LINEAR_ACCELERATION";
String TYPE_GYROSCOPE = "TYPE_GYROSCOPE";
String LOCATION_SERVICE = "LOCATION_SERVICE";
String TYPE_MULTIMEDIA = "TYPE_MULTIMEDIA";

IFacility getFacility(Context context, String facilityName);
}


public class FacilityFactory implements IFactory {
@Override
public IFacility getFacility(Context context, String facilityName) {
Field[] fields = IFacility.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
if (TYPE_MAGNETIC_FIELD.equals(facilityName)) {
return new SensorFacility(context);
} else if (TYPE_ACCELEROMETER.equals(facilityName) || TYPE_LINEAR_ACCELERATION.equals(facilityName)) {
return new SensorFacility(context);
} else if (TYPE_GYROSCOPE.equals(facilityName)) {
return new SensorFacility(context);
} else if (LOCATION_SERVICE.equals(facilityName)) {
return new GPSFacility(context);
} else if (TYPE_MULTIMEDIA.equals(facilityName)) {
return null;
}
}
return null;
}
}


4)声明业务类,在业务类中操作所有设备

package com.wkw.presenter.clientbusiness
...
public void initFacilityList(Context context, Handler handler) {
...
facilities = new ArrayList<IFacility>();
for (int i = 0; i < IFacility.class.getDeclaredFields().length; i++) {
IFacility facility = facilityFactory.getFacility(context, IFacility.class.getDeclaredFields()[i].getName());
if (facility != null) {
facility.initFacility(IFacility.class.getDeclaredFields()[i].getName(), handler);
facilities.add(facility);
}
}
...
}

public void startAll() {
synchronized (lock) {
if (null != facilities)
for (IFacility it : facilities) {
it.startRun();
}
}
}

public void releaseAll() {
synchronized (lock) {
if (null != facilities) {
for (IFacility it : facilities) {
it.release();
}
}
}
}


  好了,到这里,所有设备都能够通过工厂类进行操作了,耦合度低的同时,扩展性也很高。后面如果有新加或删除设备,直接到IFacility、IFactory、FacilityFactory中添加相应设备名或操作即可。完全不需要在业务类中进行修改。

  最后,推荐一本书《代码整洁之道》,我还没开始看呢。不过,为了能够更好得混迹于程序界,大家一起学习吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JAVA接口 代码设计