元語言抽象就是建立新的語言。它在工程設計的所有分支中都扮演著重要的角色,在電腦程式設計領域更是特別重要。因為這個領域中,我們不僅可以設計新的語言,還可以通過構造求值器的方式實現這些語言。對某個程式設計語言的求值器(或者解釋器)也是一個過程,在應用於這個語言的一個表達式時,它能夠執行求值這個表達式所... ...
最近在看《大話設計模式》,這本書通過對話形式講解設計模式的使用場景,有興趣的可以去看一下。
第一篇講的是簡單工廠模式,要求輸入兩個數和運算符號,得到運行結果。
這個需求不難,難就難在類要怎麼設計,才能達到可復用、維護性強、可拓展和靈活性高。
運算符可能是加、減、乘、除,未了方便以後可以拓展其它運算符,這裡可以聲明一個抽象介面,通過簡單工廠設計模式返回不通的運算類。
package operate
type IOperate interface {
GetResult(a int, b int) int
}
首先聲明一個IOperate
抽象介面表示運算,然後新建Add
、Sub
、Mul
和Div
結構體實現這個運行介面:
package operate
type Add struct{}
func (o Add) GetResult(a int, b int) int {
return a + b
}
type Sub struct{}
func (o Sub) GetResult(a int, b int) int {
return a - b
}
type Mul struct{}
func (o Mul) GetResult(a int, b int) int {
return a * b
}
type Div struct{}
func (o Div) GetResult(a int, b int) int {
if b == 0 {
panic("除數不能為0")
}
return a / b
}
然後定義一個工廠,參數為運算符號:
package main
// NewOperate 按照操作符號創建操作對象
func NewOperate(o string) operate.IOperate {
switch o {
case "+":
return operate.Add{}
case "-":
return operate.Sub{}
case "*":
return operate.Mul{}
case "/":
return operate.Div{}
default:
panic("操作符號錯誤")
}
}
最後運行:
package main
import "fmt"
func main() {
var a, b int
fmt.Println("請輸入兩個數:")
fmt.Scanf("%d %d", &a, &b)
fmt.Println("請輸入運算符號(+、-、*、/):")
var operate string
fmt.Scanf("%s", &operate)
operateObj := NewOperate(operate)
result := operateObj.GetResult(a, b)
fmt.Printf("%d %s %d = %d\n", a, operate, b, result)
}
要增加不同的運算操作只需要新增實現了抽象運算介面的結構體和修改工廠,因為go
語言的函數也是一種類型,其實上面的代碼可以簡化,不用每次都新增一個結構體:
type OperateFun func(a, b int) int
// GetOperateFunc 按照操作符號創建操作函數,函數式編程
func GetOperateFunc(o string) OperateFun {
switch o {
case "+":
return func(a, b int) int {
return a + b
}
case "-":
return func(a, b int) int {
return a - b
}
case "*":
return func(a, b int) int {
return a * b
}
case "/":
return func(a, b int) int {
if b == 0 {
panic("除數不能為0")
}
return a / b
}
default:
panic("操作符號錯誤")
}
main
函數可以這樣調用:
var a, b int
fmt.Println("請輸入兩個數:")
fmt.Scanf("%d %d", &a, &b)
fmt.Println("請輸入運算符號(+、-、*、/):")
var operate string
fmt.Scanf("%s", &operate)
operateFun := GetOperateFunc(operate)
result = operateFun(a, b)
fmt.Printf("%d %s %d = %d\n", a, operate, b, result)
寫業務代碼還是要多想一下用什麼設計模式合適,避免編寫的代碼後面不好維護和擴展,這需要多練習。