标签: factory-pattern

C++ Abstract Factory使用模板

我正在尝试用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)

c++ templates factory-pattern

12
推荐指数
1
解决办法
2万
查看次数

C++中的工厂模式 - 正确执行此操作?

我对"设计模式"相对较新,因为它们在正式意义上被提及.我很久没有成为一名专业人士,所以我对此很陌生.

我们有一个纯虚拟接口基类.这个接口类显然是提供了派生子进程应该做什么功能的定义.软件中的当前用法和情况决定了我们想要使用什么类型的派生子,因此我建议创建一个包装器,它将传达我们想要的派生子类型,并返回指向新派生对象的Base指针.据我所知,这个包装器是一个工厂.

好吧,我的一位同事在Base类中创建了一个静态函数来充当工厂.这有两个原因导致我麻烦.首先,它似乎打破了Base类的接口性质.我认为界面本身需要知道从中衍生出来的孩子,这对我来说是错误的.

其次,当我尝试在两个不同的Qt项目中重用Base类时,会导致更多问题.一个项目是我实现第一个(可能只是这个类的真正实现......虽然我想对其他两个具有几个不同派生类的特性使用相同的方法)派生类,第二个是实际最终将使用我的代码的应用程序.在我编写代码时,我的同事创建了一个派生类,作为真实应用程序的测试人员.这意味着我必须将他的标题和cpp文件添加到我的项目中,这似乎是错的,因为我在实现我的部分时甚至没有使用他的代码用于项目(但是当它完成时他将使用我的).

我是否正确认为工厂真的需要成为Base类的包装而不是作为工厂的Base?

c++ design-patterns interface factory-pattern

12
推荐指数
1
解决办法
8638
查看次数

使用访客模式从平面DTO构建对象图

我写了一个很好的简单的小域模型,其对象图如下所示:

-- 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)

c# visitor dto domain-model factory-pattern

12
推荐指数
2
解决办法
2596
查看次数

满足开放/封闭原则的工厂模式?

我有以下具体Animal产品:DogCat.

我正在使用参数化的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)

c# reflection anti-patterns factory-pattern

12
推荐指数
2
解决办法
4645
查看次数

我们是否需要优先选择构造函数而不是静态工厂方法?如果是的话,何时?

我一直在阅读Joshua Bloch撰写的Effective Java,到目前为止,它确实辜负了它的声誉.第一个项目为构造函数的静态工厂方法提供了令人信服的案例.这么多,我开始质疑好老建设者的有效性:).

本书的优点/缺点总结如下:

好处:

  1. 他们有名字!
  2. 我们有全面的实例控制(单身人士,表现等)
  3. 他们可以返回子类型/接口
  4. 编译器可以提供类型推断

缺点:

  1. 私有类不能被子类化
  2. 它们不像构造函数那样在文档中脱颖而出

第一个缺点实际上可能是A Good Thing(正如书中所提到的).第二个,我认为只是一个小缺点,可以通过即将发布的java版本(javadoc的注释等)轻松解决.

看起来,最终工厂方法几乎具有构造函数的所有优点,许多优点,并没有真正的缺点!

所以,我的问题基本上分为三个部分:

  1. 默认情况下总是在构造函数上使用静态工厂方法是一种好习惯吗?
  2. 使用构造函数是否合理?
  3. 为什么面向对象的语言不能为工厂提供语言级支持?

注意:有两个类似的问题:何时使用构造函数以及何时使用getInstance()方法(静态工厂方法)?对象的创建:构造函数或静态工厂方法.然而,答案要么只是提供上面的列表,要么重申我已经知道的静态工厂方法背后的基本原理.

java constructor design-patterns factory-pattern effective-java

12
推荐指数
1
解决办法
1235
查看次数

DDD存储库和工厂

在我的应用程序中有几层.本主题将重点介绍域和基础结构层.

我在域层中有存储库接口ClientRepositoryInterface.我在Infrastructure层中实现了此接口ClientRepositoryImpl.

但是为了在其存在的循环中间重建对象,我需要工厂(ReconstitutionClientFactory).调用工厂将在存储库中.埃里克埃文斯的书被描述为正常的做法.

但是应该找到这个工厂(ReconstitutionClientFactory)?在域或基础架构层?

我想在Domain ...但是!但是下层会直接调用更高层!这是错的,但怎么做对了?

domain-driven-design ddd-repositories repository-pattern factory-pattern

12
推荐指数
2
解决办法
7773
查看次数

在对象实例上调用new有什么好处?

我正在读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对象实例有什么好处?我认为这是它的用途,对吧?我的猜测是,如果有人想编写这样的构造函数,他将不得不添加一些代码,将第一个对象的属性复制到即将创建的对象.

oop perl constructor factory-pattern

11
推荐指数
3
解决办法
281
查看次数

使用C++模板在编译时在AbstractFactory中动态注册构造函数方法

当实现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)

c++ templates factory-pattern

11
推荐指数
2
解决办法
5743
查看次数

使用工厂模式保存数据?

我已经越来越熟悉工厂模式(以及战略模式)以及模式可以带来的巨大好处.但是,我一直在努力应对以下情况:

以前,我会做类似以下的事情,其中​​有一个经理类可以构建和保存汽车.这里没有依赖注入,并且是一个糟糕的实现,特别是在尝试单元测试时.

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

11
推荐指数
1
解决办法
3302
查看次数

Symfony:控制器工厂

我正在制作一个自定义用户包,允许定义多个用户类型,使用自己的存储库,管理器,提供商等.因此,我决定创建一个控制器工厂,而不是创建有限的控制器组,这将产生控制器基于定义的用户类型和配置.但这提出了一个重要的问题 - 这些工厂应该在哪里运营?

现在,请注意,在工厂中创建控制器是不够的,我们还必须在某处设置所有路径.

问题是 - 什么是最好的架构呢?

在选择我将放置代码的图层时,我正在考虑,其中包括:

  1. 在Extension的load方法中加载工厂定义,并在那里创建所有控制器.问题:路由器在那里不可用,因为它发生在容器构建之前,所以我无法在同一个地方创建路由.

  2. Sooo ...也许在编译器传递?但编译器传递无法访问配置...我的意思是......实际上它已经,如果我只是加载配置并手动处理它,但我仍然不确定这是否是一个好地方,但我我现在正倾向于这个解决方案.

在创建路线时:

  1. 我应该在控制器工厂中放置路由创建逻辑吗?但我正在创建控制器作为服务,而工厂无法访问创建的控制器的serviceId,并且创建路由需要serviceId,所以不应该.

  2. 在控制器本身?我的意思是,这就是注释路由的工作方式,因此它可能是可行的.控制器必须ControllerInterface使用该方法实现类似我自己的东西getRoutes,并且外部服务/编译器传递需要首先创建控制器作为服务,然后从所述控制器获取路由,修改它们,以便它们引用该控制器的serviceId并将它们添加到路由器......无论这看起来多么混乱.

  3. 还有其他选择吗?

关于这种特殊模式的信息非常缺乏 - 控制器工厂:).

controller routes factory-pattern symfony

11
推荐指数
1
解决办法
824
查看次数