还不知道怎么重构吗?

宏观

重构需要明白的知识点

• 为什么重构,重构的是什么,什么时候重构,怎样重构

• 重构:大规模重构,小规模重构

• 通过单元测试保证重构的质量

封装,抽象,继承,多态分别解决那些编程问题?

  • 封装 : 通过对访问权限控制来实现封装,封装的意义在于暴露少许接口或属性,避免业务调用者在不理解业务的前提下对接口或属性业务做修改。封装目的是:隐藏信息,保护数据,public private protected
  • 抽象: 通过 interface 或 abstract 或一个函数都能实现抽象特性。 抽象的意义:让开发者只关注功能点,不关注实现的设计思路,这样做的好处帮助我们过滤掉不必要的信息,抽象无处不在(方法命名也是抽象,所以经常被认为不是面向对象编程特性之一)
  • 继承: Java 中通过 extend 实现继承特性,继承意义:is a 的关系,提高代码复用。(继承不要过度使用,可以使用组合代替继承,继承耦合性太高。)
  • 多态: 继承,重写,接口都可以实现动态,多态意义:可扩展和复用,可扩展在第二个例子中使用接口实现多态,如果需要扩展只需要添加一个实现类,而对于 print 方法里的业务逻辑是不需要改动的。所以也是实现代码复用性

继承+重写实现实现多态

根据上面的代码需要满足以下语法机制

• 父类对象可以引用子类对象

DynamicArray dynamicArray = new SortedDynamicArray();

• 编程语言中可以使用继承,子类继承父类

public class SortedDynamicArray extends DynamicArray

只要这样才可以让 SortedDynamicArray 传递给 DynamicArray

DynamicArray dynamicArray = new SortedDynamicArray();
test(dynamicArray); // 打印结果:1、3、5
public static void test(DynamicArray dynamicArray) {
dynamicArray.add(5);
dynamicArray.add(1);
dynamicArray.add(3);
for (int i = 0; i < dynamicArray.size(); ++i) {
System.out.println(dynamicArray[i]);
}
}

• 子类可以重写父类方法 SortedDynamicArray 重写 DynamicArray 方法

public class SortedDynamicArray extends DynamicArray {
@Override public void add(Integer e) {
ensureCapacity();
for (int i = size-1; i>=0; --i) { // 保证数组中的数据有序
if (elements[i] > e) {
 elements[i+1] = elements[i];
else {
 break;
}
}
elements[i+1] = e;
++size;
}
}

接口实现多态

面向对象比面向过程优势是什么?

• 基本区别:代码组织的方式不同,面向过程中方法和数据结构是分开的。面向对象的代码被组织成一组类,方法和数据结构被绑定在一起,定义在类中。

• OOP 面对复杂的业务逻辑则凸显出优势,1 把需求翻译为类 2 类之间建立交互关系 3 按照流程组装类。

• OOP 具有四大特性,封装 抽象 继承 多态

• OOP 更加人性化

常见违反面向对象规则

• 滥用 get 和 set 方法

• 对公共类没有做到单一职责原则

• 贫穷模式开发:指开发模式是面向过程开发,例如 mvc

接口与抽象类区别

抽象类如何定义

abstract 修饰;不允许实例化,只能被继承;可以有方法体和属性;子类继承父类必须实现父类中的抽象方法 抽象类表示 is-a 关系

public class MessageQueueLogger extends Logger
(Logger logger = new Logger(…); 会报编译错误
protected abstract void doLog(Level level, String message);
@Override
public void doLog(Level level, String mesage) {
// 格式化 level 和 message, 输出到日志文件
fileWriter.write(...);
}

接口如何定义

• 接口里面不能有属性和方法体

• 类实现接口,必须实现接口中的方法体

• 接口是 has -a 关系

抽象类和接口能解决什么编程问题

• 因为抽象类可以继承,所以拥有代码复用的特性,当然不止有这个好处,否则我们直接继承类就可以。另一个好处就是实现多态的特性

当下面代码调用的时候会报错,是因为 logger 父类中没有 log()方法

• 接口:抽象类更多的是代码复用,接口更偏向于解耦。

如何决定要抽象类还是接口

抽象类

• 解决代码复用问题

• is-a 关系

接口

• 解决抽象问题

• has-a 关系

为什么基于接口编程而非实现编程,有必要为每个类都定义接口吗

基于接口而非实现编程,这句话可以理解为基于抽象而非实现编程。

需求

把以前通过阿里云上传下载的代码修改为私有服务器上传和下载,下面图片是上传阿里云的代码

解决方案

如果想解决这个问题,在编写代码的时候我们要遵循基于接口而非实现编程的原则

• 函数命名不能保留任何实现细节

• 封装具体的实现细节,例如对于一些特殊的实现我们要封装。不要暴露给调用者,例如图片中的获取 token 相关信息

• 为实现类定义抽象接口。接口的定义只表明做什么,而不是怎么做。并且要思考是否通用,当新添加新的实现不会修改接口

什么时候定义接口

• 接口和实现相分离,封装不稳定的实现,暴露稳定的接口

参考资料

  • 设计模式之美
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王雪芬-Judy领袖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值