【发布时间】:2011-12-02 19:11:17
【问题描述】:
我正在尝试为我的服务工厂和 dao 工厂创建一些通用工厂,但遇到了一些限制。
我的服务和 dao 工厂通常如下所示:
public static class PersonServiceFactory
{
private static PersonService personService;
public static PersonService GetInstance()
{
if (personService == null)
{
PersonDao personDao = PersonDaoFactory.GetInstance();
personService = new PersonService(personDao);
}
return personService;
}
}
public static class PersonDaoFactory
{
private static PersonDao personDao;
internal static PersonDao GetInstance()
{
if (personDao == null)
{
personDao = new PersonDao();
}
return personDao;
}
}
然后我尝试做一个通用工厂:
public abstract class EntityDaoFactory<daoClass>
where daoClass : class, new()
{
private static daoClass factorySupportClass;
internal static daoClass GetInstance()
{
if (factorySupportClass == null)
{
factorySupportClass = new daoClass();
}
return factorySupportClass;
}
}
public abstract class EntityServiceFactory<serviceClass, daoClass>
where serviceClass : class, new()
where daoClass : class
{
private static serviceClass factorySupportClass;
internal static serviceClass GetInstance()
{
if (factorySupportClass == null)
{
//daoClass daoSupportClass = *how to get daoSupportClassfactory.GetInstance(); here?*
factorySupportClass = new serviceClass(daoSupportClass);
}
return factorySupportClass;
}
}
所以他们可以这样使用:
public static class PersonDaoFactory : Entities.EntityDaoFactory<PersonDao>
{
}
public static class PersonServiceFactory : Entities.EntityServiceFactory<PersonService, PersonDaoFactory>
{
}
以下是我遇到的问题:
不能使用静态类作为泛型的类型约束,我试图将其用于 EntityServiceFactory,因为没有它我不知道如何注入适当的 dao。
不能让工厂派生自通用工厂,因为我收到如下错误:
静态类“Persons.PersonDaoFactory”不能 从类型派生 '实体.EntityDaoFactory'。 静态类必须派生自对象。
- 尝试使用私有构造函数将它们全部设为非静态类以解决该问题,但后来我得到:
'Persons.PersonService' 必须是具有公共的非抽象类型 无参数构造函数,以便将其用作参数 泛型类型或方法中的“serviceClass” 'Entity.EntityServiceFactory
我能够读懂为什么会出现第 3 个数字,但这仍然不能解决我的问题。我让 DaoFactory 工作了,但它只有在特定的 DaoClass 不需要任何依赖注入时才有效,否则会再次弹出错误 3。
有没有办法让这些通用工厂使用不同的方法工作,同时仍然能够使用 DI?
编辑----
我能够进行这种工作,但它有一些奇怪之处。首先我创建了一个 IEntityFactory 接口:
public interface IEntityFactory<T>
where T : class
{
T GetInstance();
}
然后将EntityDaoFactory改为:
public abstract class EntityDaoFactory<daoClass> : IEntityFactory<daoClass>
where daoClass : class, new()
{
private static daoClass factorySupportClass;
public daoClass GetInstance()
{
if (factorySupportClass == null)
{
factorySupportClass = new daoClass();
}
return factorySupportClass;
}
}
所以我可以传入适当的类型参数并将 EntityServiceFactory 更改为:
public abstract class EntityServiceFactory<serviceClass, daoClass, daoFactoryClass>
where serviceClass : class, new()
where daoClass : class, new()
where daoFactoryClass : IEntityFactory<daoClass>, new()
{
private static serviceClass factorySupportClass;
public static serviceClass GetInstance()
{
if (factorySupportClass == null)
{
daoFactoryClass daoSupportFactory = new daoFactoryClass();
daoClass daoSupportClass = daoSupportFactory.GetInstance();
factorySupportClass = new serviceClass();
}
return factorySupportClass;
}
}
因此,对于特定的实现,例如 Person 对象,调用如下所示:
public class PersonDaoFactory : Entities.EntityDaoFactory<PersonDao>
{
}
public class PersonServiceFactory : Entities.EntityServiceFactory<PersonService, PersonDao, PersonDaoFactory>
{
}
所以它现在可以工作了,但奇怪的是:
您可以实例化一个工厂,这是 EntityServiceFactory 所必需的(据我所知,这是唯一的方法吗?),但对于使用我的 API 的人来说,他们没有理由这样做,但是他们仍然可以。
现在可以在没有参数的情况下实例化具有依赖性要求的服务和 DAO,这会破坏实例化的类方法(但我必须这样做才能将其用作类型参数)。他们甚至不应该通过实例化这些对象,但他们现在可以并且错误地这样做。
我刚刚想到的最后一个问题是这个解决方案并不能很好地处理可变数量的依赖关系。仍然想知道是否有更好的方法来解决这个问题?
结论:我认为最终即使它有效,我还是放弃了很多订单来拥有那个通用工厂,它不是那么灵活并且没有给我太多,所以我可能由于限制,在这种情况下不会使用它。
【问题讨论】:
-
看起来你所有的问题都是因为你已经将工厂标记为静态这没有意义此外考虑到你将使用 DI 来减少这种静态依赖
-
这些与单身人士有着惊人的相似之处。
-
如果你只需要建造一个东西,你就不需要建造工厂。
-
en.wikipedia.org/wiki/Factory_pattern "例如,使用这个定义,单例模式实现的单例就是正式工厂。"
-
@DOTang:确实。但是你不会在需要实例化某些东西的地方使用单例(
new()要求)。