上一次关于技术分享的博客还是在一年前,最近没写博客的原因一个就是工作忙,没时间写;还有就是最近在做PC端的应用开发,Android很少去写代码。PC端主要是用C#编写的桌面应用,Android是使用Java编写的移动端App,其实现在一想,C#和Java其实本源是一致的,都是面向对象编程,从架构的维度来看,都是可以做工程化的语言,而架构最注重的就是设计模式。

1 为什么要看源码?

看源码除了看这个框架的原理之外,还有就是能够接触到丰富的设计模式。可能在项目开发过程当中,没有过分注重这些,单例模式用到飞起,其他的设计模式一概不知,这就是对设计模式的不熟悉,针对特定的场景使用对应的设计模式,对后续的迭代很有帮助,这也是通向高级开发、架构师这条道路上的必经之路,虽然这部分知识很枯燥,但是是每个工程师必须灵活掌握的,面试必问的问题。

2 面向对象的6大原则

solid(坚硬的,坚固的),教大家快速记住6大原则,s(single responsibility 单一职责原则)、o(open close 开闭原则)、l(liskov substitution 里式替换原则)、i(interface 接口隔离原则)、d(dependency 依赖倒置原则)、迪米特原则,牢牢记住面向对象的6大设计原则,代码的健壮性才能得到保证,才足够坚固。

2.1 单一职责原则

单一职责,从字面意思上来看就是只负责自己的事情。对于一个类来说,越简单越好,一个类T负责职责P,这样做的好处就是,如果T负责P1和P2,会导致P1改动的时候,影响P2的功能使用。

2.2 开闭原则

这个原则是6大设计原则中,最重要的一个原则,这对于代码的扩展性和灵活性有很大的帮助,面向扩展开放,面向修改关闭,总的来说就是面向接口编程。

拿网络库来说,除了原生的HttpUrlConnection,还有一些成熟的框架OkHttp、Retrofit等,在封装网络库时,我第一版使用的是OkHttp,第二版迭代我要用Retrofit,第三版我要用RxJava + Retrofit + OkHttp,如果没有考虑到开闭原则,势必要在原有的网络库上做大手术,这是有风险的。

public interface IHttpRender {

    void get();

    void post();
}
public class OKHttpRequest implements IHttpRender{


    @Override
    public void get() {

        Log.e("TAG","OKHttpRequest get");
    }

    @Override
    public void post() {

        Log.e("TAG","OKHttpRequest post");

    }
}
public class RetorfitRequest  implements IHttpRender{

    @Override
    public void get() {

        Log.e("TAG","RetorfitRequest get");
    }

    @Override
    public void post() {
        Log.e("TAG","RetorfitRequest post");
    }
}
public class HttpUtils {

    private  IHttpRender mHttpRender;

    public HttpUtils(){}

    public void setHttpRequest(IHttpRender mHttpRender){

        this.mHttpRender = mHttpRender;
    }

    public void post(){

        mHttpRender.post();
    }
}

在使用网络请求时,可以根据现有的场景,选择想要使用的框架。在修改网络请求框架时,并不影响应用层的代码

 HttpUtils httpUtils = new HttpUtils();
 //在此选择想要使用的网络请求框架
 httpUtils.setHttpRequest(new OKHttpRequest());
 httpUtils.post();
E/TAG: OKHttpRequest post

2.3 里式替换原则

简单来说就是,只要父类出现的地方,子类就可以出现。在上边的代码中,其实已经体现出了这一点。
HttpUtils中,定义了一个方法setHttpRequest,其中形参是IHttpRender,那么我在传值的时候,就可以传入IHttpRender的子类例如OKHttpRequest,这其实就是继承和多态的体现。

2.4 依赖倒置原则

高层不依赖低层的细节,而是依赖低层的抽象,什么意思?
HttpUtils (高层) IHttpRender OKHttpRequest(低层),在HttpUtils中,依赖的是IHttpRender,而跟OKHttpRequest具体怎么实现无关,只是依赖他们的父类抽象。

2.5 接口隔离原则

其实跟单一职责原则相像,在实际开发过程中,需要的是小接口,尽可能的将接口拆分,接口中的方法要和接口的实现类相关,无关的不要放进接口,因为需要重新方法。

2.6 迪米特原则

类与类之间的耦合度越小越好,避免牵一发而动全身。

3 链式调用

其实对于链式调用,往往用于大量参数配置的场景中,像OkHttp配置各类参数,在封装网络库时,尽量避免在方法的形参列表中出现太多的参数信息,优先使用链式调用。

class HttpRequest
    {

        //请求的方式
        private const int GET_TYPE = 0x0011;
        private const int POST_TYPE = 0x0022;

        private int requestType = GET_TYPE;

        private JObject mParams;

        private string mUrl;

        public HttpRequest() {

            mParams = new JObject();
        }


        public HttpRequest get() {

            requestType = GET_TYPE;
            return this;
        }

        public HttpRequest post() {

            requestType = POST_TYPE;
            return this;

        }

        public HttpRequest url(string PostUrl) {

            this.mUrl = PostUrl;
            return this;

        }

        public HttpRequest setParams(string key, string value) {

            mParams.Add(key, value);

            return this;
        }

        public string request()
        {

            string result = "";
            try
            {
                ServicePointManager.Expect100Continue = false;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(mUrl);
                request.ServicePoint.Expect100Continue = false;//指定此属性为false  "application/json"
                //设置网络请求方式
                request.Method = requestType == GET_TYPE ? "GET" : "POST";
                request.ContentType = "application/json";
                var requestStream = request.GetRequestStream();


                StreamWriter streamWriter = new StreamWriter(requestStream, Encoding.GetEncoding("utf-8"));
                //请求的参数信息
                streamWriter.Write(mParams.ToString());
                streamWriter.Flush();
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                var responseStream = response.GetResponseStream();
                //StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                result = sr.ReadToEnd();

                Console.WriteLine("post请求返回的结果" + result);
            }
            catch (Exception e)
            {

                //出现网络异常
                //MessageBox.Show("上传脚本出现异常,请重试" + e.Message.ToString());
                Console.WriteLine("捕获异常----net:" + e.Message.ToString());
                return null;
            }

            return result;

        }
    }

这是用C#简单写了一个网络请求类,在这个类中,首先保证了单一职责的设计原则,其次在调用时,可通过链式调用,代码更简洁美观。

class HttpUtils
    {

        private HttpRequest mHttpRequest;


        public HttpUtils() {

            mHttpRequest = new HttpRequest();
        }

        public void request(string postUrl) {


            mHttpRequest.get()
                .url(postUrl)
                .setParams("124", "123")
                .setParams("123", "123")
                .request();
        }
    }
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