[英]Restricted class factory design pattern
有沒有一種優雅的(或任何)方式來實現C#的關注?
ItemBase
類(進一步ItemBase
到Item1
, Item2
...),該類不允許直接實例化(非公共構造)-防止用戶創建Item*
任何“未跟蹤”實例。 Manager
,其實例(允許多個實例) 只能創建和提供Item*
實例(因為它們會跟蹤生成的實例並做一些額外的工作)。 Manager
實例想操縱托管Item
實例的非公共成員(類似於Manager
成為Item*
的friend
)。 Manager
衍生Item*
那將是很好的。 筆記:
如果可能的話,請考慮從如何以最佳,優雅的方式實施特定問題解決方案的過程中提出這個問題。 我希望它是通用的,不,我沒有資源,是的,我已經嘗試了一些變體,但是沒有一個能滿足我的需求。 謝謝。
據我所知,沒有可以接受的friend
替代方法( internal
和InternalsVisibleToAttribute
都不錯),因此ItemBase
僅提供了“特殊”(但公共)修改方法,用戶必須知道,這些方法不是為他:o(
我喜歡這種解決方案 ,但是我無法發明如何允許多個Manager
實例使用它。
我認為這可能會回答您的問題:
public class ItemBase
{
protected ItemBase()
{
}
public void PublicMethod() { }
public int PublicProperty { get; set; }
}
public class Factory
{
private class PrivateItemBase : ItemBase
{
public void PrivateMethod() { }
public int PrivateProperty { get; set; }
}
public Factory(int id)
{
}
public IEnumerable<ItemBase> Items { get; private set; }
public ItemBase CreateItem()
{
PrivateItemBase rValue = new PrivateItemBase();
rValue.PrivateMethod();
rValue.PrivateProperty = 4;
return rValue;
}
}
好的,放棄。 如果這可以幫助您充分理解其目的,那么我(目前)最終會找到一種較差的解決方案。 傳遞創建函數是通過靜態構造函數(用戶無法訪問)完成的,不幸的是,丑陋的事情是它們的調用...
知道如何使它變得更好嗎?
項目定義:
namespace SpecialFactory
{
public enum ItemType
{
Item1,
Item2,
// ... Anyone deriving the Item* should add an item here
}
public abstract class ItemBase
{
public abstract ItemType Id {get;}
public static void RegisterAllCreators()
{
// Force static constructors invocation
var it = Item1.ClassId | Item2.ClassId; // Anyone deriving the Item* should ensure invocation of Manager.RegisterCreator
}
}
public class Item1 : ItemBase
{
static Item1()
{
Manager.RegisterCreator(ItemType.Item1, () => new Item1());
}
protected Item1()
{
}
public static ItemType ClassId => ItemType.Item1;
public override ItemType Id => ClassId;
}
public class Item2 : ItemBase
{
static Item2()
{
Manager.RegisterCreator(ItemType.Item2, () => new Item2());
}
protected Item2()
{
}
public static ItemType ClassId => ItemType.Item2;
public override ItemType Id => ClassId;
}
}
管理者:
namespace SpecialFactory
{
public class Manager
{
static Manager()
{
ItemBase.RegisterAllCreators();
}
protected static Dictionary<ItemType, Func<ItemBase>> creators = new Dictionary<ItemType, Func<ItemBase>>();
protected readonly List<ItemBase> managedItems = new List<ItemBase>();
protected ItemBase CreateItem(ItemType type)
{
ItemBase item = null;
if (creators.ContainsKey(type))
{
if ((item = creators[type]()) != null)
managedItems.Add(item);
}
return item;
}
public static void RegisterCreator(ItemType type, Func<ItemBase> creator)
{
if (!creators.ContainsKey(type))
creators[type] = creator;
}
public Manager()
{
}
public ItemBase Test(ItemType type)
{
// var notAllowed = new Item1();
var allowed = CreateItem(type);
return allowed;
}
}
}
考試:
namespace SpecialFactory
{
class Program
{
static void Main(string[] args)
{
var m1 = new Manager();
var m2 = new Manager();
var i1 = m1.Test(ItemType.Item1);
var i2 = m2.Test(ItemType.Item2);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.