标签: factory-pattern

如何模拟对象工厂

我使用Factories(请参阅http://www.php.net/manual/en/language.oop5.patterns.php获取模式)来增加代码的可测试性.一个简单的工厂看起来像这样:

class Factory
{
    public function getInstanceFor($type)
    {
        switch ($type) {
            case 'foo':
                return new Foo();
            case 'bar':
                return new Bar();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是使用该工厂的示例类:

class Sample
{
    protected $_factory;

    public function __construct(Factory $factory)
    {
        $this->_factory = $factory;
    }

    public function doSomething()
    {
        $foo = $this->_factory->getInstanceFor('foo');
        $bar = $this->_factory->getInstanceFor('bar');
        /* more stuff done here */
        /* ... */
    }
}
Run Code Online (Sandbox Code Playgroud)

现在进行适当的单元测试,我需要模拟将返回类的存根的对象,这就是我遇到的问题.我认为有可能这样做:

class SampleTest extends PHPUnit_Framework_TestCase
{
    public function testAClassUsingObjectFactory()
    {
        $fooStub = $this->getMock('Foo');
        $barStub = $this->getMock('Bar');

        $factoryMock = …
Run Code Online (Sandbox Code Playgroud)

php phpunit factory-pattern

6
推荐指数
1
解决办法
4532
查看次数

XmlSerializer和工厂创建的元素

我正在尝试序列化/反序列化具有工厂创建的成员的对象.例如,假设有一个类型的成员Foo,它使用FooFactory.CreateFoo(int bar)进行实例化.

我目前的想法是

1.创建自定义XmlReader(例如,从XmlTextReader派生),并将工厂附加到它

2.Implement IXmlSerializable

3.在ReadXml()中,我可以从读者手中抢到工厂.

不确定这是否是最优雅的方式,是否有人做过类似的尝试?

.net c# xml-serialization factory-pattern xmlserializer

6
推荐指数
1
解决办法
1057
查看次数

可扩展程序的良好设计模式

我有一个关于如何为我的程序设计好的问题.我的程序非常简单,但我希望拥有良好的架构,并使我的程序在未来易于扩展.

我的程序需要从外部数据源(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中提供一些示例,那就太棒了.

python architecture design-patterns factory-pattern

6
推荐指数
1
解决办法
1982
查看次数

为什么我需要FactorySupplier?

在我正在研究的项目中(不是我的项目,只是在研究它),有很多这样的结构:

project.priv.logic.MyServiceImpl.java
project.priv.service.MyServiceFactoryImpl.java

project.pub.logic.MyServiceIF.java
project.pub.service.MyServiceFactoryIF.java
project.pub.service.MyServiceFactorySupplier.java
Run Code Online (Sandbox Code Playgroud)

服务的调用方式如下:

MyServiceFactorySupplier.getMyServiceFactory().getMyService()
Run Code Online (Sandbox Code Playgroud)

据我所知,工厂用于隐藏更改MyServiceImpl位置或内容的实现MyServiceImpl.但为什么我的工厂(供应商)还有另一家工厂?我认为我的Factory和FactorySupplier改变的概率大致相等.另外我还没有找到一个案例,其中创建的工厂是动态创建的(我认为这将是抽象工厂模式中的情况)但只返回MyServiceFactoryImpl.getInstance().通常的做法是实施FactorySupplier吗?有什么好处?

java design-patterns factory factory-pattern

6
推荐指数
1
解决办法
96
查看次数

工厂设计模式实施疑点

我正在尝试为学习OOP而创建一个用于Telegram信使的机器人.我真的迷失了如何解决这个问题.我有一个Message实体,包含所有的getter和setter,我认为这是非常直截了当的.我的问题是我想创建两种(或更多)类型的工厂

1)一条简单的消息,您只需要向您发送要发送消息和文本的chat_id的工厂,可能是这样的:

<?php

namespace Telegram\Domain\Factory;

use Telegram\Domain\Entity\Message;

class MessageRaw extends MessageAbstract {
    public function createMessage($chat_id, $text) {
        $message = new Message();
        $message->setChatId($chat_id);
        $message->setText($text);

        return $message;
    }
}
Run Code Online (Sandbox Code Playgroud)

MessageAbstract的位置

<?php

namespace Telegram\Domain\Factory;

abstract class MessageAbstract {
    abstract public function createMessage($chat_id, $text);
}
Run Code Online (Sandbox Code Playgroud)

2)带键盘消息(Telegram使您可以在发送消息时包含自定义键盘).我有问题,键盘是作为一个数组给出的,所以这将是createMessage的另一个参数.

所以我的问题是,我应该总是给出$ keyboard参数,无论是简单的消息还是带键盘的消息?或者这两种类型的消息是否足够不同,以便它们应该从不同的类创建(我想不是)?或者也许我不应该在工厂里做这件事,但是不应该使用制定者和吸气剂?

TLDR:如何以奇特的方式创建具有不同数量的参数的对象,如下所示

$MessageRaw = new MessageRaw($chat_id, $text);
$MessageNumericKeyboard = new MessageNumericKeyboard($chat_id, $text); //numeric keyboard is standard so can be set in the createMessage Function
$MessageCustomKeyboard = new MessageCustomKeyboard($chat_id, $text, ['A', …
Run Code Online (Sandbox Code Playgroud)

php oop factory-pattern

6
推荐指数
1
解决办法
94
查看次数

Unity:使用泛型类型注册和解析类

我正在使用Unity并尝试尽可能遵循SOLID原则.因此,所有实现仅具有接口的依赖性.

我有一个collectionwrapper,看起来像这样:

public interface ICollectionWrapper<TModel>
{
    int TotalCount { get; set; }
    IEnumerable<TModel> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在我想创建ICollectionFactory<T>一个带工厂的实例.这是我到目前为止所得到的:

public interface ICollectionWrapperFactory
{
    ICollectionWrapper<T> CreateCollection<T>();
    ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items);
    ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items, int totalCount);
}

public class CollectionWrapperFactory : ICollectionWrapperFactory
{
    private readonly IUnityContainer _container;

    public CollectionWrapperFactory(IUnityContainer container)
    {
        _container = container;
    }

    public ICollectionWrapper<T> CreateCollection<T>()
    {
        var collectionWrapper = _container.Resolve<ICollectionWrapper<T>>();
        return collectionWrapper;
    }

    public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items)
    {
        throw new System.NotImplementedException();
    }

    public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items, int …
Run Code Online (Sandbox Code Playgroud)

c# inversion-of-control unity-container factory-pattern

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

简单工厂和工厂方法设计模式的区别

我正在新学习设计模式,我试图理解简单工厂和工厂方法模式之间的区别。首先我想澄清一下,我尝试阅读 Stack-overflow 和其他网站上的大量相关文章,但这对我没有帮助。

这是我的问题:让我们考虑一下我的产品层次结构,如下所示: 在此输入图像描述

我写了一个简单的工厂类,如下所示

public class SimpleItemFactory {

    static Item getItem(String type) {
        if(type.equals("Cake")) {
            return new Cake();
        }else if(type.equals("Chocolate")) {
            return new Chocolate();
        }else {
            return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以现在我将所有对象创建都集中在一处,因此如果明天发生任何更改[例如构造函数需要一个参数],我们只需在一处进行更改。但它打破了 OPEN CLOSED 原则,就好像明天我们添加更多项目,我们需要更改 getItem() 方法(如果条件)。所以我们选择工厂方法模式 在此输入图像描述

我们创建Factory类如下所示:

public abstract class ItemFactory {
    abstract Item getItem();
}

class CakeFactory extends ItemFactory {
    @Override
    Item getItem() {
        return new Cake();
    }
}

class ChocolateFactory extends ItemFactory {
    @Override
    Item getItem() {
        return new Chocolate();
    }
}


class Client{
    public static …
Run Code Online (Sandbox Code Playgroud)

java design-patterns software-design factory-pattern

6
推荐指数
1
解决办法
2357
查看次数

根据请求参数在运行时创建 EF Core DbContext

背景

我们正在使用 ASP.Net Core 和 Entity Framework Core 2.2 构建一个 Web 应用程序

我们正在连接到旧数据库。设置是有 16 个数据库,所有数据库都具有完全相同的模式,保存不同的上下文数据。我们无法改变这一点。

我们需要在运行时根据请求参数连接到特定数据库。

想象一下,母公司下的每个业务都有一个数据库。

想象一下,每个数据库都有像 Employee、Client 和 Shift(员工为 Client 工作的轮班)这样的表。

还有一个“中央”数据库,其中包含所有其他数据库中的通用信息,例如设置等。

我们需要在单个列表视图中列出所有企业的所有员工。

我们计划使用中央数据库中的 SQL 视图来检索这些数据,该视图只是在其他每个数据库之间执行 UNION(如果您有关于如何更好地执行此操作的建议,请分享)。

CREATE VIEW dbo.v_all_employees AS 
    SELECT EmployeeId, Fullname, 1 AS BusinessId FROM BusinessA.dbo.Employees
    UNION ALL SELECT EmployeeId, Fullname, 2 AS BusinessId FROM BusinessB.dbo.Employees
    -- etc. etc.
Run Code Online (Sandbox Code Playgroud)

我们有一组模型代表所有数据库中的所有实体(表),因为它们共享完全相同的模式,例如一个 Employee 类,一个 Client 类等。

用例

用户通过此路线转到网页以查看所有企业的员工列表:

http://example.org/employees

然后,用户单击单个员工的“详细信息”链接以查看更多详细信息,将用户带到以下网址:

http://example.org/employees/details?employeeId=123&businessId=xyz

我所坚持的是我们如何在运行时实例化特定于业务的 DbContext,给定 BusinessId。

我想出了三种方法(现在第四种感谢@mylee)来达到预期的结果,并且正在寻找来自社区的反馈。

每个选项都假定每个 DbContext 将实现一个接口,该接口公开所有 DbSets 和 DbContext 方法,然后我们将使用工厂模式来确定要使用哪个 DbContext 实现。

第一个选项: 只需让工厂根据请求参数“bizId”创建正确的 DbContext。 …

c# factory-pattern service-locator .net-core ef-core-2.2

6
推荐指数
2
解决办法
2232
查看次数

为什么 Haskell 不需要工厂模式?模式在 OOP 中解决的需求如何在 Haskell 中解决?

我读过这个关于抽象工厂模式的问题,但它的唯一答案试图在 Haskell 中模拟在 OOP 语言中的情况(尽管前言是沿着你在 Haskell 中不需要它的路线)。

另一方面,我的意图并不是在 Haskell 等函数式语言上强制使用特定于 OOP 的模式。恰恰相反,我想了解Haskell 如何解决 OOP 中通过工厂模式解决的需求

我有一种感觉,即使这些需求一开始在 Haskell 中也没有意义,但我无法更好地表述这个问题。

我对工厂模式结构的理解(基于这个看起来很清楚的视频)是

  1. 有很多不同的产品,都实现了一个通用接口
  2. 有一堆不同的创建者类,都实现了一个通用接口
  • 2 中的每个类都隐藏了一个逻辑来创建 1 中的产品
    • (如果我理解正确的话,对象和创建者之间没有必要存在一对一的映射,因为创建者可以隐藏不同的逻辑,根据用户输入/时间/条件/任何内容对创建哪个特定对象做出不同的选择.)
  • 客户端代码将拥有创建者,每次使用其中一个(创建者,而不是客户端代码)将知道如何创建产品以及哪个特定产品。

所有(或部分)如何适用于 Haskell?

有几个不同的产品类实现一个通用的产品接口是 Haskell 中的一个东西,接口是一个类型class,产品是类型(datas/ newtypes/现有类型)。例如,从链接的视频参考飞船和小行星的例子,我们可以有一个类型class定义Obstacles任何提供sizespeedposition

class Obstacle a where
  size :: a -> Double
  speed :: a -> Int
  position :: …
Run Code Online (Sandbox Code Playgroud)

oop haskell design-patterns functional-programming factory-pattern

6
推荐指数
2
解决办法
243
查看次数

构建用于平滑序列的 Factory/Builder 类模式的 Pythonic 方法

我有许多课程对一系列价格实施平滑技术。

我试图找出在__call__另一个类的函数中实现任何这些平滑类的最佳方法,然后对平滑后的序列执行一些操作:

IE

class NoSmoother:
    def __init__(self, prices):
        self.prices = prices
    
    def __call__(self):
        return self.prices

class MASmoother:
    def __init__(self, prices):
        self.prices = prices
    
    def __call__(self, window):
        return self.prices.rolling(window).mean().to_frame("price")


class ThatDoesSomethingWithSmoothedPrices():
    def __init__(self, prices):
        self.prices = prices

    def __call__(self, smoother=ma_smoother, window=3)
        smoothed_prices = SomeBuilderClassThatCallsTheCorrectSmootherClass()
Run Code Online (Sandbox Code Playgroud)

如您所见,我需要工厂/构建器类来实现NoSmoother,否则,它将调用适当的平滑类。当然,返回的对象可以从简单到复杂各不相同,例如,如果我使用卡尔曼滤波器平滑价格,则该类可以期望更多参数。

目前,我的代码class ThatDoesSomethingWithSmoothedPrices()使用价格系列进行实例化,然后通过传递 **config 进行调用。

期望的输出:

理想情况下,我希望能够从调用函数中调用任何平滑类

class ThatDoesSomethingWithSmoothedPrices()

实施示例:

configs = {'smoother': MASmoother, 'window': 3}

processor = ThatDoesSomethingWithSmoothedPrices(prices)

output = processor(**config)
Run Code Online (Sandbox Code Playgroud)

我的尝试:

class Smoother:
    def __init__(self, prices):
        self.prices = …
Run Code Online (Sandbox Code Playgroud)

python factory-pattern

6
推荐指数
1
解决办法
1471
查看次数