java代码重构改善 java代码重用( 五 )


为了接口的演化
可以减少第三方工具类的创建
可以避免创建基类
由于接口的局限性和设计目的的不同 , 接口并不能完全替换抽象类 。但是通过对接口提供一个抽象的骨架实现类,可以把接口和抽象类的优点结合起来 。接口负责定义类型 , 或许还提供一些缺省方法,而骨架实现类则负责实现除基本类型接口方法之外 , 剩下的非基本类型接口方法 。扩展骨架实现占了实现接口之外的大部分工作 。这就是模板方法(Template Method)设计模式 。
Image [5].png
接口Protocol:定义了RPC协议层两个主要的方法,export暴露服务和refer引用服务
抽象类AbstractProtocol:封装了暴露服务之后的Exporter和引用服务之后的Invoker实例,并实现了服务销毁的逻辑
具体实现类XxxProtocol:实现export暴露服务和refer引用服务具体逻辑
由于为了保持Java代码的兼容性,支持和原生态类型转换,并使用擦除机制实现的泛型 。但是使用原生态类型就会失去泛型的优势 , 会受到编译器警告 。
每一条警告都表示可能在运行时抛出ClassCastException异常 。要尽最大的努力去消除这些警告 。如果无法消除但是可以证明引起警告的代码是安全的,就可以在尽可能小的范围中,使用@SuppressWarnings("unchecked")注解来禁止警告,但是要把禁止的原因记录下来 。
参数化类型不支持协变的,即对于任何两个不同的类型Type1和Type2而言,List既不是List的子类型,也不是它的超类 。为了解决这个问题,提高灵活性 , Java提供了一种特殊的参数化类型,称作有限制的通配符类型,即List? extends E和List? super E 。使用原则是producer-extends , consumer-super(PECS) 。如果即是生产者 , 又是消费者,就没有必要使用通配符了 。
还有一种特殊的无限制通配符List?,表示某种类型但不确定 。常用作泛型的引用,不可向其添加除Null以外的任何对象 。
嵌套类(nested class)是指定义在另一个类的内部的类 。嵌套类存在的目的只是为了它的外部类提供服务,如果其他的环境也会用到的话 , 应该成为一个顶层类(top-level class) 。嵌套类有四种:静态成员类(static member class)、非静态成员类(nonstatic member class)、匿名类(anonymous class)和 局部类(local class) 。除了第一种之外,其他三种都称为内部类(inner class) 。
总而言之 , 这四种嵌套类都有自己的用途 。假设这个嵌套类属于一个方法的内部,如果只需要在一个地方创建实例 , 并且已经有了一个预置的类型可以说明这个类的特征,就要把它做成匿名类 。如果一个嵌套类需要在单个方法之外仍然可见,或者它太长了 , 不适合放在方法内部,就应该使用成员类 。如果成员类的每个实例都需要一个指向其外围实例的引用,就要把成员类做成非静态的 , 否则就做成静态的 。
通过对常见场景的代码逻辑进行抽象封装,形成相应的模板工具类,可以大大减少重复代码,专注于业务逻辑,提高代码质量 。
面向对象编程相对于面向过程,多了实例化这一步,而对象的创建必须要指定具体类型 。我们常见的做法是“哪里用到,就在哪里创建” , 使用实例和创建实例的是同一段代码 。这似乎使代码更具有可读性,但是某些情况下造成了不必要的耦合 。
对于顶层的(非嵌套的)类和接口,只有两种的访问级别:包级私有的(没有public修饰)和公有的(public修饰) 。
对于成员(实例/域、方法、嵌套类和嵌套接口)由四种的访问级别 , 可访问性如下递增:

推荐阅读