我注意到D中的函数Object.factory(char [] className)但它不能像我希望的那样工作; 这是行不通的 ;)
一个例子:
import std.stdio;
class TestClass
{
override string toString()
{
return typeof(this).stringof; // TestClass
}
};
void main(string[] args)
{
auto i = Object.factory("TestClass");
if (i is null)
{
writeln("Class not found");
}
else
{
writeln("Class string: " ~ i);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这应该导致消息:"类字符串:TestClass",但它说"找不到类".
有谁知道为什么会这样,我怎么能解决它?
或者我是否需要建立自己的班级工厂.例如,通过使用Object[string] classes;带有类实例的静态数组创建一个类.当我想要一个新实例时,我这样做:
auto i = (className in classes);
if (i is null)
{
return null;
}
return i.classinfo.create();
Run Code Online (Sandbox Code Playgroud)
编辑:
我现在就像这样使用它(例如,这是针对Web HMVC模式):
class Page : Controller
{
static this()
{ …Run Code Online (Sandbox Code Playgroud) 我正在努力想出如何在我试图创建的DTO映射器中实现工厂模式.我很确定我需要重新考虑我的设计.这是我正在运行的一个非常小的例子:
public abstract class Person
{
public string Name { get; set; }
public decimal Salary { get; set; }
}
public class Employee : Person
{
public Employee()
{
this.Salary = 20000;
}
}
public class Pilot : Person
{
public string PilotNumber { get; set; }
public Pilot()
{
this.Salary = 50000;
}
}
public static class PersonFactory
{
public static Person CreatePerson(string typeOfPerson)
{
switch (typeOfPerson)
{
case "Employee":
return new Employee();
case "Pilot":
return new Pilot(); …Run Code Online (Sandbox Code Playgroud) 我正在整理这个设计模式的解释和代码示例,试图帮助我周围的人抓住它(同时帮助自己掌握模式).
我正在寻找的是对我的解释和代码示例的意见和批评......谢谢!
什么是工厂模式?工厂模式利用特定的专用"对象创建器对象"来处理 - 对象的创建 - 并且大部分时间 - 实例化,类似于现实世界的工厂.
现实世界的例子
想象一下汽车工厂是各种类型汽车的创造者.那个汽车厂的装配线之一可能有一天会生产一辆卡车,但是在另一天可能会重新生产汽车.假设经销商向其指定的帐户处理部门下达10辆汽车的订单.那个部门然后利用某个工厂并订购了10辆汽车.账户处理人员并不关心自己制造汽车(想象效果不佳)他们只使用最终产品,确保经销商获得他们的车辆.
明年同一辆车的新车型出现,订单开始流入.账户处理人员(仍然不关心汽车的生产)下订单,但现在他们收到的汽车是不同的,装配方法甚至是也许工厂可能会有所不同,但帐户处理人员不必担心这一点.另外一个想法:车辆的工厂装配商可能确切地知道如果某个帐户处理者下订单要采取什么行动(即,帐户处理者X下订单,工厂装配工知道对于帐户处理者X,他们生产10辆Y型车辆).另一个选择可能是帐户处理程序告诉装配工确切地生产什么类型的车辆.
如果账户处理者也处理了车辆的创建(即它们被耦合),则每当车辆以任何方式改变时,每个账户处理者都必须在生产该车辆时进行再培训.这会产生质量问题,因为有比工厂更多的帐户处理程序......会出现错误,费用会更高.
回到OOP
作为应用于软件工程的设计模式的对象工厂在概念上类似于上述示例...工厂生成各种类型的其他对象,您可以利用生成某种对象类型的装配线(对象汇编器),返回到某种方式.汇编程序可以检查请求客户端和句柄,或者客户端可以告诉汇编程序它需要什么对象.现在......你正在一个项目并创建一个对象工厂和各种汇编程序,稍后在项目中,需求稍有变化,现在要求您更改对象内容以及客户端如何处理该对象.由于您使用了工厂模式,这是一个简单的更改,在一个位置,您可以更改或添加工厂生成的对象,
执行此操作的不幸方法是没有工厂方法,实例化每个对象实例并在客户端本身格式化对象内容...假设您在20个客户端中使用了此特定对象.现在你必须去每个客户端,改变每个对象实例和格式......浪费时间......懒惰......第一次以正确的方式做到这一点,这样你就可以节省自己(和其他人)的时间并努力以后.
代码示例(C#)
以下是利用工厂进行食品和各种食品的示例
Factory module
public enum FoodType
{
//enumerated foodtype value, if client wants to specify type of object, coupling still occurs
Hamburger, Pizza, HotDog
}
/// <summary>
/// Object to be overridden (logical)
/// </summary>
public abstract class Food
{
public abstract double FoodPrice { get; }
}
/// <summary>
/// Factory object to be overridden (logical)
/// </summary>
public abstract class FoodFactory …Run Code Online (Sandbox Code Playgroud) 使用php 5.2,我正在尝试使用工厂将服务返回给控制器.我的请求uri的格式为www.mydomain.com/service/method/param1/param2/etc.然后我的控制器将使用uri中发送的令牌调用服务工厂.从我所看到的情况来看,我的工厂有两条主要路线可供选择.
单一方法:
class ServiceFactory {
public static function getInstance($token) {
switch($token) {
case 'location':
return new StaticPageTemplateService('location');
break;
case 'product':
return new DynamicPageTemplateService('product');
break;
case 'user'
return new UserService();
break;
default:
return new StaticPageTemplateService($token);
}
}
}
Run Code Online (Sandbox Code Playgroud)
或多种方法:
class ServiceFactory {
public static function getLocationService() {
return new StaticPageTemplateService('location');
}
public static function getProductService() {
return new DynamicPageTemplateService('product');
}
public static function getUserService() {
return new UserService();
}
public static function getDefaultService($token) {
return new StaticPageTemplateService($token);
}
}
Run Code Online (Sandbox Code Playgroud)
所以,考虑到这一点,我将有一些通用服务,我将传递该令牌(例如,StaticPageTemplateService和DynamicPageTemplateService),它可能会实现另一个工厂方法,就像这样来获取模板,域对象等等.将是特定服务(例如,UserService),它将是该令牌的1:1而不会被重用.因此,对于少量服务而言,这似乎是一种不错的方法(如果不是,请提供建议).但是,随着时间的推移,随着时间的推移和我的网站的增长,我最终会有100种可能性.这似乎不再是一个好方法.我只是开始使用或者是否有其他更适合的设计模式?谢谢. …
哪种方法更好,首先创建子实体,然后传递给聚合根添加它们,或者让聚合根创建它们?例如:
Order.AddOrderLine(new OrderLine(product, quantity, ...));
Run Code Online (Sandbox Code Playgroud)
要么
Order.AddOrderLine(product, quanity, ...);
Run Code Online (Sandbox Code Playgroud)
哪种方法更好?我确信这纯粹是主观的,但我想看看哪个有更多的优点与缺点.
我有一种情况,我想通过工厂对象动态创建一个对象,但需要通过spring上下文创建对象,以允许自动装配依赖项.我知道有很多其他方法可以解决这个问题 - 例如使用服务定位器模式 - 但是如果可能的话我想这样做.
想象一下,我有两个对象:
class OuterObject {
List<InnerObjectInterface> innerObjs;
...
}
class InnerObject implements InnerObjectInterface{
@Autowired
SomeDependency someDependency;
...
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个工厂,它可以完成以下工作:
class OuterObjectFactory {
private innerObject = new InnerObject();
public OuterObject construct(params){
OuterObject o = new OuterObject();
List<InnerObjectInterface> inners = new ArrayList<InnerObjectInterface>();
...
for(some dynamic condition){
...
inners.add(createInnerObject());
...
}
}
public createInnerObject(){
return innerObject;
}
}
Run Code Online (Sandbox Code Playgroud)
我的spring-context.xml看起来像:
<bean id="outerObjectFactory" class="path.OuterObjectFactory" />
<bean id="innerObject" class="path.InnerObject" factory-bean="outerObjectFactory" factory-method="createInnerObject" />
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用.只创建了一个innerObject,我希望它的行为类似于scope ="prototype".如果我将scope ="prototype"添加到bean定义中:
<bean id="innerObject" class="path.InnerObject" factory-bean="outerObjectFactory" factory-method="createInnerObject" scope="prototype"/>
Run Code Online (Sandbox Code Playgroud)
然后它似乎创建了许多innerObjects,但它们没有正确连线.我的同事认为, …
我正在审查代码中有很多这样的语句:
private SomeInterface x = Locator.getInstance(SomeInterface.class)
Run Code Online (Sandbox Code Playgroud)
我希望有类似的东西
private SomeInterface x;
@Inject
public Consumer(SomeInterface x){ // constructor
this.x = x;
}
Run Code Online (Sandbox Code Playgroud)
第一种方法有问题吗?好的,依赖关系并不那么明显,但可以通过配置Locator轻松交换实现.
我已经读过Pimpl有利于二进制兼容性,接口有利于轻松切换实现.我需要结合这两种技术,以便我的应用程序能够通过配置文件切换底层实现.
以下是我当前设计的布局:
Foo类:提供面向客户的API,我很担心ABI兼容性这里
一流的IFoo:接口类(所有的纯虚方法,虚析构函数)
类Vendor1Foo:实现IFoo的,使用的供应商1的库
类Vendor2Foo:实现IFoo的,使用供应商2的图书馆
通过不使用pimpl并严格使用接口,客户端代码可能如下所示:
IFoo* foo = new Vendor1Foo();
Run Code Online (Sandbox Code Playgroud)
问题是我的客户端代码根本无法了解Vendor1或Vendor2,而Foo只是我必须执行此操作的众多类之一.
我正在尝试做的所有概念如下:
class foo
{
private:
QScopedPointer<IFoo> pimpl;
void initImpl(); // Reads from QSettings and initializes pimpl
}
Run Code Online (Sandbox Code Playgroud)
有什么想法可以优雅地解决这个问题吗?
我希望能够提出一些宏或模板类/方法来帮助标准化我如何处理这个并最大限度地减少违反DRY.
模板类可以作为一个辅助性PIMPL像香草萨特的大上广义PIMPL方法对C++ 11:herbsutter.com/gotw/_101,它也必须包含逻辑实例根据配置的正确实施
这里有pimpl成语,桥梁模式和工厂模式的元素.在上面的例子中,initImpl()可以被认为是一个工厂方法.我正在寻找可能会或可能不会使用所有这些模式的解决方案.
我已经看过c ++ pimpl习语:实现取决于模板参数以及SO上的大多数pimpl习语问题.标题似乎很有希望,但它对我的特定用例没有帮助.
我不能使用C++ 11并使用Qt. D-Pointers无法解决我的问题,因为它们绑定到单个实现.
我有一个关于如何为我的程序设计好的问题.我的程序非常简单,但我希望拥有良好的架构,并使我的程序在未来易于扩展.
我的程序需要从外部数据源(XML)获取数据,从这些数据中提取信息,最后需要准备SQL语句以将信息导入数据库.因此,对于现在存在的所有外部数据源,将来会有我的应用程序的简单"流程":获取,提取和加载.
我正在考虑创建名为DataFetcher,DataExtractor和DataLoader的泛型类,然后编写将继承它们的特定类.我想我需要一些工厂设计模式,但是哪个?FactoryMethod还是抽象工厂?
我也想不要使用这样的代码:
if data_source == 'X':
fetcher = XDataFetcher()
elif data_source == 'Y':
fetcher = YDataFetcher()
....
Run Code Online (Sandbox Code Playgroud)
理想情况下(我不确定这是否容易实现),我想编写新的"数据源处理器",在现有代码中添加一行或两行,我的程序将从新数据源加载数据.
如何利用设计模式来实现目标?如果您可以在python中提供一些示例,那就太棒了.
我最近看过工厂设计模式,因为他提到了正常方法中的一个问题
*需要在客户端类中使用new关键字.
因此,通过使用工厂,我们已经实现了这一点(客户端不使用新的).但是从客户端隐藏新东西有什么好处?
一个问题是当客户端使用新的关键字时,他负责删除该内存.如果我们也使用工厂,我们仍然需要这样做,当客户端在最后创建一个对象时,客户端必须删除它(工厂不会删除它们).
我理解,其他优点,如重用现有代码,无需更改客户端代码.但是我对从客户端隐藏新(甚至是类)所取得的成果感到困惑.
提前致谢.
factory-pattern ×10
c# ×2
c++ ×2
java ×2
architecture ×1
d ×1
interface ×1
javabeans ×1
oop ×1
php ×1
pimpl-idiom ×1
python ×1
qt ×1
spring ×1