设为首页 加入收藏

TOP

代码重构(三):数据重构规则(三)
2017-10-10 12:15:56 】 浏览:1304
Tags:代码 重构 数据 规则
extField! 5 @IBOutlet var secondNumberTextField: UITextField! 6 @IBOutlet var resultTextField: UITextField! 7 8 override func viewDidLoad() { 9 super.viewDidLoad() 10 } 11 12 //获取第一个输入框的值 13 func getFirstNumber() -> String { 14 return firstNumberTextField.text! 15 } 16 17 //获取第二个输入框的值 18 func getSecondNumber() -> String { 19 return secondNumberTextField.text! 20 } 21 22 //加数与被加数中的值改变时会调用的方法 23 @IBAction func textFieldChange(sender: AnyObject) { 24 self.resultTextField.text = calculate(getFirstNumber(), second: getSecondNumber()) 25 } 26 27 28 //计算两个数的值 29 func calculate(first: String, second: String) -> String { 30 return String(stringToInt(first) + stringToInt(second)) 31 } 32 33 //将字符串安全的转变成整数的函数 34 func stringToInt(str: String) -> Int { 35 guard let result = Int(str) else { 36 return 0 37 } 38 return result 39 } 40 }

 

2.对上述代码进行分析并重构

因为代码比较简单,所以很容易进行分析。在上述UI代码中,我们很清楚的看到后两个函数,也就是calculate()与stringToInt()函数是数据处理的部分,只依赖于数据,与UI关系不是很大,所以我们可以使用复制被监测数据规则将该段业务逻辑代码进行提取重构。重构后UI以及UI对外的工作方式不变。

下方的Calculate类就是我们提取的数据业务类,负责处理数据。在该类中我们创建了三个属性来与UI中的输入框进行对应,这也就是所说的复制“被监测的数据”。因为和也就是resultNumber是由firstNumber和SecondNumber计算而来的,所以我们就把resultNumber定义成了计算属性,而firstNumber和secondNumber为存储属性。并为存储属性提供setter方法。在Calculate类的构造函数中,我们为两个值指定了初始化数据也就是“0”。最下方的那两个函数就是我们从UI中直接拷贝过来的数据,一点没有修改,也是可以工作的,因为这部分代码只依赖于数据,而不依赖于UI。

    

创建为相应的业务逻辑处理类并提取完业务逻辑后,我们需要将业务逻辑中的数据,也就是复制过来的数据与UI中的数据提供者进行绑定,并返回计算结果。下方红框中就是我们要修改的部分,在UI中我们删除掉处理业务数据的代码,然后创建也给Calculate对象,并在相应的事件监听的方法中更新Calculate对象中的数据。如下所示

   

 

七、Change Unidirectional Association to Bidirectional(将单向关联改为双向关联)

要介绍本部分呢,我想引用本篇博文中第(三)部分是实例。因为在第三部分的实例中Customer与Order的关系是单向关联的,也就是说Order引用了Customer, 而Customer没有引用Order。换句话说,我们知道这个订单是谁的,但你不知道只通过用户你是无法知道他有多少订单的。为了只通过用户我们就能知道该用户有多少订单,那么我们需要使用到“将单向关联改为双向关联”这条规则。

1. 在Customer类中添加上指向Order类的链

因为Customer没有指向Order类的链,所以我们不能获取到该用户有多少订单,现在我们就要添加上这条链。将单向关联改为双向关联,具体做法是在Customer中添加一个数组,该数组中存储的就是该用户所拥有的订单。这个数组就是我们添加的链。数组如下:

1     //添加与Order关联的链,一个用户有多个订单
2     private var orders:Array<Order> = []

在Customer中值只添加数组也是不行的呢,根据之前提到的重构规则,我们要为数组封装相应的操作方法的,下方就是我们要在Customer中添加的操作数组的方法。具体代码如下所示:

1     //====================添加==================
2     func addOrder(order: Order) {
3         self.orders.append(order)
4     }
5     
6     func getOrders() -> Array<Order> {
7         return self.orders
8     }

在Order类关联Customer时,建立Customer到Order的关联。也就是将当前订单添加进该用户对应的订单数组中,具体做法如下:

     

与之对应的规则是Change Bidirectional Association to Unidirectional(将双向关联改为单向关联),就是根据特定需求删去一个链。就是说,原来需要双向链,可如今由于需求变更单向关联即可,那么你就应该将双向关联改为单向关联。

 

八、Replace Magic Number with Synbolic Constant(以字面常量取代魔法数)

这一点说白了就是不要在你的应用程序中直接出现字数值。这一点很好理解,在使用字面数值时,我们要使用定义好的常量来定义。因为这样更易于维护,如果同一个字面数值写的到处都是,维护起来及其困难。当使用字面常量时维护起来就容易许多。该规则比较容易理解,在此不做过多的赘述。看下方实例即可。对于下方的实例而言,如果在版本迭代中所需的PI的精度有所改变,那么对于替换后的程序而言,我们只需修改这个常量的值即可。

1 func test(height: Double) -> Double {
2     return 3.141592654 * height
3 }
4 
5 //替换
6 let PI = 3.141592654
7 func test1(height: Double) -> Double {
8     return PI * height
9 }

 

九、Encapsulate Field(封装字段)

当你的类中有对外开放字段时,最好将其进行封装,不要直接使用对象来访问该字段,该优缺点与上述的“自封装字段”的优缺点类似。因为直接访问类的字段,会降低程序的模块化,不利于程序的扩充和功能的添加。再者封装是面向对象

首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Swfit中视图跳转 下一篇代码重构(四):条件表达式重构规则

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目