[英]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.