1. 程式人生 > >設計模式之一:簡單工廠模式,用python實現簡易計算器

設計模式之一:簡單工廠模式,用python實現簡易計算器

最近自學Python,想做些小專案練練手,發現程傑寫的大話設計模式這書不錯,適合新手入門。開始這本書第一章學習,這裡實現簡單工廠模式。以實現圖形介面的簡易計算器為例項,能夠計算+-/*% ( )等混合表示式,ps: 沒有實現負數的功能。具體過程大致分為以下幾個步驟:

  • 定義只計算兩個數的運算類 Operation
  • 繼承Operation類,實現+-*/%子類
  • 定義運算工廠OperationFactory
  • 定義混合運算類MixedOperation
  • 定義圖形介面顯示類Display

1. 定義只計算兩個數的運算類 Operation

定義兩個成員變數,及一個成員函式:

class Operation
:
number_a = 0 number_b = 0 def get_result(self): return 0

2. 繼承Operation類,實現+-*/%子類

如定義加法類OperationAdd,重寫get_result()方法:

class OperationAdd(Operation):
    def get_result(self):
        return self.number_a + self.number_b

3. 定義運算工廠OperationFactory

這就是這一章用到的簡單工廠模式,通過例項化物件來完成某一種運算需求。這裡用到Python的字典來實現如C++語言中的switch功能。

class OperationFactory():
    @staticmethod
    def create_operation(operator):
        # use dict to replace switch function
        operator_dict = {
            '+': OperationAdd,
            '-': OperationSub,
            '*': OperationMul,
            '/': OperationDiv,
            '%': OperationMod,
        }
        oper = operator_dict.get(operator)()

4. 定義混合運算類MixedOperation

四則混合運算(還包括取餘%)的演算法是通過中綴表示式轉換為字尾表示式,再對字尾表示式進行計算。關於中綴表示式轉換為字尾表示式再計算的詳細過程可參考這位博主的文章

class MixedOperation():
    priority_dict = {'(': 1, ')': 1, '*': 3, '/': 3, '%': 3, '+': 4, '-': 4}

    def __init__(self, input_exp):
        self.input_exp = input_exp
        self.postfix_list = self.infix2postfix(self.input_exp)
        self.result = self.cal_postfix(self.postfix_list)

    def infix2postfix(self, input_exp):
        infix_exp = input_exp
        postfix_list = []
        stack = []
        # transfer to infix list which does not contain null item
        infix_list = re.split('(\+|-|\*|/|%|\(|\))', infix_exp)
        while '' in infix_list:
            infix_list.remove('')
        for index, item in enumerate(infix_list):
            if self.is_num(item):
                postfix_list.append(item)
            elif not self.is_num(item):
                if len(stack) == 0:
                    stack.append(item)
                elif item == '(':
                    stack.append(item)
                elif item == ')':
                    stack_re = stack[::-1]
                    k = len(stack_re) - stack_re.index('(') - 1  # index of the last '(' in stack
                    out_items = stack[(k+1):len(stack)]  # get out these items after '('
                    postfix_list.extend(out_items[::-1])
                    del stack[k:len(stack)]
                elif self.priority_dict[item] < self.priority_dict[stack[-1]]:  # higher priority
                    stack.append(item)
                else:
                    stack_copy = stack
                    for index0, item0 in [(len(stack)-i-1, stack[len(stack)-i-1]) for i in range(len(stack))]:
                        if len(stack) == 0 or self.priority_dict[item0] > self.priority_dict[item] or item0 == '(':
                            break
                        else:
                            postfix_list.append(item0)
                            del stack_copy[index0]
                    stack_copy.append(item)
                    stack = stack_copy
        postfix_list.extend(stack[::-1])
        return postfix_list

    def cal_postfix(self, postfix_list):
        if len(postfix_list) == 1:
            return self.str2num(postfix_list[0])
        else:
            for index, item in enumerate(postfix_list):
                if self.priority_dict.has_key(item):
                    oper = OperationFactory.create_operation(item)
                    oper.number_a = self.str2num(postfix_list[index-2])
                    oper.number_b = self.str2num(postfix_list[index-1])
                    temp_res = oper.get_result()  # get the calculate result of two numbers before operator item
                    postfix_list[index-2] = str(temp_res)
                    del postfix_list[index-1:index+1]
                    break
                else:
                    pass
            return self.cal_postfix(postfix_list)

    def is_num(self, item):
        if re.findall('\d+', item):
            return 1
        else:
            return 0

    def str2num(self, item):
        if re.findall('\.', item):
            return float(item)
        else:
            return int(item)

