何时使用Factory方法模式?
请提供一些具体的想法何时在项目中使用它?以及它如何比新关键字更好的方式?
所以我有一个工厂类,我正在尝试研究单元测试应该做什么.从这个问题我可以验证返回的接口是我期望的特定具体类型.
如果工厂返回具体类型,我应该检查什么(因为目前不需要使用接口)?目前我做的事情如下:
[Test]
public void CreateSomeClassWithDependencies()
{
// m_factory is instantiated in the SetUp method
var someClass = m_factory.CreateSomeClassWithDependencies();
Assert.IsNotNull(someClass);
}
Run Code Online (Sandbox Code Playgroud)
这个问题是Assert.IsNotNull看起来有点多余.
另外,我的工厂方法可能正在设置该特定类的依赖关系,如下所示:
public SomeClass CreateSomeClassWithDependencies()
{
return new SomeClass(CreateADependency(), CreateAnotherDependency(),
CreateAThirdDependency());
}
Run Code Online (Sandbox Code Playgroud)
我想确保我的工厂方法正确设置所有这些依赖项.有没有其他方法可以做到这一点来制作那些public/internal我在单元测试中检查的依赖属性?(我不是修改测试对象以适应测试的忠实粉丝)
编辑:回应罗伯特哈维的问题,我正在使用NUnit作为我的单元测试框架(但我不会认为它会产生太多差异)
我经常看到这个词,我可能已经在代码和库中使用了它,但我从来没有真正得到它.在我看到的大多数写作中,他们只是希望你能弄明白.
什么是班级工厂?有人可以解释这个概念吗?
这是关于工厂模式.我有点困惑.
我看到了createInstance()方法是静态的实现和一些非静态的实现.
有人说这取决于"风格"或"味道",有些人说它没有.维基百科说它应该是非静态的,并且http://www.dofactory.com/Patterns/PatternFactory.aspx也表示它应该是非静态的,根据Gang of Four的说法.
我的问题是:它是否依赖于风格和品味,或者它是否违反了工厂模式,如果它是以静态方式实现的?什么是对的?
design-patterns factory factory-method factory-pattern static-factory
我有很多(抽象的)工厂,他们通常被实施为单身人士.
通常是为了方便不必将它们传递给真正与使用或了解这些工厂无关的层.
大多数时候我只需要在启动哪个工厂实现代码程序的其余部分时做出决定,也许可以通过一些配置
它看起来像是
abstract class ColumnCalculationFactory {
private static ColumnCalculationFactory factory;
public static void SetFactory(ColumnCalculationFactory f) {
factory = f;
}
public static void Factory() {
return factory;
}
public IPercentCalculation CreatePercentCalculation();
public IAverageCalculation CreateAverageCalculation();
....
}
Run Code Online (Sandbox Code Playgroud)
有些人闻到了这一点,我只是不确定是什么 - 它可能更像是一个被解雇的全球而不是单身人士.这并不是真的必须只有一个工厂创建ColumnCalculations - 虽然我的程序不需要更多.
这被认为是最佳实践吗?我应该在一些(半)全局AppContext类中填充它们吗?还有别的东西(我还没准备好切换到一些更大的IoC容器,还是转向一下spring.net)?
我正在使用这个:
但在尝试运行我的应用程序时,我得到以下异常:
java.lang.IllegalStateException: Could not find backup for factory javax.faces.application.ApplicationFactory.
at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:1011)
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:343)
at org.apache.myfaces.context.servlet.FacesContextImplBase.getApplication(FacesContextImplBase.java:159)
at org.apache.myfaces.context.servlet.FacesContextImplBase.getELContext(FacesContextImplBase.java:210)
at javax.faces.component.UIViewRoot.setLocale(UIViewRoot.java:1463)
at org.apache.myfaces.webapp.AbstractFacesInitializer._createFacesContext(AbstractFacesInitializer.java:477)
at org.apache.myfaces.webapp.AbstractFacesInitializer.initStartupFacesContext(AbstractFacesInitializer.java:449)
at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:113)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4797)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5291)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
谢谢,
我有一个带有静态工厂方法的类.我想调用工厂来检索类的实例,然后通过c#object initializer语法进行额外的初始化:
MyClass instance = MyClass.FactoryCreate()
{
someProperty = someValue;
}
Run Code Online (Sandbox Code Playgroud)
VS
MyClass instance = MyClass.FactoryCreate();
instance.someProperty = someValue;
Run Code Online (Sandbox Code Playgroud) Factory Girl是一个方便的rails框架,可以轻松创建测试模型实例.
factory_girl允许您快速定义每个模型的原型,并询问具有对手头测试很重要的属性的实例.
一个例子(也来自主页):
Factory.sequence :email do |n|
"somebody#{n}@example.com"
end
# Let's define a factory for the User model. The class name is guessed from the
# factory name.
Factory.define :user do |f|
# These properties are set statically, and are evaluated when the factory is
# defined.
f.first_name 'John'
f.last_name 'Doe'
f.admin false
# This property is set "lazily." The block will be called whenever an
# instance is generated, and the return value of …Run Code Online (Sandbox Code Playgroud) Java允许我们在Enum上嵌入数据和行为.我不想直接在Enum上实现工厂,因为我认为这不是它的作用.
但我可以在枚举上放置类引用,并在外部工厂上构造对象.与传统工厂模式相比,您的最佳实施方案是什么?在哪种情况下哪种解决方案更好用?
现在,代码.
两种解决方案中用于构造对象的函数.如果需要,可以使用Map实现fly-weight模式.
private Action getAction(Class<? extends Action> actionClazz) {
// logger + error handling
return actionClazz.newInstance();
}
Run Code Online (Sandbox Code Playgroud)
1)与传统工厂:
public enum ActionEnum {
LOAD_DATA,
LOAD_CONFIG;
}
public Action getAction(ActionEnum action) {
switch (action) {
case LOAD_CONFIG:
return getAction(ActionLoadConfig.class);
case LOAD_DATA:
return getAction(ActionLoadData.class);
}
}
Run Code Online (Sandbox Code Playgroud)
2)使用Enum风格的工厂:
public enum ActionEnum {
LOAD_DATA(ActionLoadConfig.class),
LOAD_CONFIG(ActionLoadData.class);
public ActionEnum(Class<? extends Action> clazz){...}
public Class<? extends Action> getClazz() {return this.clazz}
}
public Action getAction(ActionEnum action) {
return getAction(action.getClazz());
}
Run Code Online (Sandbox Code Playgroud) 我有一堂课Foo
class Foo;
Run Code Online (Sandbox Code Playgroud)
工厂返回指针:
std::unique_ptr<Foo> createFoo();
Run Code Online (Sandbox Code Playgroud)
因为Herb告诉我,在Foo的一生中没有特别要求的普通函数应该采用简单的指针:
void plainf(Foo* f);
Run Code Online (Sandbox Code Playgroud)
我的客户应该如何正确地做到这一点?
plainF(createFoo());
Run Code Online (Sandbox Code Playgroud)
如果他不得不写,他会不高兴:
auto someName = createFoo();
plainF(someName.get());
Run Code Online (Sandbox Code Playgroud) factory ×10
c# ×2
java ×2
unit-testing ×2
c++ ×1
class ×1
enums ×1
factory-bot ×1
initializer ×1
jsf ×1
jsf-2 ×1
object ×1
singleton ×1
tdd ×1
temporary ×1