开闭原则

2023-02-26  本文已影响0人  木叶苍蓝

前言:
开闭原则的指导思想是——代码对功能扩展开放的同时应对修改关闭。我们在开发过程中,不要指望需求能从一开始就能完全确定,这是非常不切实际的想法。既然需求是一定会变化的,那么我们就应该把需求变化作为一种常态来处理,将代码设计的相对更加易扩展,易维护。在工作中的很多时候,开发与产品经理之间的主要矛盾就是,经常变化的需求与不能变化的代码之间的矛盾。

概述

开闭原则的关键在于抽象,将代码中可能会经常发生变化的部分封装成接口或抽象类(注意:Python中没有类似于 JAVA语言中接口的概念),这样当有新的需求或需求发生变化时,就可以对现有代码进行扩展以适应新的情况,不至于整个推到重做。只要从项目开发之初就遵循开发封闭原则,那么写出灵活,易扩展和易维护代码就不难做到。简言之,应尽量通过扩展实现变化而不是通过修改。
适用场景:

场景

以生活中书店售书的场景为例,原来只按照原价销售小说,现在由于经济下滑,书店为了生存开始打折销售:所有50元以上的书 8 折销售,其他 9 折销售,符合开闭原则的代码如下:

from abc import ABCMeta, abstractmethod

class Book(object):
    __metaclass__ = ABCMeta

    def __init__(self, name, price, author):
        self.name = name
        self.price = price
        self.author = author

    def getName(self):
        return self.name

    def getAuthor(self):
        return self.author

    @abstractmethod
    def getPrice(self):
        pass

    def get_book_info(self):
        return "Book name is %s Price is %s Author is %s" % (self.getName(), self.getPrice()/100.0, self.getAuthor())

class NormalBook(Book):
    def getPrice(self):
        return self.price

根据需求描述可知,书的价格会因外部经济环境变化而变化,所以在代码设计之初将抽象类Book 中获取书价格的方法 getPrice 置为抽象方法,抽象类外部 NormalBook 类实现原价售书,CheapBook 类实现打折售书。根据开闭原则,为解决书价格经常变化的场景,代码中增加一个子类 cheapBook 重写抽象父类 Book 中的 getPrice 方法,而不是直接在原 NormalBook 类上做修改。

class cheapBook(Book):
    def getPrice(self):
        if self.price > 5000:
            return self.price * 0.8
        else:
            return self.price * 0.9


class BookStore():
    def __init__(self, BookObj):
        self.book_list = []
        self.book_list.append(BookObj("西游记", 3000, "吴承恩"))
        self.book_list.append(BookObj("三国演义", 6000, "罗贯中"))
        self.book_list.append(BookObj("红楼梦", 8000, "曹雪芹"))

    def sell(self, book):
        print("Sell info {}".format(book.get_book_info()))

if __name__ == "__main__":
    book_store = BookStore(NormalBook)
    for book in book_store.book_list:
        book_store.sell(book)

    print("#" * 20)
    book_store = BookStore(cheapBook)
    for book in book_store.book_list:
        book_store.sell(book)

对扩展开放,对修改关闭宾补意味着不作任何修改,需求的变化往往是底层模块的变更倒逼高层模块的逐步解耦,以实现代码灵活性,可扩展性,可维护性的目标。
注意事项:

上一篇 下一篇

猜你喜欢

热点阅读