Ich denke, die gebräuchlichste Add
Methode, einer Sammlung etwas hinzuzufügen, ist die Verwendung einer Methode, die eine Sammlung bietet:
class Item {}
var items = new List<Item>();
items.Add(new Item());
und daran ist eigentlich nichts ungewöhnliches.
Ich frage mich jedoch, warum wir das nicht so machen:
var item = new Item();
item.AddTo(items);
es scheint irgendwie natürlicher zu sein als die erste Methode. Dies hätte den Vorteil, dass, wenn die Item
Klasse eine Eigenschaft wie folgt hat Parent
:
class Item
{
public object Parent { get; private set; }
}
Sie können den Setter privat machen. In diesem Fall können Sie natürlich keine Erweiterungsmethode verwenden.
Aber vielleicht irre ich mich und habe dieses Muster noch nie gesehen, weil es so ungewöhnlich ist? Wissen Sie, ob es ein solches Muster gibt?
In C#
einer Erweiterungsmethode wäre das sinnvoll
public static T AddTo(this T item, IList<T> list)
{
list.Add(item);
return item;
}
Wie wäre es mit anderen Sprachen? Ich denke, in den meisten von ihnen musste die Item
Klasse eine ICollectionItem
Schnittstelle bereitstellen, die wir sie nennen .
Update-1
Ich habe ein bisschen mehr darüber nachgedacht und dieses Muster wäre zum Beispiel wirklich nützlich, wenn Sie nicht möchten, dass ein Artikel mehreren Sammlungen hinzugefügt wird.
Testschnittstelle ICollectable
:
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);
}
und eine Beispielimplementierung:
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
}
Verwendung:
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)
, aber das ist kein guter OO-Stil.
item.AddTo(items)
Angenommen, Sie haben eine Sprache ohne Erweiterungsmethoden: natürlich oder nicht, um addTo zu unterstützen, würde jeder Typ diese Methode benötigen und für jede Art von Sammlung bereitstellen, die das Anhängen unterstützt. Das ist wie das beste Beispiel für die Einführung von Abhängigkeiten zwischen allem, was ich jemals gehört habe: P - Ich denke, die falsche Prämisse hier ist der Versuch, eine Programmierabstraktion für das „echte“ Leben zu modellieren. Das geht oft schief.