Python_接口设计

一,接口设计

使用polygon函数来画一个50边形,来接近一个圆。写circle这个函数了,需要半径r作为一个参数:

$ cat circle.py 

#!/bin/bash

import math

def circle(t, r):

    circumference = 2 * math.pi * r

    n = 50

    length = circumference / n

    polygon(t, n, length)

第一行计算了圆的周长,使用2乘以圆周率再乘以半径r。这个计算用到了圆周率,所以要导入math模块。通常都要把导入语句放到整个脚本的开头。

n是我们用来逼近一个圆所用的线段数量,所以length就是每一个线段的长度了(周长circumference/线段数量n)。polygon画一 个50边的多边形,来近似做一个半径为r的圆。

这种方案的一个局限性就是n是常数,就意味着对于一些大尺寸的圆,线段数目就太多了;而对小的圆,又浪费了很多小线段。

解决的方法就是进一步扩展函数,让函数把n也作为一个参数。这就会让用户(调用circle函数的任何人)有更多决定权,可以控制所用的线段数量,当然,接口就不那么简洁了。

函数的接口:就是关于它如何工作的一个概述,比如都有什么变量? 函数实现什么功能? 以及返回值是什么? 允许调用者随意操作而不用处理一些无关紧要的细节,这种函数接口就是简洁的。

在本例中,r包含于接口内,因为要用它来确定所画圆的大小。n就不那么合适了,因为它是用来处理如何具体绘制一个圆的。

与其让接口复杂冗余,更好的思路是让n根据周长来自适应一个合适的值:

$ cat circle.py 

#!/bin/bash

import math

def circle(t, r):

    circumference = 2 * math.pi * r

    n = int(circumference / 3) + 1

    length = circumference / n

    polygon(t, n, length)

现在线段数量就是周长的三分之一了,因此每段线段的长度近似为3,这个大小可以让圆看着不错,也对任意大小的圆都适用。

二,重构

当写circle这个函数的时候,我们能利用多边形函数polygon是因为一个足够多边的多边形和圆很接近。但圆弧就不太适合这个思路了,我们不能用多边形或者圆来画一个圆弧。

一个替代的方法就是把polygon修改一下,转换成圆弧:

$ cat circle.py 

#!/bin/bash

import math

def circle(t, r, angle ):

    arc_length = 2 * math.pi * r * range / 360

    n = int(arc_length / 3) + 1

    step_length = arc_length / n

    step_angle = angle / n

    for i in range(n):

        t.fd(length)

        t.lt(angle)

这个函数的后半段看着和多边形那个还挺像的,但必须修改一下接口才能重利用多边形的代码。

我们在多边形函数上增加angle(角度)作为第三个参数,但继续叫多边形就不太合适了,因为不闭合。所以就改名叫它多段线polyline:

def polyline(t, n, length, angle):
     for i in range(n):
            t.fd(length)
            t.lt(angle)

现在就可以用多段线polyline来重写多边形polygon和圆弧arc:

$ cat circle.py 

#!/bin/bash

import math

def polygon(t, n, length):

    angle = 360.0 / n

    polyline = (t, n, length, angle)

def arc(t, r, angle ):

    arc_length = 2 * math.pi * r * range / 360

    n = int(arc_length / 3) + 1

    step_length = arc_length / n

    step_angle = float(angle) / n

    polyline(t, n, step_length, step_angle)

最终就可以用圆弧arc来重写circle:

def circle(t, r):

    arc(t, r, 360)

这个过程中,改进了接口设计,增强了代码再利用,这就叫做重构。

在本例中, 我们先是注意到圆弧arc和多边形polygon有相似的代码,所以,把他们都用多段线polyline 来实现。

如果我们事先进行了计划,估计就会先写出多段线函数polyline,然后就不用重构了,

但我们在开始一个项目之前往往不一定了解的那么清楚。一旦开始编码了,你就逐渐更理解其中的问题了。

有时候重构就意味着你已经学到了新的内容了。

结束。