设为首页 加入收藏

TOP

代码重构(三):数据重构规则(四)
2017-10-10 12:15:56 】 浏览:1303
Tags:代码 重构 数据 规则
的特征之一,所以我们需要将字段变成私有的,然后对外提供相应的setter和getter方法。具体做法如下所示。

 1 //重构前
 2 class Person {
 3     var name: String = ""
 4     
 5     init(name: String) {
 6         self.name = name
 7     }
 8 }
 9 
10 //重构后
11 class Person {
12     private var name: String = ""
13     
14     init(name: String) {
15         self.name = name
16     }
17     
18     func getName() -> String {
19         return name
20     }
21     
22     func setName(name: String) {
23         self.name = "China:" + name
24     }
25 }

 

十、Encapsulate Collection(封装集合)

“封装集合”这一重构规则应该来说并不难理解。当你的类中有集合时,为了对该集合进行封装,你需要为集合创建相应的操作方法,例如增删改查等等。下方就通过一个不封装集合的实例,看一下缺点。然后将其重构。关于“封装集合”具体的细节参见下方实例。

1.未封装集合的实例

下方我们先创建一个图书馆图书类,为了简化示例,该图书类只有一个书名。下方代码段就是这个图书类,如下所示:

class LibraryBook {
    private var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func getName() -> String {
        return self.name
    }
}

 

紧接着要创建一个借书者,借书者中有两个字段,一个是借书者的名字,另一个是所借书籍的数组。在Lender中我们没有为lendBooks数组封装相应的方法,只为其提供了getter/setter方法,具体代码如下所示。

 1 class Lender {
 2     private var name: String
 3     private var lendBooks: Array<LibraryBook> = []
 4     
 5     init(name: String) {
 6         self.name = name
 7     }
 8     
 9     func getName() -> String {
10         return self.name
11     }
12     
13     func setLendBooks(books: Array<LibraryBook>) {
14         self.lendBooks = books
15     }
16     
17     func getLendBooks() -> Array<LibraryBook> {
18         return self.lendBooks
19     }
20 }

 

紧接着我们要创建一个测试用例,观察这两个类的使用方式。由下面程序的注释可知,首先我们需要创建一个books的数组,该数组就像一个篮子似的,它可以存储我们要借的书籍。让后将创建的书籍添加到该数组中,最后将books赋值给借书人中的lendBooks。如果要对书籍进行修改,那么只有先获取借书人的lendBooks, 然后进行修改,最后再将修改后的值赋值回去。

 1 //先创建一个书籍数组
 2 var books: Array<LibraryBook> = []
 3 //添加要借的书籍
 4 books.append(LibraryBook(name: "《雪碧加盐》"))
 5 books.append(LibraryBook(name: "《格林童话》"))
 6 books.append(LibraryBook(name: "《智慧意林》"))
 7 
 8 //创建借书人
 9 let lender: Lender = Lender(name: "ZeluLi")
10 lender.setLendBooks(books)
11 
12 //获取所借书籍
13 var myBooks = lender.getLendBooks()
14 
15 //对书籍数组修改后再赋值回去
16 myBooks.removeFirst()
17 lender.setLendBooks(myBooks)

 

2.为上面的Lender类添加相应的集合操作的方法

由上面的测试用例可以看出,Lender类封装的不好。因为其使用方式以及调用流程太麻烦,所以我们得重新对其进行封装。所以就会用到“Encapsulate Collection”原则。下面我们就会为Lender添加上相应的集合操作的方法。说白了,就是讲上面测试用例做的一部分工作放到Lender类中。下方是为Lender添加的对lendBooks相应的操作方法。下方代码中的Lender类与上面的Lender类中的lendBooks不同,我们使用了另一个集合类型,也就是字典,而字典的key就是书名,字典的值就是书的对象。具体代码如下所示:

   

 

经过上面这样一封装的话,使用起来就更为合理与顺手了。用大白话讲,就是好用。下方是我们重新封装后的测试用例,简单了不少,而且组织也更为合理。具体请看下方代码段:

    

 

十一、Replace Subclass with Fields(以字段取代子类)

什么叫“以字段取代子类”呢?就是当你的各个子类中唯一的差别只在“返回常量数据”的函数上。当遇到这种情况时,你就可以将这个返回的数据放到父类中,并在父类中创建相应的工厂方法,然后将子类删除即可。直接这样说也许有些抽象,接下来,我们会通过一个小的Demo来看一下这个规则具体如何应用。1.创建多个子类,并每个子类只有一个函数的返回值不同

接下来我们就要创建重构前的代码了。首先我们创建一个PersonType协议(也就是一个抽象类),该协议有两个方法,一个是isMale(),如果是子类是男性就返回true,如果子类是女性就返回false。还有一个是getCode()函数,如果子类是男性就返回“M”,如果是子类是女性就返回“F”。 这两个子类的差别就在于各个函数返回的值不同。下方是PersonType的具体代码。

1 protocol PersonType {
2     func isMale() -> Bool
3     func getCode() -> String
4 }

然后我们基于PersonType创建两个子类,一个是Male表示男性,一个是Female表示女性。具体代码如下:

 1 class Male: PersonType {
 2     func isMale() -> Bool {
 3         return true
 4     }
 5     
 6     func getCode() -> String {
 7         return SenderCode.Male.rawValue
 8     }
 9 }
10 
11 class Female: PersonTyp
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Swfit中视图跳转 下一篇代码重构(四):条件表达式重构规则

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目