Skip to content

Commit

Permalink
auto commit
Browse files Browse the repository at this point in the history
  • Loading branch information
CyC2018 committed Mar 4, 2018
1 parent dc31eaa commit a22f778
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 13 deletions.
57 changes: 44 additions & 13 deletions notes/重构.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,37 +109,68 @@

在重构前,需要先构建好可靠的测试环境,确保安全地重构。

重构是以微小的步伐修改程序,如果犯下错误,很容易便可以发现它
重构需要以微小的步伐修改程序,如果重构过程发生错误,很容易就能发现错误

**案例分析**

影片出租店应用程序,包括三个类:Movie、Rental 和 Customer,Rental 包含租赁的 Movie 以及天数
影片出租店应用程序,需要计算每位顾客的消费金额

<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//a758c8b2-0ac7-438f-90c2-3923ffad6328.png"/> </div><br>
包括三个类:Movie、Rental 和 Customer,Rental 包含租赁的 Movie 以及天数。

最开始的实现是把所有的计费代码都放在 Customer 类中,在变化发生时,需要对这部分代码进行更改。本案例中可能发生的变化有:一种类别的计费方式发生改变;添加新的电影类别。考虑到计费代码可能存在于多处,一旦发生改变时,就需要对所有计费代码进行修改。
<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//25d6d3d4-4726-47b1-a9cb-3316d1ff5dd5.png"/> </div><br>

<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//9e5e3cc6-3107-4051-b584-8ff077638fe6.png"/> </div><br>
最开始的实现是把所有的计费代码都放在 Customer 类中。

以下是继承 Movie 的多态方案。但是由于一部 Movie 的类别会动态改变,因此这种方案不可行
可以发现,该代码没有使用 Customer 类中的任何信息,更多的是使用 Rental 类的信息,因此第一个可以重构的点就是把具体计费的代码移到 Rental 类中,然后 Customer 类的 getTotalCharge() 方法只需要调用 Rental 类中的计费方法即可

<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//2a502516-5d34-4eef-8f39-916298a60035.png"/> </div><br>

引入 Price 来反应类别信息,通过组合的方式在 Movie 中加入 Price 对象,这样每种类别的计费方式都封装在不同的 Price 子类中,并且 Movie 对象也可以动态改变类别。这种方式可以很好地适应上述提到的变化。
```java
class Customer...
double getTotalCharge() {
while (rentals.hasMoreElements()) {
double thisAmount = 0;
Rental each = (Rental) rentals.nextElement();
switch (each.getMovie().getPriceCode()) {
case Movie.REGULAR:
thisAmount += 2;
if (each.getDaysRented() > 2)
thisAmount += (each.getDaysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
thisAmount += each.getDaysRented() * 3;
break;
case Movie.CHILDRENS:
thisAmount += 1.5;
if (each.getDaysRented() > 3)
thisAmount += (each.getDaysRented() - 3) * 1.5;
break;
}
}
```

使用 switch 的准则是:只能在对象自己的数据上使用,而不能在另一个对象的数据基础上使用。解释如下:switch 使用的数据通常是一组相关的数据,例如上面的代码使用了 Movie 的多种类别数据。当这组类别的数据发生改变时,例如上面的代码中增加 Movie 的类别或者修改一种 Movie 类别的计费方法,就需要修改 switch 代码。如果允许违反了准则,就会有多个地方的 switch 使用了这部分的数据,那么需要打开所有的 switch 代码进行修改。

以下是继承 Movie 的多态解决方案,这种方案可以解决上述的 switch 问题,因为每种电影类别的计费方式都被放到了对应 Movie 子类中,当变化发生时,只需要去修改对应子类中的代码即可。

<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//76b48b4c-8999-4967-893b-832602e73285.png"/> </div><br>

但是由于 Movie 可以在其生命周期内修改自己的类别,一个对象却不能在生命周期内修改自己所属的内,因此这种方案不可行。可以通过使用策略模式来解决这种问题(原书写的是使用状态模式,但是这里应该为策略模式,具体可以参考设计模式内容)。

下图中,Price 有多种实现,Movie 组合了一个 Price 对象,并且在运行时可以改变组合的 Price 对象,从而使得它的计费方式发生改变。

<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//c02a83b8-a6b9-4d00-a509-6f0516beaf5e.png"/> </div><br>
<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//2a842a14-e4ab-4f37-83fa-f82c206fe426.png"/> </div><br>

重构后的时序图和类图
重构后整体的类图和时序图如下

<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//95f4559c-3d2a-4176-b365-4fbc46c76cf1.png"/> </div><br>
<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//4440ad24-625b-489a-96c1-e5ab1b06a30f.png"/> </div><br>

<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//293b9326-02fc-4ad8-8c79-b4a7b5ba60d3.png"/> </div><br>
<br><div align="center"> <img src="https://github.com/CyC2018/InterviewNotes/blob/master/pics//8c139711-3500-4f71-8456-c1adaf429ad0.png"/> </div><br>

# 第二章 重构原则

重构是对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

重构的好处:改进软件设计;使软件更容易理解;帮助找到 bug;提高编程速度。
重构的好处:改进软件设计;使软件更容易理解;帮助找到 Bug;提高编程速度。

三次法则:第一次做某件事时只管去做;第二次做类似事情时可以去做;第三次再做类似的事,就应该重构。

Expand Down
Binary file added pics/25d6d3d4-4726-47b1-a9cb-3316d1ff5dd5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pics/2a842a14-e4ab-4f37-83fa-f82c206fe426.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pics/4440ad24-625b-489a-96c1-e5ab1b06a30f.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pics/76b48b4c-8999-4967-893b-832602e73285.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pics/8c139711-3500-4f71-8456-c1adaf429ad0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a22f778

Please sign in to comment.