语言-编程原则SOLID-OCP

open/closed principle 

At first thought that might sound quite academic and abstract. What it means though is that we should strive to write code that doesn’t have to be changed every time the requirements change. How we do that can differ a bit depending on the context, such as our programming language. When using Java, C# or some other statically typed language the solution often involves inheritance and polymorphism, which is what this example will illustrate.

 

起初认为这可能听起来颇具学术性和抽象性。 但它的意思是,我们应该努力编写代码,而不必在每次需求更改时都进行更改。 我们如何做到这一点可以根据上下文而有所不同,比如我们的编程语言。 当使用Java,C#或其他静态类型的语言时,解决方案通常涉及继承和多态,这就是本例将说明的内容。

 

If we look back our previous example, where did we go wrong? Clearly even our first implementation of the Area wasn’t open for extension. Should it have been? I’d say that it all depends on context. If we had had very strong suspicions that Aldford would ask us to support other shapes later on we could probably have prepared for that from the get-go. However, often it’s not a good idea to try to anticipate changes in requirements ahead of time, as at least my psychic abilities haven’t surfaced yet and preparing for future changes can easily lead to overly complex designs. Instead, I would suggest that we focus on writing code that is well written enough so that it’s easy to change if the requirements change.

 

如果我们回顾我们前面的例子,我们在哪里出错?显然,即使我们对“区域”的第一次实施也没有延续。它应该是?我会说这一切都取决于上下文。如果我们有强烈的怀疑,奥尔德福德会要求我们稍后支持其他形状,我们可能已经准备好了,从一开始。然而,试图预先考虑需求的变化通常不是一个好主意,因为至少我的心理能力还没有出现,为未来的变化做准备很容易导致过于复杂的设计。相反,我建议我们着重编写足够好的代码,以便在需求发生变化时很容易进行更改。

 

Once the requirements do change though it’s quite likely that they will change in a similar way again later on. That is, if Aldford asks us to support another type of shape it’s quite likely that he soon will ask for support for a third type of shape.

 

一旦需求发生变化,虽然他们很可能会在稍后再次以类似的方式改变。也就是说,如果Aldford要求我们支持另一种形状,很可能他很快会要求支持第三种形状。

 

So, in other words, I definitely think we should have put some effort into abiding by the open/closed principle once the requirements started changing. Before that, in most cases, I would suggest limiting your efforts to ensuring that the code is well written enough so that it’s easy to refactor if the requirements starts changing.

 

换句话说,我一定认为,一旦需求开始改变,我们应该努力遵守开放/封闭的原则。在此之前,在大多数情况下,我建议限制您的努力,以确保代码写得够好,以便在需求开始改变时很容易重构。

 

 

 

Good

bad

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# This is a reimplementation of `python_code.bad.open_close` module which

# abides by the open/close principle. You can see that it will be easy to

# extend the functionality of `AreaCalculator` in this module whereas it

# is not in `python_code.bad.open_close` module.

 

from abc import ABCMeta, abstractproperty

 

class Shape(object):

    __metaclass__ = ABCMeta

    @abstractproperty

    def area(self):

        pass

 

class Rectangle(Shape):

    def __init__(self, width, height):

        self.width = width

        self.height = height

 

    @property

    def area(self):

        return self.width * self.height

 

class AreaCalculator(object):

 

    def __init__(self, shapes):

        self.shapes = shapes

 

    @property

    def total_area(self):

        total = 0

        for shape in self.shapes:

            total += shape.area

        return total

 

# Note that if we want to extend the functionality of AreaCalculator to support calculating

# area of different shape, we only need to define new subtype of `Shape` and leave other code

# alone without modify them. That is the key of open/close principle.

 

def main():

    shapes = [Rectangle(1, 6), Rectangle(2, 3)]

    calculator = AreaCalculator(shapes)

 

    print("The total area is: ", calculator.total_area)

 

if __name__ == '__main__':

    main()

#!/usr/bin/env python

# -*- coding: utf-8 -*-

 

# Think about what will happen if you want to extend the class to calculate

# the area of different shape? What would you do with the code in the property

# `total_area` of class `AreaCalculator`?

 

class Rectangle(object):

 

    def __init__(self, width, height):

        self.width = width

        self.height = height

 

class AreaCalculator(object):

 

    def __init__(self, shapes):

        assert isinstance(shapes, list), "`shapes` should be of type `list`."

        self.shapes = shapes

 

    @property

    def total_area(self):

        total = 0

        for shape in self.shapes:

            total += shape.width * shape.height

 

        return total

 

def main():

    shapes = [Rectangle(2, 3), Rectangle(1, 6)]

    calculator = AreaCalculator(shapes)

    print("The total area is: ", calculator.total_area)

 

if __name__ == '__main__':

 

    main()

 

 

总结一句话:

 作者通过一个客户不断的提出新的需求来说明,如果我们把所有的代码功能都写在一个类中,这样会导致每一次需求更改的时候,全部要重写一遍,所以提出了OCP方法,也就是说,将不同的功能或者方法写出不同的类,以便将来扩展,增加程序的健壮性。

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值