6.4 重构鱼书核心对象

1.重构思路:

首先来看YuShuBook。之所以YuShuBook会出现大量的classmathod,他的原因就在于:YuShuBook并不会保存数据,而是把所有数据都返回给了调用方去;换句话说YuShuBook是个伪面向对象(伪类),因为他只是包装了一系列的方法,而没有存储这个类的特征,数据。

既然一个类或者对象应该有自己的特征和数据,那么我们就没有必要通过方法的形式把本应该用来描述这个列的特征的数据返回回去,而是保存在YuShuBook这个类中。

YuShuBook关键词缀在Book中,依此可以知道,我们这个类是用来描述书籍的,而search_by_isbn,search_by_key这些方法返回的就是关于书籍的数据,所以我们完全可以用这个方法所返回的数据来描述类本身,把他存储到类的内部,而不是返回到外部去(保持类的内聚性)

2.重构后的代码

class YuShuBook:

    search_by_isbn_url = "http://t.yushu.im/v2/book/isbn/{}"

    search_by_key_url = "http://t.yushu.im/v2/book/search?q={}&count={}&start={}"

    def __init__(self):
        self.total = 0
        self.books = []

    def search_by_isbn(self, isbn):
        url = self.search_by_isbn_url.format(isbn)
        result = HTTP.get(url)
        self.__fill_single(result)

    def search_by_key(self, q, page=1):
        url = self.search_by_key_url.format(q, current_app.config["PRE_PAGE"],
                                           self.calculate_start(page))
        result = HTTP.get(url)
        self.__fill_collection(result)

    def __fill_single(self, data):
        if data:
            self.books = [data]
            self.total = 1

    def __fill_collection(self, data):
        self.books = data['books']
        self.total = data['total']

    def calculate_start(self, page):
        return (page-1) * current_app.config["PRE_PAGE"]
# 具体的单一数据处理封装在BookViewModel里
class BookViewModel:

    def __init__(self, book):
        self.title = book['title'],
        self.publisher = book['publisher'],
        self.pages = book['pages'],
        self.author = book['author'],
        self.price = book['price'],
        self.summary = book['summary'],
        self.image = book['image']


# BookCollection只负责集合的处理
class BookCollection:

    def __init__(self):
        self.keyword = ''
        self.total = 0
        self.books = []

    def fill(self, yushu_book, keyword):
        self.keyword = keyword
        self.total = yushu_book.total
        self.books = [BookViewModel(book) for book in yushu_book.books]

在重构的时候,我们没有在类中保存查询参数,如果保存了查询参数,在代码层面是没有问题的,但是存在一个问题就是:YuShuBook的作用是隐藏了数据的具体获取方式,也就是说YuShuBook足够的抽象,他不需要我们去关心数据具体是怎么来的,但是如果我们把查询参数也加入到类里面来之后,他就会使得这个类更加的具体化,因为我们保持的数据更多,更加精准,甚至描述了使如何获取数据的,一般一个类太具体化就会存在一个扩展和修改的问题,加入YuShuBook有一天内部的数据来源改成从数据库里获取信息,那么这样的情况下面,我们把查询参数放在YuShuBook中反而不好了,他减少了YuShuBook的灵活性

Last updated