[英]Is it a bad practice to add elements to List using getter method in java?
假設我在一個類中有一個private ArrayList
或一個LinkedList
,我永遠不會為它分配新的引用,或者換句話說,這永遠不會發生:
myLinkedList = anotherLinkedList;
這樣我就不需要使用setMyLinkedList(anotherLinkedList)
。
但! 我需要向其中添加元素,或從中刪除元素。
我是否應該只編寫一種新的setter
來執行adding
而不是setting
的任務,例如myLinkedList.add(someElement)
?
或者可以通過使用getter
來做到這一點,而不違反Encapsulation
原則?
getMyLinkedList().add(someElement)
(+假設如果我不遵守封裝,我將失去我的標記:-”)
我不認為做這樣的事情是一個特別好的做法:
myObj.getMyList().add(x);
因為您以非只讀方式公開私有類變量,但據說我確實經常看到它(我正在看着您,自動生成的類)。 我認為與其這樣做,不如返回一個不可修改的列表,並允許類的用戶通過顯式方法添加到列表中:
public class MyClass{
private final List<String> myList = new ArrayList<String>();
public List<String> getList(){
return Collections.unmodifiableList(this.myList);
}
public void addToList(final String s){
this.myList.add(s);
}
}
編輯在查看您的評論后,我想添加一些關於您的二傳手想法:
我的意思是在類本身內部的一種新的 setter 中使用那行代碼,比如 public void setter(someElement){this.myLinkedList.add(someElement);}
如果我正確理解您,您是說您想公開一個只會添加到您的列表中的方法。 總的來說,這就是我認為您應該追求的目標,以及許多人在答案中概述的內容,但是,將其標記為 setter 有點誤導,因為您沒有重新分配(設置)任何東西。 如果可能,我強烈建議從您的 getter 方法返回只讀列表。
我建議在這種情況下最好遵循您的封裝原則並使用一種方法將元素添加到列表中。 您通過將列表設為private
來限制對列表的訪問,以便其他類無法直接訪問該數據類型。
讓存儲您的ArrayList
的類可以直接訪問列表,但是當其他類想要添加到列表時,請使用add()
方法。
通常,您不應假設 getter 返回的列表是原始列表。 例如,它可以被裝飾或代理。 如果要防止在目標對象上設置新列表,則可以改為在目標類上定義 add 方法。
一旦您擁有任何類型的Collection
,如果客戶端可以從您的私有列表中添加或刪除對象是有意義的,那么將諸如add()
、 remove()
之類的方法add()
到您的類的接口中通常不是一個壞主意.
實現這些額外方法很有用的原因(這可能看起來有點矯枉過正,因為畢竟這些方法大多只是調用Collection
上的方法)是為了保護惡意客戶端不會對您不想要的列表做事他們來做,因為大多數Collection
的接口不僅僅包含add()
和remove()
方法,而且大多數情況下,您不希望客戶端處理您無法控制的事情。 因此封裝原則對你的老師來說很重要。
另一個優點:如果在任何時候,您決定在將對象添加到列表時必須滿足某個條件,這可以在您已有的方法中輕松實現。 如果您讓客戶訪問您的列表的直接引用,那么實現這種事情並不容易(這種情況並不少見)。
希望這可以幫助
所以你有一個包含List
字段的類(它應該是final
,因為你不打算分配給它),並且你希望允許調用者添加到List
,但不能替換它。
您可以為列表提供一個吸氣劑:
public List<E> getMyList() {
return myList;
}
或者提供一種添加到該列表的方法:
public void addToMyList(E e) {
myList.add(e);
}
兩者都是有效的設計決策,但您使用哪種取決於您的用例。 第一個選項使調用者可以直接訪問List
,從而有效地將其公開。 當用戶將重復修改和使用列表時,這很有用,但可能會出現問題,因為您不再相信List
處於任何可靠狀態(調用者可以清空它,或重新排序,甚至惡意插入對象不同的類型)。 因此,僅當您打算信任呼叫者時才應使用第一個選項。
第二個選項給調用者更少的權力,因為他們一次只能添加一個元素。 如果您想提供附加功能(插入、添加所有功能等),您必須依次包裝每個操作。 但它讓您更有信心,因為您可以確定List
僅以您認可的方式進行修改。 后一個選項還隱藏(封裝)您正在使用List
的實現細節,因此如果封裝對您的用例很重要,您希望采用這種方式來避免暴露您的內部數據結構,並且只公開行為你想授予調用者。
這取決於應用程序 - 兩者都是可以接受的。 仔細查看您正在編寫的類,並決定是否允許用戶直接訪問列表的內容,或者您是否希望他們先經歷一些中間過程。
例如,假設您有一個ListEncrypter
類,其中包含您的MyLinkedList
列表。 此類的目的是加密存儲在MyLinkedList
任何MyLinkedList
。 在這種情況下,您需要提供一個自定義 add 方法,以便在將添加的項目放入列表之前對其進行處理,並且如果您想訪問該元素,您還需要對其進行處理:
public void add(Object element)
{
MyLinkedList.add(encrypt(element););
}
public Object get(int index)
{
return decrypt(MyLinkedList.get(index););
}
在這種情況下,您顯然希望拒絕用戶訪問MyLinkedList
變量,因為內容將被加密並且他們將無法對其進行任何操作。
另一方面,如果您沒有真正對數據進行任何處理(並且您確定將來永遠不需要),您可以跳過創建專用方法而只允許用戶直接訪問通過get
方法get
列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.