[go語言]避免過度重構

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。golang-nuts上有人提了一個問題[1],詢問怎麼樣把減少兩個類似資料結構和演算法的重複代碼。簡而言之,有兩個struct:QuickFindSet和QuickUnionSet,它們各有Count,IsConnected, Find,Union等方法。他發現這兩個struct的一些函數的實現是一樣的,因此他希望能消除這些重複代碼。// quick-findtype QuickFindSet struct {
numOfComponents uintitems []uint
}
func NewSet(n uint) QuickFindSet{
set := QuickFindSet{ numOfComponents: n,items: make([]uint, n) }for i, _ := range set.items{
set.items[i] = uint(i)
}return set
}
func (set *QuickFindSet) Count() uint{
return set.numOfComponents
}
func (set *QuickFindSet) IsConnected (p,q uint) bool {
return set.Find(p) ==set.Find(q)
}
func (set *QuickFindSet) Find(p uint)uint {
return set.items[p]
}
func (set *QuickFindSet) Union(p, quint) {
rootP := set.Find(p)rootQ := set.Find(q)if rootP == rootQ {
return
}for i, _ := range set.items{
if set.items[i] == rootP {
set.items[i] = rootQ
}
}set.numOfComponents--
}
// weighted quick-uniontype QuickUnionSet struct {
numOfComponents uintitems []uintsizes []uint
}
func NewSet(n uint) QuickUnionSet{
set := QuickUnionSet{ numOfComponents:n, items: make([]uint, n), sizes: make([]uint, n) }for i, _ := range set.items{
set.items[i] = uint(i)
set.sizes[i] = uint(1)
}return set
}
func (set *QuickUnionSet) Count() uint{
return set.numOfComponents
}
func (set *QuickUnionSet) IsConnected(p, q uint) bool {
return set.Find(p) ==set.Find(q)
}
func (set *QuickUnionSet) Find(p uint)uint {
for p != set.items[p] {
p = set.items[p]
}return p
}
func (set *QuickUnionSet) Union(p, quint) {
rootP := set.Find(p)rootQ := set.Find(q)if rootP == rootQ {
return
}if set.sizes[rootP] <set.sizes[rootQ] {
set.items[rootP] = rootQ
set.sizes[rootQ] +=set.sizes[rootP]
} else {
set.items[rootQ] = rootP
set.sizes[rootP] +=set.sizes[rootQ]
}set.numOfComponents--
}
可以看到,QuickFindSet和QuickUnionSet的Count和IsConnected函數的實現是一樣的:func (set*QuickFindSet) Count() uint {
returnset.numOfComponents
}func(set *QuickFindSet) IsConnected (p, q uint) bool{
return set.Find(p) ==set.Find(q)
}func (set*QuickUnionSet) Count() uint {
returnset.numOfComponents
}func(set *QuickUnionSet) IsConnected (p, q uint) bool{
return set.Find(p) ==set.Find(q)
}作者說他編程的時候總是想把重複的代碼消除掉,在其他的語言裡可以用class或者宏來達到這個目的,他想知道在go語言裡怎麼樣做比較好。事實上這裡還有一個問題:這裡需要重構來消除重複代碼嗎?或者說,什麼樣的情況下需要重構代碼?我認為,以下條件同時滿足時才需要重構代碼:
  1. 代碼非常的混亂以至於很難閱讀
  2. 已有需有或者有潛在的需求需要修改代碼
而對比這裡的代碼:
  1. 這裡重複的代碼非常少,只有幾行代碼。代碼結構也比較清晰。
  2. 作為一個和商務邏輯關聯不大的基礎資料結構,變化的需求很小。
因此我的結論是:這裡的代碼不需要重構,不需要去消除那寥寥幾行的重複代碼。也有人從另外一個角度提出意見:減少這些演算法的重複代碼也意味著它們之間耦合更加緊密,如果以後需要修改其中的一個演算法,會影響到其他的演算法實現;而一定的重複代碼可以保持它們之間的獨立性。
Russ Cox也給出了類似的意見:確實在其他語言裡可以使用帶有虛擬方法的抽象類別來消除這樣很小的代碼重複,但它也會把這兩個實際上只有很少共同點的演算法實現捆綁在一起。保留獨立代碼的好處遠遠超過減少一兩行重複代碼的便利。(Itis true that (in other languages) one could use 'abstract classeswith virtual methods' to eliminate this minor duplication, but itwould also tie together two implementations that really have verylittle in common. The benefits of keeping separate things separatefar outweighs the minor convenience of avoiding a duplicated lineor two. )
最後,我的結語是:凡事都有個度,怎麼樣避免過度重構呢?也許我們可以從重構的動機和結果來考慮一下,而不只是為了重構而重構。
[1]https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/6GAfbi-BpVE
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.