5. 定義圖形介面顯示類Display

為了讓程式有較為好的擴充套件性模組性,讓計算和顯示類進行分離,第一次圖形化介面程式設計,沒仔細研究,寫的很簡單,使用的Tkinter包,可參考相關Tkinter程式設計資料,見參考資料。該部分程式碼參見後面完整的Python程式。

程式效果如圖:

這裡寫圖片描述

附件:

參考資料:

相關推薦

設計模式之一簡單工廠模式python實現簡易計算器

最近自學Python,想做些小專案練練手,發現程傑寫的大話設計模式這書不錯,適合新手入門。開始這本書第一章學習,這裡實現簡單工廠模式。以實現圖形介面的簡易計算器為例項,能夠計算+-/*% ( )等混合表示式,ps: 沒有實現負數的功能。具體過程大致分為以下幾個步

設計模式之一簡單工廠模式

package com.xjh.demo.designpattern.pattern1; public abstract class Animal { public abstract void eat(); } package com.xjh.demo.de

設計模式系列之一簡單工廠模式

前言 設計模式能夠幫助我們設計出健壯,低耦合性的程式碼,從此和高耦合的程式碼say goodbye!在所有的的設計模式中,簡單工廠算是我們平時接觸比較多的吧,多執行緒中的消費者工廠類與生產者工廠類應該算是接觸最早的設計模式,簡單工廠模式要解決的首要問題就是降低

初識設計模式1簡單工廠模式

簡單工廠 height 判斷 目前 mes strong 產品 return logs 簡單工廠模式 簡單工廠模式是類的創建模式,又叫做靜態工廠方法模式。簡單工廠模式由一個工廠對象決定生產出哪一種產品類的實例。 為什麽要使用簡單工廠模式 原因很簡單:解耦。 LOL場

設計模式筆記簡單工廠模式 -- 創建型

-- 一個 筆記 簡單 靜態 com 工廠模式 不同 static 簡單工廠模式 定義一個工廠類,可以根據輸入的不同返回不同類的實例。被創建的類通常有共同的父類。因為通常創建實例的方法都是static,所以又被稱為靜態工廠模式 代碼樣例 設計模式筆記:簡單

PHP設計模式系列簡單工廠模式

簡單工廠模式 簡單工廠模式是屬於建立型模式,又叫做靜態工廠方法(Static Factory Method)模式,但不屬於23種GOF設計模式之一。簡單工廠模式是由一個工廠物件決定創建出哪一種產品類的例項。簡單工廠模式是工廠模式家族中最簡單實用的模式,可以理解

大話設計模式簡單工廠模式

一.模式定義 簡單工廠模式也稱為靜態工廠模式。屬於類建立型設計模式。實質是一個“”工廠系統“”可以產生出多種不同的”產品物件”,使用者不需要知道“”產品物件“”是怎麼產生的,只需要知道關於該“產品物件”的關鍵引數,將該引數傳給“工廠系統”就可以由工廠系統生產出對應的產品。

Java描述設計模式(02)簡單工廠模式

一、生活場景簡介 1、引入場景 訂餐流程簡單描述 1)、食品抽象類,規定食品的基礎屬性操作 2)、魚類,雞肉類食品類擴充套件 3)

設計模式筆記1簡單工廠模式

1.3 簡單 修改 作用 面向對象 對象 面向 tro 計算   如果想成為一名更優秀的軟件設計師,了解優秀軟件設計的演變過程比學習優秀設計本身更有價值。 1.1 面向對象的好處   通過封裝、繼承多態把程序的耦合度降低,使用設計模式使得程序更加靈活,容易修改,易於復用

C#設計模式之創建類模式簡單工廠模式

div main bst http fin 想要 對象 sqlserver 關鍵字 這是記錄設計模式種的創建型模式的第一篇,所以,在開頭要說一些關於創建型模式的含義和意義。 創建型模式 軟件系統在運行時,類將被實例化成對象,並由這些被創建的對象協作完成系統中要求的各項業務功

Java 設計模式(一)簡單工廠模式

參考連結:簡單工廠模式-Simple Factory Pattern 1. 模式概述 定義:定義一個工廠類,它可以根據引數的不同返回不同類的例項,被建立的例項通常都具有共同的父類。因為在簡單工廠模式中用於建立例項的方法是靜態方法,因此簡單工廠模式又被稱為靜態工廠方法模式。 簡

大話設計模式簡單工廠模式

    由於面向過程程式設計造成的程式碼膨脹問題越來越嚴重,使其維護的代價高,靈活性很低。為了使程式碼易維護、易擴充套件、易複用和靈活性好,所以我們在採用面向物件程式設計的時候,防止採用面向物件的語言實際上卻做著面向過程的事兒,更需要採用某種設計模式,核心就是使程式變得高內

c++設計模式簡單工廠模式(Simple Factory Pattern)

 定義: 從設計模式的型別上來說,簡單工廠模式是屬於建立型模式,又叫做靜態工廠方法(StaticFactory Method)模式,但不屬於23種GOF設計模式之一。簡單工廠模式是由一個工廠物件決定創建出哪一種產品類的例項。簡單工廠模式是工廠模式家族中最簡單實用的模式,

設計模式簡單工廠模式

簡單工廠模式又叫做靜態工廠方法模式,不屬於23種設計模式中的一種。 簡單工廠模式是工廠模式家族中最簡單的一種。 簡單工廠模式具有以下優點: 讓外界可以從直接建立具體物件的尷尬局面解脫出來,僅僅負責“消費”物件就可以了 外界不必管這些物件究竟如何建立及組織

設計模式之策略模式&amp;簡單工廠模式

抽象 jsb args watermark amp pri eas 時間 並且 學習設計模式已經有非常長一段時間了。事實上先前已經敲過一遍了,可是老認為沒有學到什麽,認識也不夠深刻,如今趁著重構機房。再又一次來過,也不晚。 事實上在敲了機房之後,看看模式,事實

Note8:C#設計模式工廠方法模式(VS 簡單工廠模式 & 抽象工廠模式

工廠方法模式 blog 抽象工廠 nbsp strong str cnblogs note 設計 一、資源說明 (1)本文有參考:http://www.cnblogs.com/zhili/p/FactoryMethod.html 待更!Note8:C#設計模式—工廠方法

簡單工廠模式

returns 原則 分離 問題 簡單的 編號 tor 在一起 分享 設計模式分類:  創建型模式。  結構型模式。  行為模式。   23種設計模式,如何記。面向對象的系統中有很多對象,創建型模式解決的問題就是如何創建對象,何時創建對象,它努力的讓代碼不要太多的關註對象的

【JS設計模式】溫習簡單工廠模式工廠方法模式、抽象工廠模式概念

his mac script 開頭 str new 每一個 簡單工廠 pattern 註:空心箭頭表示的是種繼承關系,工廠類和產品類之間是一種依賴關系。是用箭頭加虛線表示的,以下的模型圖是用的實線是不正確(時間不夠用,在這裏我偷懶了。這個習慣不好,呵呵)簡單工廠模式(S

(原創)我眼中的設計模式系列之簡單工廠模式(一)

int 業務 text 們的 acc 現在 rgs sub reat 簡單工廠模式   在日常的軟件開發中,我們一般都是按照模塊來劃分工作的。 場景一:   試想我們現在有這麽一個模塊,為其他的模塊提供服務,比如說我們調用了好幾個外部接口,統一返回XML字符串,每個接口返回

Java設計模式百例 - 簡單工廠模式

java設計模式工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象很好的方式。具體來說,有簡單工廠模式(simple factory)、工廠方法模式(factory method)和抽象工廠模式(abstract factor