什么是这家工厂,使用工厂模式的优势是什么?它是否提供可插拔架构?为什么它被称为"工厂"?
使用DI方法处理条件子工厂的正确方法是什么?场景是注入到条目中的加载器对象取决于该条目的设置.最初我是将IoC容器注入工厂并使用它来根据命名约定来解决.但是,我真的想保持工厂清洁容器.
将工厂注入到将从数据库加载所有设置的类中,然后使用工厂创建一组条目.这些设置确定将在给定条目内使用哪个加载器.
编辑:更改代码以更好地突出显示实际问题.问题是必须同时支持多个数据库管理器,如果不是这样,那么它将很简单.数据库管理器类型由为特定条目存储的条目设置确定.
public class Entry : IEntry
{
private ISomething loader;
public Entry(ISomething something)
{
this.loader = something;
}
}
public class EntryFactory : IEntryFactory
{
IEntry BuildEntry(IEntrySetting setting)
{
//Use setting object to determine which database manager will be used
}
}
public class EntryManager
{
public EntryManager(IEntryFactory entryFactory)
{
var entrySettings = this.settings.Load();
foreach(var setting in entrySettings)
{
this.entries.Add(entryFactory.BuildEntry(setting));
}
}
}
Run Code Online (Sandbox Code Playgroud)
我曾考虑让子工厂在主要工厂注册并以这种方式解决,但我不知道是否有更好的方法.
我正在尝试生成一个代表java.nio.file.Path使用静态方法的bean Paths.get(String path).我目前的Spring设置如下:
<bean id="myPath" class="java.nio.file.Paths" factory-method="get">
<constructor-arg value="c:\\tmp\\" />
</bean>
Run Code Online (Sandbox Code Playgroud)
但它带来了一个令人兴奋的回归No matching factory method found: factory method 'get'.任何想法为什么会这样?
我已经看到了通过引用类对象并使用一个create方法来实现对象创建工厂的地方:class.newInstance()它使用反射,与直接调用默认构造函数相比可能效率不高.
如果java支持类似的东西return new this();,我可以在父类中实现它,这将作为工厂方法(如果没有这样的构造函数,将抛出异常class.newInstance()).
为什么不支持这样的东西?
PS:我在stackOverflow中的第一个问题:)
我对工厂的理解是它封装了所有继承公共抽象类或接口的具体类的实例化.这允许客户端与确定要创建哪个具体类的过程分离,这反过来意味着您可以从程序中添加或删除具体类,而无需更改客户端的代码.你可能不得不改变工厂,但工厂是"专门建造的",实际上只有一个改变的理由 - 添加/删除了一个具体的类.
我已经构建了一些实际上封装了对象实例化的类,但原因不同:对象很难实例化.目前,我将这些类称为"工厂",但我担心这可能是一种误称,并会混淆其他可能会查看我的代码的程序员.我的"工厂"类没有决定实例化哪个具体类,它们保证一系列对象将以正确的顺序实例化,并且当我调用时,正确的类将被传递给正确的构造函数new().
例如,对于我正在处理的MVVM项目,我编写了一个类来确保我SetupView的实例化得当.它看起来像这样:
public class SetupViewFactory
{
public SetupView CreateView(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities)
{
var setupViewModel = new SetupViewModel(databaseModel, settingsModel, viewUtilities);
var setupView = new SetupView();
setupView.DataContext = setupViewModel;
return setupView;
}
}
Run Code Online (Sandbox Code Playgroud)
把它称为"工厂"是否令人困惑?它不决定几个可能的具体类,它的返回类型不是接口或抽象类型,但它确实封装了对象实例化.
如果它不是"工厂",它是什么?
编辑
很多人都认为这实际上是Builder Pattern.
从dofactory定义Builder Pattern 如下:
将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示.
这似乎也有点延伸.困扰我的是"不同的表现形式".我的目的不是抽象构建视图的过程(不是那个不值得的目标).我只是想在一个地方设置创建特定视图的逻辑,这样如果任何成分或创建该视图的过程发生变化,我只需要更改这一个类.构建器模式似乎真的在说,"让我们创建一个创建视图的一般过程,然后您可以为您创建的任何视图执行相同的基本过程." 很好,但那不是我在这里做的.
编辑2
我刚刚在维基百科关于依赖注入的文章中找到了一个有趣的例子.
在"Manually Injected依赖"下,它包含以下类:
public class CarFactory {
public static Car buildCar() {
return new Car(new SimpleEngine());
}
}
Run Code Online (Sandbox Code Playgroud)
这几乎是完全相同 …
我正在思考在PHP中实现工厂模式的两种不同方法之一.我不知道这些变种是否有正确的名称,所以现在我打算称它们为内部工厂和外部工厂.
内部工厂:工厂方法在类本身中实现为静态公共方法
<?php
class Foo
{
protected
$loadedProps = false;
public static factory ($id)
{
$class = get_called_class ();
$item = new $class ($id);
if ($item -> loadedProps ())
{
return ($item);
}
}
public function loadedProps ()
{
return ($this -> loadedProps);
}
protected function loadPropsFromDB ($id)
{
// Some SQL logic goes here
}
protected function __construct ($id)
{
$this -> loadedProps = $this -> loadPropsFromDB ($id);
}
}
?>
Run Code Online (Sandbox Code Playgroud)
外部工厂:工厂及其初始化的项目作为单独的实体实施
<?php
class Foo
{
protected
$loadedProps = …Run Code Online (Sandbox Code Playgroud) 我正在使用以下(简化的)工厂设计来创建一些继承层次结构的对象,不应该是任何特殊的:
// class to create
class Class
{
public:
Class(Type type, Foo foo);
};
// Simple creator class.
// Used in practice to do some runtime checks about whether or not construction is allowed.
class Creator
{
public:
Class* create( Type type, Foo foo ) const
{
return new Class( type, foo );
}
};
class Factory
{
public:
Factory
{
// fill object creator map on construction
_map[ "name" ] = new Creator<Class>;
}
Class* create( const std::string& name, …Run Code Online (Sandbox Code Playgroud) 从上周开始,我在Azure数据工厂(v2)中运行的SSIS包逐个失败。他们没有改变。所有软件包都因相同的一系列错误而失败,如下所示。
这些程序包可以在Visual Studio中完美运行,但是当我将它们部署到Data Factory时,我收到了这些消息。
关于如何看待有什么想法?
我试图重新编译脚本组件,以重新部署整个项目。我还尝试将C#代码复制到新组件中,不幸的是导致了同样的问题。
我正在寻找一个我正在研究的项目的设计模式,并想知道我是否可以得到一些输入.
背景
名为Ranker的接口定义如下.
interface Ranker<T> {
public void rank(List<T> item);
}
Run Code Online (Sandbox Code Playgroud)
Ranker的每个实现都可以有多个Rankers作为成员变量,每个成员Rankers都可以有多个Rankers作为其成员变量.你明白了.排名者可以使用其他排名来帮助排名它的项目.
在我的特定情况下,我有27个不同的Rankers,每个Rankers都定义了不同的 dataType.其中一个Rankers将使用其中26个最终能够对这些项目进行排名.
RankerForTypeA
RaknerForTypeB
RankerForTypeC
RankerForTypeD
RankerForTypeE
RankerForTypeF
RankerForTypeG
RankerForTypeH
RankerForTypeI
RankerForTypeJ
RankerForTypeK
...
Run Code Online (Sandbox Code Playgroud)
意思是,RankerTypeA具有RankerTypeB,RankerTypeF和RankerTypeK作为成员并且需要它们以便适当地对A类项进行排序.
问题
每个Rankers的实例化逻辑都不同.我想使用一些帮助我创建这些助手的模块/工厂/等.我最终需要它来创建RankerForTypeA.我有类似的想法.
interface RankerFactory {
Ranker<A> getRankerForA(paramsForA);
Ranker<B> getRankerForB(paramsForB);
Ranker<C> getRankerForC(paramsForC);
...
}
public class DefaultRankerFactory implements RankerFactory {
Ranker<A> getRankerForA(paramsForA) {
getRankerForB(paramsForB)
...
}
Ranker<B> getRankerForB(paramsForB) {
getRankerForC(paramsForC)
...
}
Ranker<C> getRankerForC(paramsForC) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
这有点棘手.我想让人们轻松地说使用他们认为合适的定制助手.回到我之前绘制的层次结构,让我们说对于TypeB,人们想要使用CustomRankerForTypeB而不是 …
我的目标是根据枚举返回一个方法.目前,我已经创建了一个工厂,但它使用的是我不喜欢的开关盒.代码工作正常但我想使用更好的模式并替换当前的开关案例.你如何设计这个没有任何开关案例或如果否则(实例)......
我还试图在枚举中实现一个Stategy模式.但是无法自动装配bean.
请参阅下面的我目前的代码.
public enum Car {
AUDI, FORD;
}
Run Code Online (Sandbox Code Playgroud)
public class SuperCar{
private Car car;
}
Run Code Online (Sandbox Code Playgroud)
public class Audi extends SuperCar{
// some other properties
}
Run Code Online (Sandbox Code Playgroud)
public class Ford extends SuperCar{
// some other properties
}
Run Code Online (Sandbox Code Playgroud)
@Service
public class AudiService{
public void save(Audi audi){
// some code
}
}
Run Code Online (Sandbox Code Playgroud)
@Service
public class FordService{
public void save(Ford ford){
// some code
}
}
Run Code Online (Sandbox Code Playgroud)
@Service
public class CarFactory{
private FordService fordService;
private AudiService audiService;
public CarFactory(FordService fordService, AudiService audiService) {
this.fordService …Run Code Online (Sandbox Code Playgroud)