我正在尝试用C++为多个抽象工厂创建一个抽象工厂模板,并想出了这个.
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <map>
#include <stdio.h>
class Base
{
public:
virtual ~Base() {}
virtual bool Get() = 0;
};
class DerivedA : public Base
{
public:
bool Get()
{
return true;
}
};
class DerivedB : public Base
{
public:
bool Get()
{
return false;
}
};
template <class T>
class Creator
{
public:
virtual ~Creator(){}
virtual T* Create() = 0;
};
template <class T>
class DerivedCreator : public Creator<T>
{
public:
T* Create()
{
return new …Run Code Online (Sandbox Code Playgroud) 我对"设计模式"相对较新,因为它们在正式意义上被提及.我很久没有成为一名专业人士,所以我对此很陌生.
我们有一个纯虚拟接口基类.这个接口类显然是提供了派生子进程应该做什么功能的定义.软件中的当前用法和情况决定了我们想要使用什么类型的派生子,因此我建议创建一个包装器,它将传达我们想要的派生子类型,并返回指向新派生对象的Base指针.据我所知,这个包装器是一个工厂.
好吧,我的一位同事在Base类中创建了一个静态函数来充当工厂.这有两个原因导致我麻烦.首先,它似乎打破了Base类的接口性质.我认为界面本身需要知道从中衍生出来的孩子,这对我来说是错误的.
其次,当我尝试在两个不同的Qt项目中重用Base类时,会导致更多问题.一个项目是我实现第一个(可能只是这个类的真正实现......虽然我想对其他两个具有几个不同派生类的特性使用相同的方法)派生类,第二个是实际最终将使用我的代码的应用程序.在我编写代码时,我的同事创建了一个派生类,作为真实应用程序的测试人员.这意味着我必须将他的标题和cpp文件添加到我的项目中,这似乎是错的,因为我在实现我的部分时甚至没有使用他的代码用于项目(但是当它完成时他将使用我的).
我是否正确认为工厂真的需要成为Base类的包装而不是作为工厂的Base?
我写了一个很好的简单的小域模型,其对象图如下所示:
-- Customer
-- Name : Name
-- Account : CustomerAccount
-- HomeAddress : PostalAddress
-- InvoiceAddress : PostalAddress
-- HomePhoneNumber : TelephoneNumber
-- WorkPhoneNumber : TelephoneNumber
-- MobilePhoneNumber : TelephoneNumber
-- EmailAddress : EmailAddress
Run Code Online (Sandbox Code Playgroud)
这个结构与我必须使用的遗留数据库完全不一致,所以我定义了一个平面DTO,其中包含客户图中每个元素的数据 - 我在数据库中有视图和存储过程,这些允许我在这两个方向上使用这种扁平结构与数据进行交互,这一切都很好,花花公子:)
将域模型展平为DTO以进行插入/更新是直截了当的,但我遇到的问题是使用DTO并从中创建域模型...我的第一个想法是实现访问每个元素的访问者客户图,并根据需要从DTO注入值,有点像这样:
class CustomerVisitor
{
public CustomerVisitor(CustomerDTO data) {...}
private CustomerDTO Data;
public void VisitCustomer(Customer customer)
{
customer.SomeValue = this.Data.SomeValue;
}
public void VisitName(Name name)
{
name.Title = this.Data.NameTitle;
name.FirstName = this.Data.NameFirstName;
name.LastName = this.Data.NameLastName;
}
// ... and so on …Run Code Online (Sandbox Code Playgroud) 我有以下具体Animal产品:Dog和Cat.
我正在使用参数化的Factory方法来创建所述产品.根据AnimalInfo传递给Factory方法的参数,将创建具体产品.映射逻辑放在Factory方法中.
这是我的代码:
public abstract class AnimalInfo
{
public abstract String Sound { get; }
}
public class DogInfo : AnimalInfo
{
public override string Sound
{
get { return "Bark"; }
}
}
public class CatInfo : AnimalInfo
{
public override string Sound
{
get { return "Meow"; }
}
}
public abstract class Animal
{
public abstract void Talk();
}
public class Dog : Animal
{
private readonly …Run Code Online (Sandbox Code Playgroud) 我一直在阅读Joshua Bloch撰写的Effective Java,到目前为止,它确实辜负了它的声誉.第一个项目为构造函数的静态工厂方法提供了令人信服的案例.这么多,我开始质疑好老建设者的有效性:).
本书的优点/缺点总结如下:
好处:
- 他们有名字!
- 我们有全面的实例控制(单身人士,表现等)
- 他们可以返回子类型/接口
- 编译器可以提供类型推断
缺点:
- 私有类不能被子类化
- 它们不像构造函数那样在文档中脱颖而出
第一个缺点实际上可能是A Good Thing(正如书中所提到的).第二个,我认为只是一个小缺点,可以通过即将发布的java版本(javadoc的注释等)轻松解决.
看起来,最终工厂方法几乎具有构造函数的所有优点,许多优点,并没有真正的缺点!
所以,我的问题基本上分为三个部分:
注意:有两个类似的问题:何时使用构造函数以及何时使用getInstance()方法(静态工厂方法)?和对象的创建:构造函数或静态工厂方法.然而,答案要么只是提供上面的列表,要么重申我已经知道的静态工厂方法背后的基本原理.
java constructor design-patterns factory-pattern effective-java
在我的应用程序中有几层.本主题将重点介绍域和基础结构层.
我在域层中有存储库接口ClientRepositoryInterface.我在Infrastructure层中实现了此接口ClientRepositoryImpl.
但是为了在其存在的循环中间重建对象,我需要工厂(ReconstitutionClientFactory).调用工厂将在存储库中.埃里克埃文斯的书被描述为正常的做法.
但是应该找到这个工厂(ReconstitutionClientFactory)?在域或基础架构层?
我想在Domain ...但是!但是下层会直接调用更高层!这是错的,但怎么做对了?
domain-driven-design ddd-repositories repository-pattern factory-pattern
我正在读Programming Perl,我找到了这段代码:
sub new {
my $invocant = shift;
my $class = ref($invocant) || $invocant;
my $self = {
color => "bay",
legs => 4,
owner => undef,
@_, # Override previous attributes
};
return bless $self, $class;
}
Run Code Online (Sandbox Code Playgroud)
对于像这样的构造函数,调用new对象实例有什么好处?我认为这是它的用途,对吧?我的猜测是,如果有人想编写这样的构造函数,他将不得不添加一些代码,将第一个对象的属性复制到即将创建的对象.
当实现MessageFactory类来实例化Message对象时,我使用了类似的东西:
class MessageFactory
{
public:
static Message *create(int type)
{
switch(type) {
case PING_MSG:
return new PingMessage();
case PONG_MSG:
return new PongMessage();
....
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常但每次添加新消息时我都要添加一个新的XXX_MSG并修改switch语句.
经过一些研究后,我发现了一种在编译时动态更新MessageFactory的方法,因此我可以添加任意数量的消息,而无需修改MessageFactory本身.这样可以更简洁,更容易维护代码,因为我不需要修改三个不同的位置来添加/删除消息类:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
class Message
{
protected:
inline Message() {};
public:
inline virtual ~Message() { }
inline int getMessageType() const { return m_type; }
virtual void say() = 0;
protected:
uint16_t m_type;
};
template<int TYPE, typename IMPL>
class MessageTmpl: public Message
{
enum { _MESSAGE_ID = TYPE }; …Run Code Online (Sandbox Code Playgroud) 我已经越来越熟悉工厂模式(以及战略模式)以及模式可以带来的巨大好处.但是,我一直在努力应对以下情况:
以前,我会做类似以下的事情,其中有一个经理类可以构建和保存汽车.这里没有依赖注入,并且是一个糟糕的实现,特别是在尝试单元测试时.
public class CarManager
{
public static Car GetCarFromDatabase(int carId) { return new Car(); }
public static void SaveCar(Car car) { }
}
Run Code Online (Sandbox Code Playgroud)
我现在看到我可以Factories为我制造不同的车,无论是来自数据库,还是来自哪里!这很棒!所以,这是我的问题:
Q1:我的理解是,Factories只应构建对象,这是正确的吗?如果是这样,我的第二个问题呢?
Q2:如果我按照工厂模式构建我的对象,我应该如何保存我的对象?这有不同的模式,还是我不完全理解工厂模式?
c# design-patterns dependency-injection strategy-pattern factory-pattern
我正在制作一个自定义用户包,允许定义多个用户类型,使用自己的存储库,管理器,提供商等.因此,我决定创建一个控制器工厂,而不是创建有限的控制器组,这将产生控制器基于定义的用户类型和配置.但这提出了一个重要的问题 - 这些工厂应该在哪里运营?
现在,请注意,在工厂中创建控制器是不够的,我们还必须在某处设置所有路径.
问题是 - 什么是最好的架构呢?
在选择我将放置代码的图层时,我正在考虑,其中包括:
在Extension的load方法中加载工厂定义,并在那里创建所有控制器.问题:路由器在那里不可用,因为它发生在容器构建之前,所以我无法在同一个地方创建路由.
Sooo ...也许在编译器传递?但编译器传递无法访问配置...我的意思是......实际上它已经,如果我只是加载配置并手动处理它,但我仍然不确定这是否是一个好地方,但我我现在正倾向于这个解决方案.
在创建路线时:
我应该在控制器工厂中放置路由创建逻辑吗?但我正在创建控制器作为服务,而工厂无法访问创建的控制器的serviceId,并且创建路由需要serviceId,所以不应该.
在控制器本身?我的意思是,这就是注释路由的工作方式,因此它可能是可行的.控制器必须ControllerInterface使用该方法实现类似我自己的东西getRoutes,并且外部服务/编译器传递需要首先创建控制器作为服务,然后从所述控制器获取路由,修改它们,以便它们引用该控制器的serviceId并将它们添加到路由器......无论这看起来多么混乱.
还有其他选择吗?
关于这种特殊模式的信息非常缺乏 - 控制器工厂:).
factory-pattern ×10
c# ×3
c++ ×3
constructor ×2
templates ×2
controller ×1
domain-model ×1
dto ×1
interface ×1
java ×1
oop ×1
perl ×1
reflection ×1
routes ×1
symfony ×1
visitor ×1