我編碼一個二叉樹作爲學習練習的一部分。我試圖去適應在二叉樹中刪除節點的兩種方法:DeleteByMerge和DeleteByCopy。在這種情況下,我是否正確地選擇了繼承的組合?
爲用戶提供選擇這些方法的最佳方式是什麼?
我傾向於一個組合方法(如策略):
public class BinaryTree{
BtreeDelete del;
public BinaryTree(){
this.del = new DeleteByCopy();
}
public BinaryTree(BtreeDelete del){
this.del = del;
}
public boolean delete(Node node){
// Common code
del.delete()
}
}
類DeleteByMerge和DeleteByCopy實現接口BtreeDelete,這樣我就可以在實例化線了類似這樣的:
BinaryTree btree = new BinaryTree(new DeleteByMerge());
或
BinaryTree btree = new BinaryTree(new DeleteByCopy());
。基於
繼承方法:
public class BinaryTree{
public BinaryTree(){
}
public boolean delete(Node node){
// Common code
deleteNode();
}
// An overriddable hook with a default implementation
protected boolean deleteNode(Node node){
//By default implementation for DeleteByCopy is provided
}
}
不同實現刪除將要求一個獨立的子類(導致類可能爆炸):
public class BtreeDelByMerge extends BinaryTree{
protected boolean deleteNode(Node node){
// Code for deleting a node by Merging
}
}
我與繼承方法的疑慮是BtreeDelByMerge不是一種Btree類型,它的行爲不會變化太大,並且爲其方法之一創建單獨的子類似乎不自然。如果我想要一個具有插入的特定實現以及刪除等的樹,它也不會像構圖方法那麼好。
在這種情況下繼承方式有什麼特別的優勢嗎?另外,提供所有選擇是一個好主意嗎?例如:集合框架沒有提供太多的選擇,所以實現的封裝很好,一致但僵化。
爲什麼'BtreeDelByMerge'不是'Btree'類型?我看到你沒有從'Btree'擴展它,但是你有它繼承'deleteNode()',所以我認爲你就是這麼做的。就我個人而言,我會在這裏繼承。如果你擔心太多的實現,允許人們通過構造函數即插即用幫助對象只會複雜化。 –
看看[這篇文章](http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance)。 'DeleteByCopy'和'DeleteByMerge'都提供了'deleteNode'方法,我認爲他們在這個問題上共享相同的接口是合適的。 –
@ musical_coder是的,我編輯了從BinaryTree繼承的代碼。通過繼承方法,當涉及到連接不同的實現時,我如何提供與組合方法相同的靈活性? – ChrisOdney