Android编程思想,面向对象程序设计第一篇——设计模式6个原则

    做了几年的安卓,发现很多安卓从业者并不是计算机科班出身,很多都是转业或者在培训机构培训之后成为了一名安卓开发者。比较多的初级开发者只对安卓API有一定的了解。但是对于整个项目的程序设计并不是清楚,导致出现项目代码混乱,代码可扩展性、可维护性、可读性都比较差。

    怎么解决这些问题呢?

   首先推荐一本费里曼的书《Head First》,这是一本关于设计模式的书。作者由非常生动而简单的生活故事抛出问题,从而用设计模式解决问题,把高深的知识讲解的简单而有趣。真是非常佩服老外的功力,真是循循善诱。

首先让我们学习一下6个设计原则:

1.单一职责原则

    一个对象最好拥有尽量少的职能,避免各个只能之间互相影响。所谓的职能是对这个类的外部而说的而不是对于类的内部而言的职能。

public classDownloadFileRequest{

private String mFileUrl;

private Context mContext;

publicDownloadFileRequest(Context context){

mContext = context;

}


public void startDownloadFile(){


}


public void stopDownloadFile(){

}

}

比如在这段代码里面,只有一个文件下载功能,startDownloadFile()和stopDownloadFile()不能算是两个功能,因为

他们两都是围绕着文件下载的生命周期的。假如在这个类里面添加一个上传文件功能uploadFile()就不合适了。因为他就是另外一个功能,比如你下载完文件想将这个对象或者对象里面持有的context销毁就会影响到上传的功能,导致上传功能对context的引用抛出空指针。这就不利于两个功能的解耦,也不利于对象的回收。


2.里氏替换原则

    子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法;子类中可以增加自己特有的方法;当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松;当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

3.依赖倒置原则

 抽象不应该依赖细节;细节应该依赖抽象。这个原则的意思是,一个类的主要业务逻辑要抽象出来,只有要用到具体参数的地方才到具体的类中去实现。以实现更多的代码复用和更简单的扩展。别人来继承你的类的时候只需要实现你的抽象方法就可以了,而不需要去理解太多你的业务逻辑。

以下代码可以不用细看

public abstract class ProtocolBase {


public static final String NAME_ACTION = "action";
public static final String NAME_PARAMS = "params";
public static final String NAME_STATE  = "state";
public static final String NAME_DATA   = "data";
public static final String NAME_MSG    = "msg";

public static final KeyValuePair<Integer, Object> ERROR = new KeyValuePair<Integer, Object>(-1, "Error");

public boolean mCancel;

public interface IProtocolListener{
void onSuccess(Object resultData);
void onFailure(int state, String errMsg);
}

protected Context mContext;
protected IProtocolListener mListener;

public ProtocolBase(Context context, IProtocolListener listener){
mContext = context;
mListener = listener;
}


public void postRequest(){
String strArray = generateParams().toString();
ByteArrayEntity reqEntity = null;
try {
reqEntity = new ByteArrayEntity(strArray.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
HttpClientInst.post(mContext, Config.BASE_URL, reqEntity, new AsyncHttpResponseHandler() {

@Override
public void onSuccess(int state, Header[] headers, byte[] response) {
if(mCancel) return;
if(state == 200){
try {
String str = new String(response, getCharset());
JSONArray responseArray = new JSONArray(str);
Object resultData = parseResult(responseArray);
if(resultData == null){
if(mListener != null){
mListener.onFailure(-1, "数据解析出错");
}
}else{
if(null != responseArray && responseArray.length() > 0){
int stateCode = responseArray.optJSONObject(0).optInt(NAME_STATE);
if(stateCode == 400){
ToastUtils.showLongToast(mContext, "登录过期或账号在其他设备登录!");
ActivityUtils.startLoginActivity(mContext, "", "", false);
UserManager.getInst().setLoginOutOfDate();
}
}
KeyValuePair<Integer, Object> kv = (KeyValuePair<Integer, Object>) resultData;
if(kv == null || kv.first != 200){
if(mListener != null){
if(kv.second != null && kv.second instanceof String){
mListener.onFailure(kv.first, (String)kv.second);
}else{
mListener.onFailure(kv.first, "数据解析出错");
}
}
}else if(mListener != null){
try {
mListener.onSuccess(resultData);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
if(mListener != null){
mListener.onFailure(-1, "数据解析出错");
}
}
}else{
//应该不会走到这里才对
if(mListener != null){
mListener.onFailure(state, "网络请求错误!");
}
}
}

@Override
public void onFailure(int state, Header[] header, byte[] errorBytes, Throwable throwable) {
if(mCancel) return;
if(mListener != null){
mListener.onFailure(state, "网络请求错误!");
}
}
});
}

public void setCancel(boolean cancel){
mCancel = cancel;
}

public abstract Object parseResult(JSONArray resultArray);

public abstract JSONArray generateParams();

}


这是一个post请求类,具体的请求只需要继承这个类,实现parseResult()解析返回的数据结果,实现generateParams()传入要上传的参数,和然后调用 postRequest()这个方法就行了。而具体是怎么进行的请求步骤和怎么返回结果,怎么又把结果转成了json,这些业务逻辑统统不需要去理会。这就是遵循依赖倒置原则的好处。

4.接口隔离原则

  接口隔离原则就是一个接口最好只有一个类的尽量少的功能,而不要太多的功能使用同一个接口,或者多个不同的类使用同一个接口。

  就好比人和鱼,人有嘴巴吃饭和鼻子呼吸,鱼也用嘴巴吃但呼吸却是用鱼鳃。所以这两个类就不能用同一个接口。如果用同一个接口就得实现用嘴巴吃,用鼻子呼吸,用腮呼吸着三个方法。但是鱼是不能用嘴巴呼吸的,人也不能用腮呼吸。所以各自包含着一个没用的方法。

  所以宁愿多建立几个接口也不要多个功能用同一个接口。

5.迪米特法则

 迪米特法则的意思是一个类应该尽量少的把自己的内部业务逻辑暴露出去,而是只要让别人知道调用你的什么方法会处理什么事情就好了。

6.开闭原则

 (1)对于扩展是开放的(Open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们在封装类的时候要尽量把眼光放长远一点,对产品接下来会做怎么的扩展有一定的预见性,保留扩展功能的能力。另一方面就是在封装类的时候要有普遍通用性,不能封装了一个类在这种情况下可以用,添加了一个属性之后就不能用了。

    (2)对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。也就是说拓展的时候多用继承而不要用太多的修改,继承之后可以在子类添加父类没有的方法。而不要太大的去改动原来的代码逻辑。

设计模式的6个原则是android代码设计的法则,后面的设计模式和java语言特性带来的设计思想,所有内容无一例外都要遵循这些原则,只不过是更细致到具体的应用细节而已。

设计原则就先讲到这里,接下来会讲设计模式,我们下一节见

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闽农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值