美文网首页Python
UML 类图中的结构及 python 实现

UML 类图中的结构及 python 实现

作者: RoyTien | 来源:发表于2018-10-21 12:20 被阅读60次

    Reference


    python设计模式-UML类图中的结构及python实现
    看懂UML类图和时序图
    faif/python-patterns

    前言


    学习设计模式的时候,需要用到 UML 来理解每个设计模型。 一般的 UML 是假设以 Java 为实现语言,那么如何用 Python 来实现 UML 的各种结构呢?

    工具


    本文的UML图采用gliffy绘制。
    Python版本2.7

    类图


    类图是由类和类之间的连接关系构成
    这里只介绍类和抽象类
    连接关系这里介绍泛化(generalization),实现(realize),聚合(aggregation),组合(composition),关联(assocation),依赖(dependency) 共六种。


    抽象类(Java 中的接口 interface)

    图示

    interface在 UML 中的图形为

    interface

    其上半部分又一个 interface 的标示,在interface中一般只给出接口的定义;
    实现一般放在子类中实现。

    代码

    在 Python 中本身是没有接口或是抽象类这种概念的,但是可以通过抛出 NotImplementedError 这个异常来实现,或是通过 abc(Abstract Base Class) 这个 Python 库来实现。

    通过抛异常实现
    from __future__ import print_function
    
    class Drawable:
        def size(self):
            raise NotImplementedError
    
        def draw(self, x, y, scale=1.0):
            raise NotImplementedError
    
    class Circle(Drawable):
        def size(self):
            print('Circle')
    
        def draw(self, x, y, scale=1.0):
            print(x * y * scale)
    
    c = Circle()
    c.draw()
    

    如果子类没有实现方法,在事例化的时候不会报错,只有调用到未实现的方法的时候才会报错。

    使用 abc 模块来实现

    这里暂不实现

    from abc import ABCMeta, abstractmethod, abstractproperty
    

    类 Class

    图示

    class 在 UML 中的图形为

    class
    整个图形分为三部分:上面为类名,中间为类属性,下面为类方法。
    可以看到有 -+# 这三种符号,其分别代表私有,共有,保护。其中保护变量在 Python 中是不存在的。
    共有变量可以在类外被直接访问,且可以被子类继承;私有变量只能再次类中被访问且不可以被子类继承。

    代码

    from __funture__ import print_functiopn
    class Flower(object):
        def __init__(self, floral=None, leaf=None):
            self.floral = floral
            self.__leaf = leaf
            
        def flowing(self):
            print('flower')
    
        def __grow(self):
            print('grow grow')
    

    以两条下划线抬头的变量为私有变量,方法为私有方法。
    「Python其实可以在类外面访问到私有变量或方法。因为生成 Python 字节码的时候,编译器自动将含有 __ 开头的属性或方法前加上了 _{classname},所以可以在类外通过 _Flower__leaf 来访问 __leaf 属性。但是不要尝试访问私有变量或方法」

    连接关系


    类的继承结构表现在 UML 中为:泛化 (generalize) 与实现 (realize)
    继承关系为is - a的关系;两个对象之间如果可以用is - a类表示,就是继承关系:(..是..)

    泛化关系(generalization)

    图示

    泛化关系在 UML 中的图形为


    generalization

    泛化关系用由一条直线和一个空心三角箭头标示,连接的两端都是类。在代码中的结构就是继承非抽象类。
    Car 在现实中有实现,可用 Car 定义具体的对象。

    代码

    泛化关系表现为继承非抽象类

    from __future__ import print_function
    
    class Car(object):
        def __init(self):
            self.wheel = ['17']
            self.body = 'Independent Suspension'
    
        def run(self):
            #get the car started
        def horn(self):
            print('car is coming')
    
    class Suv(Car):
        def horn(self):
            print('Suv is coming')
    
    class Jeep(Car):
        def horn(self):
            print('Jeep is coming')
    

    实现(realize)

    图示

    实现在 UML 中的图形为


    realize

    实现关系用一条虚线和空心三角箭头表示。
    "交通工具" 作为一个抽象概念,在现实中并无法直接用来定义对象;只有指明具体的子类(Car 还是 Bicycle)才可以用来定义对象。

    代码

    CarBicycle 继承了 Vehicle 这个抽象类。

    from __future__ import print_function
    
    class Vehicle(object):
        def run(self):
            raise NotImplementedError
    
    class Car(Vehicle):
        def run(self):
            print('car run run')
    
    class Bicycle(Vehicle):
        def run(self):
            print('bicycle run run')
    

    关联关系(association)

    关联关系用一条直线表示;它描述不同类的对象之间的结构关系;它是一种静态的关系,通常与运行状态无关,一般由常识等因素决定的;它一般用来定义对象之间静态的,天然的结构;所以,关联关系是一种 "强关联" 的关系。

    比如,乘车人和车票之间就是一种关联关系;学生和学校就是一种关联关系;

    图示

    关联关系在 UML 中的图形为


    Association

    关联关系为一条直线,关联关系默认不强调方向,表示对象间相互知道;如果需要强调方向,使用线状箭头,如图,表示 A 知道 B,B 不知道 A。
    在代码中,关联对象通常是以成员变量的形式实现的。上图在代码中就是 A 中有一个属性为 B 类的实例。也可以为双箭头表示相互知道。

    代码

    class B(object):
        pass
    
    class A(object):
        def __init__(self):
            self.b = B()
    

    依赖关系(dependency)

    依赖关系描述一个对象在运行期间会用到另一个对象,与关联关系不同的是,它是一种临时性的关系,通常在运行期间产生,并且随着运行时的变化,依赖关系也可能发生变化。

    显然依赖也有方向,双向依赖是一种非常糟糕的结构,我们总是应该保持单向依赖,杜绝双向依赖的产生。

    注:在最终代码中,依赖关系体现为类构造方法及类方法的传入参数,箭头的指向为调用关系;依赖关系除了临时知道对方外,还是 "使用" 对方的方法和属性。

    图示

    dependency

    从图中可以看出依赖关系为在类的方法中将另一个类当作参数传入。

    代码

    from __future__ import print_function
    
    class People(object):
        def __init__(self):
            pass
    
        def drive(self, vehicle):
            vehicle.run()
    
    class Vehicle(object):
        def __init__(self):
            pass
    
        def run():
            raise NotImplementedError
    
    class Car(Vehicle):
        def __init__(self):
            pass
    
        def run():
            print('car start')
    
    class Bicycle(Vehicle):
        def __init__(self):
            pass
    
        def run():
            print('bicycle start')
    
    def main():
        car = Car()
        bicycle = Bicycle()
    
        caleb = People()
        caleb.drive(car)
        caleb.drive(bicycle)
    
    if __name__ == '__main__':
        main()
    

    Peopledrive() 方法中传入 CarBicycle 实例,调用 run() 方法,完成 Peopledrive() 方法。

    组合关系(composition)

    组合关系表示整体由部分构成,但是当整体不存在是部分也不存在,是一种强依赖关系。

    图示

    Aggregation

    组合关系是由一个实心的菱形箭头表示,菱形箭头指向整体,公司有部门组成,当公司不存在了,部门也不存在了。

    代码

    class Company(object):
        def __init__(self):
            self.__departments = []
    
        def build_department(self, department):
            self.__departments.append(department)
    
    class Department(object):
        def __init__(self, title):
            self.title = title
    
    def main():
        company = Company()
        company.build_department(Department('Back End Development'))
        company.build_department(Department('Front End Development'))
    
    if __name__ = '__main__':
        main()
    

    聚合关系(aggregation)

    聚合关系表示整体由部分构成,但是当整体不存在时部分还是可以存在的。

    图示

    aggregation
    聚合关系由一个空的菱形箭头表示,菱形箭头指向整体。当公司不存在时,人还是存在的。
    组合关系和聚合关系由常识来区别的,在实现上区别不大。

    代码

    class Company(object):
        def __init__(self):
            self.__employees = []
    
        def add_employee(self, people):
            self.__employees.append(people)
    
    class People(object):
        def __init__(self, name):
            self.name = name
    
    def main():
        company = Company()
        p1 = People('Mike')
        p2 = People('Jack')
        company.add_employee(p1)
        company.add_employee(p2)
    
    if __name__ = '__main__':
        main()
    

    相关文章

      网友评论

        本文标题:UML 类图中的结构及 python 实现

        本文链接:https://www.haomeiwen.com/subject/tqmdaftx.html