Saya pikir cara paling umum untuk menambahkan sesuatu ke koleksi adalah dengan menggunakan beberapa Add
metode yang disediakan oleh koleksi:
class Item {}
var items = new List<Item>();
items.Add(new Item());
dan sebenarnya tidak ada yang aneh tentang itu.
Namun saya heran mengapa kita tidak melakukannya dengan cara ini:
var item = new Item();
item.AddTo(items);
tampaknya lebih alami daripada metode pertama. Ini akan memiliki andantange bahwa ketika Item
kelas memiliki properti seperti Parent
:
class Item
{
public object Parent { get; private set; }
}
Anda dapat menjadikan setter pribadi. Dalam hal ini tentu saja Anda tidak dapat menggunakan metode ekstensi.
Tapi mungkin saya salah dan saya belum pernah melihat pola ini sebelumnya karena itu sangat jarang? Apakah Anda tahu ada pola seperti itu?
Dalam C#
suatu metode ekstensi akan berguna untuk itu
public static T AddTo(this T item, IList<T> list)
{
list.Add(item);
return item;
}
Bagaimana dengan bahasa lain? Saya kira sebagian besar dari mereka Item
harus menyediakan ICollectionItem
antarmuka , sebut saja antarmuka.
Perbarui-1
Saya telah memikirkannya sedikit lebih banyak dan pola ini akan sangat berguna misalnya jika Anda tidak ingin item ditambahkan ke beberapa koleksi.
ICollectable
antarmuka uji :
interface ICollectable<T>
{
// Gets a value indicating whether the item can be in multiple collections.
bool CanBeInMultipleCollections { get; }
// Gets a list of item's owners.
List<ICollection<T>> Owners { get; }
// Adds the item to a collection.
ICollectable<T> AddTo(ICollection<T> collection);
// Removes the item from a collection.
ICollectable<T> RemoveFrom(ICollection<T> collection);
// Checks if the item is in a collection.
bool IsIn(ICollection<T> collection);
}
dan contoh implementasi:
class NodeList : List<NodeList>, ICollectable<NodeList>
{
#region ICollectable implementation.
List<ICollection<NodeList>> owners = new List<ICollection<NodeList>>();
public bool CanBeInMultipleCollections
{
get { return false; }
}
public ICollectable<NodeList> AddTo(ICollection<NodeList> collection)
{
if (IsIn(collection))
{
throw new InvalidOperationException("Item already added.");
}
if (!CanBeInMultipleCollections)
{
bool isInAnotherCollection = owners.Count > 0;
if (isInAnotherCollection)
{
throw new InvalidOperationException("Item is already in another collection.");
}
}
collection.Add(this);
owners.Add(collection);
return this;
}
public ICollectable<NodeList> RemoveFrom(ICollection<NodeList> collection)
{
owners.Remove(collection);
collection.Remove(this);
return this;
}
public List<ICollection<NodeList>> Owners
{
get { return owners; }
}
public bool IsIn(ICollection<NodeList> collection)
{
return collection.Contains(this);
}
#endregion
}
pemakaian:
var rootNodeList1 = new NodeList();
var rootNodeList2 = new NodeList();
var subNodeList4 = new NodeList().AddTo(rootNodeList1);
// Let's move it to the other root node:
subNodeList4.RemoveFrom(rootNodeList1).AddTo(rootNodeList2);
// Let's try to add it to the first root node again...
// and it will throw an exception because it can be in only one collection at the same time.
subNodeList4.AddTo(rootNodeList1);
add(item, collection)
, tapi itu bukan gaya OO yang baik.
item.AddTo(items)
misalkan Anda memiliki bahasa tanpa metode ekstensi: alami atau tidak, untuk mendukung addTo, setiap jenis memerlukan metode ini dan menyediakannya untuk setiap jenis koleksi yang mendukung penambahan. Itu seperti contoh terbaik untuk memperkenalkan dependensi antara semua yang pernah saya dengar: P - Saya pikir premis yang salah di sini sedang mencoba untuk memodelkan beberapa abstraksi pemrograman ke kehidupan 'nyata'. Itu sering salah.