UML 類圖中的結構及 python 實現(xiàn)

Reference


python設計模式-UML類圖中的結構及python實現(xiàn)
看懂UML類圖和時序圖
faif/python-patterns

前言


學習設計模式的時候,需要用到 UML 來理解每個設計模型。 一般的 UML 是假設以 Java 為實現(xiàn)語言,那么如何用 Python 來實現(xiàn) UML 的各種結構呢?

工具


本文的UML圖采用gliffy繪制。
Python版本2.7

類圖


類圖是由類和類之間的連接關系構成
這里只介紹類和抽象類
連接關系這里介紹泛化(generalization),實現(xiàn)(realize),聚合(aggregation),組合(composition),關聯(lián)(assocation),依賴(dependency) 共六種。


抽象類(Java 中的接口 interface)

圖示

interface在 UML 中的圖形為

interface

其上半部分又一個 interface 的標示,在interface中一般只給出接口的定義;
實現(xiàn)一般放在子類中實現(xiàn)。

代碼

在 Python 中本身是沒有接口或是抽象類這種概念的,但是可以通過拋出 NotImplementedError 這個異常來實現(xiàn),或是通過 abc(Abstract Base Class) 這個 Python 庫來實現(xiàn)。

通過拋異常實現(xiàn)
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()

如果子類沒有實現(xiàn)方法,在事例化的時候不會報錯,只有調用到未實現(xiàn)的方法的時候才會報錯。

使用 abc 模塊來實現(xiàn)

這里暫不實現(xiàn)

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 字節(jié)碼的時候,編譯器自動將含有 __ 開頭的屬性或方法前加上了 _{classname},所以可以在類外通過 _Flower__leaf 來訪問 __leaf 屬性。但是不要嘗試訪問私有變量或方法」

連接關系


類的繼承結構表現(xiàn)在 UML 中為:泛化 (generalize) 與實現(xiàn) (realize)
繼承關系為is - a的關系;兩個對象之間如果可以用is - a類表示,就是繼承關系:(..是..)

泛化關系(generalization)

圖示

泛化關系在 UML 中的圖形為


generalization

泛化關系用由一條直線和一個空心三角箭頭標示,連接的兩端都是類。在代碼中的結構就是繼承非抽象類。
Car 在現(xiàn)實中有實現(xiàn),可用 Car 定義具體的對象。

代碼

泛化關系表現(xiàn)為繼承非抽象類

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')

實現(xiàn)(realize)

圖示

實現(xiàn)在 UML 中的圖形為


realize

實現(xiàn)關系用一條虛線和空心三角箭頭表示。
"交通工具" 作為一個抽象概念,在現(xiàn)實中并無法直接用來定義對象;只有指明具體的子類(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')

關聯(lián)關系(association)

關聯(lián)關系用一條直線表示;它描述不同類的對象之間的結構關系;它是一種靜態(tài)的關系,通常與運行狀態(tài)無關,一般由常識等因素決定的;它一般用來定義對象之間靜態(tài)的,天然的結構;所以,關聯(lián)關系是一種 "強關聯(lián)" 的關系。

比如,乘車人和車票之間就是一種關聯(lián)關系;學生和學校就是一種關聯(lián)關系;

圖示

關聯(lián)關系在 UML 中的圖形為


Association

關聯(lián)關系為一條直線,關聯(lián)關系默認不強調方向,表示對象間相互知道;如果需要強調方向,使用線狀箭頭,如圖,表示 A 知道 B,B 不知道 A。
在代碼中,關聯(lián)對象通常是以成員變量的形式實現(xiàn)的。上圖在代碼中就是 A 中有一個屬性為 B 類的實例。也可以為雙箭頭表示相互知道。

代碼

class B(object):
    pass

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

依賴關系(dependency)

依賴關系描述一個對象在運行期間會用到另一個對象,與關聯(lián)關系不同的是,它是一種臨時性的關系,通常在運行期間產(chǎn)生,并且隨著運行時的變化,依賴關系也可能發(fā)生變化。

顯然依賴也有方向,雙向依賴是一種非常糟糕的結構,我們總是應該保持單向依賴,杜絕雙向依賴的產(chǎn)生。

注:在最終代碼中,依賴關系體現(xiàn)為類構造方法及類方法的傳入?yún)?shù),箭頭的指向為調用關系;依賴關系除了臨時知道對方外,還是 "使用" 對方的方法和屬性。

圖示

dependency

從圖中可以看出依賴關系為在類的方法中將另一個類當作參數(shù)傳入。

代碼

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

聚合關系由一個空的菱形箭頭表示,菱形箭頭指向整體。當公司不存在時,人還是存在的。
組合關系和聚合關系由常識來區(qū)別的,在實現(xiàn)上區(qū)別不大。

代碼

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()
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 在UML 2.0的13種圖形中,類圖是使用頻率最高的UML圖之一。Martin Fowler在其著作《UML Di...
    雷雷_zll閱讀 13,519評論 0 14
  • 忘記了uml類圖連線之間的關系,記錄一下。 1. 關聯(lián)關系 關聯(lián)(Association)關系是類與類之間最常用的...
    cutieagain閱讀 2,012評論 0 2
  • UML概述 UML簡介 UML (Unified Modeling Language)為面向對象軟件設計提供統(tǒng)一的...
    aron1992閱讀 617評論 0 0
  • 我像是在與每一個夜晚戀愛 即使是白天的時候,我也在沉默 而夜晚,也是 我把孤獨的燭光在案臺上點燃 總它照明,引煙,...
    羊與遠方閱讀 332評論 0 0
  • “蕩胸生層云,決眥入歸鳥,會當陵絕頂,一覽眾山小?!弊孕μ┥奖阌袩o數(shù)的憧憬,于18.08.15凌晨終于爬上了泰山...
    Wuff吳凡閱讀 333評論 0 2

友情鏈接更多精彩內(nèi)容