Design

面向对象设计六大原则

涉含MVVM

volley 为例

  • 单一职责原则 Single Responsibility Principle
    简单的说一个类只做一件事。
    在volley中,例如HttpStack ,定义了一个执行网络请求的接口:

    public interface HttpStack {
        //执行一个http请求,并且返回一个httpResponse
        public HttpResponse performRequest(Request<?> request, Map<String, string> additionalHeaders)
            thorws IOException,AuthFailureError;
    }
    

    可以看到HttpStack 只有一个函数,用来执行网络请求并返回一个response。
    保证了代码的可维护性。单一职责原则并不是说一个类只有一个函数,而是说这个类中的
    方法必须是高度相关的,也就是高内聚。

    优点:

    - 类的负责性降低,实现功能更加明确;
    - 可读性高,复杂性降低;
    - 可维护性提高;
    - 变更引起的风险降低
    
  • 里氏替换原则 Liskov Substitution Principe
    里氏替换原则依赖Java的继承和多态这两个特性。简单的说就是:
    所有引用基类的地方必须能透明的使用其子类的对象。
    通俗点,就是只要父类能出现的地方子类就可以出现,而且替换为子类也不会有
    任何错误或异常。但是反过来就不行。

    示例:在volley中,定义了HttpStack来表示执行网络请求这个抽象概念。在执行网络
    请求时,只需要定义一个HttpStack对象,然后调用performRequest即可。

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
        File cacheDir = new File(context.getCacheDir(),DEFAULT_CACHUE_DIR);
        String userAgent = "volley/0";
        ...
        //1. 构造HttpStack对象.
        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                //
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }
        //2. 将HttpStack对象传递给Network对象.
        Network network = new BasicNetwork(stack);
        //3. 将network 对象传递给忘了你请求队列.
        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();
        return queue;
    
    }
    

    BasicNetwork的代码如下:

    /**
    * a network performing Volley requests over an{@link HttpStack}
    */
    public class BasicNetwork implements Network {
        //HttpStack抽象对象
        protected final HttpStack mHttpStack;
        protected final ByteArrayPool mPool;
        public BasicNetwork(HttpStack httpStack) {
            this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE));
        }
        public BasicNetwork(HttpStack httpStack, ByteArrayPool pool) {
            mHttpStack = httpStack;
            mPool = pool;
        }
    }
    

    BasicNetwork构造函数依赖的是HttpStack抽象接口,任何实现了HttpStack接口的类型都可以作为参数传递
    给BasicNetwork用以执行网络请求。

    这就是里氏替换原则,任何父类出现的地方,子类都可以出现,保证了扩展性。

    优点:

    * 代码共享,减少创建类的工作量。
    * 提高代码重用性
    * 提高代码的可扩展性
    * 提高产品或项目的开放性
    

    缺点:

    * 继承是侵入性的,只要继承,就必须拥有父类的属性和方法。
    * 降低了代码的灵活性。
    * 增强了耦合性.
    
  • 依赖倒置原则 Dependence Inversion Principle

几个关键点如下:

  • 高层模块不应该依赖底层模块,两者都应该依赖其抽象
  • 抽象不应该依赖细节
  • 细节应该依赖抽象

在Java语言里,抽象就是指接口或抽象类,两者都是不能直接被实例化的;
细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以
直接被实例化,也就是可以加上一个关键字new产生一个对象。依赖倒置原则在
Java语言中的表现就是:模块间的依赖通过抽象发生,实现类之间不发生直接关系。
其依赖关系是通过接口或抽象类产生的。就是:面向接口编程,或者说是面向对象编程,
这里的抽象指的是接口或是抽象类。

优点:

  • 可扩展性好
  • 耦合度低

开闭原则

  • 开闭原则 Open Close Principle
    开闭原则的定义是:一个软件实体如类、模块和函数应该对扩展开发,对修改关闭。
    优点:
  • 增加稳定性
  • 可扩展性高

接口隔离原则 Interface Segregation Principle

客户端不应该依赖它不需要的接口;一个类对另外一个类的依赖应该建立在
最小的接口上。根据接口隔离原则,当一个接口太大时,需要将它分割成
一些更细小的接口,使用该接口的客户端仅需要知道与之相关的方法即可.

迪米特原则 Law of Demeter

也称最小知识法则。:一个对象应该对其他对象有最小的了解
也就是说,一个类应该对自己需要耦合或调用的类知道得最小。有些类似
接口隔离原则中最小接口的概念。
类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类
的影响也越大。

waiting