我使用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) 我正在尝试序列化/反序列化具有工厂创建的成员的对象.例如,假设有一个类型的成员Foo,它使用FooFactory.CreateFoo(int bar)进行实例化.
我目前的想法是
1.创建自定义XmlReader(例如,从XmlTextReader派生),并将工厂附加到它
2.Implement IXmlSerializable
3.在ReadXml()中,我可以从读者手中抢到工厂.
不确定这是否是最优雅的方式,是否有人做过类似的尝试?
我有一个关于如何为我的程序设计好的问题.我的程序非常简单,但我希望拥有良好的架构,并使我的程序在未来易于扩展.
我的程序需要从外部数据源(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中提供一些示例,那就太棒了.
在我正在研究的项目中(不是我的项目,只是在研究它),有很多这样的结构:
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吗?有什么好处?
我正在尝试为学习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) 我正在使用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) 我正在新学习设计模式,我试图理解简单工厂和工厂方法模式之间的区别。首先我想澄清一下,我尝试阅读 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) 背景
我们正在使用 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/details?employeeId=123&businessId=xyz
我所坚持的是我们如何在运行时实例化特定于业务的 DbContext,给定 BusinessId。
我想出了三种方法(现在第四种感谢@mylee)来达到预期的结果,并且正在寻找来自社区的反馈。
每个选项都假定每个 DbContext 将实现一个接口,该接口公开所有 DbSets 和 DbContext 方法,然后我们将使用工厂模式来确定要使用哪个 DbContext 实现。
第一个选项: 只需让工厂根据请求参数“bizId”创建正确的 DbContext。 …
我读过这个关于抽象工厂模式的问题,但它的唯一答案试图在 Haskell 中模拟在 OOP 语言中的情况(尽管前言是沿着你在 Haskell 中不需要它的路线)。
另一方面,我的意图并不是在 Haskell 等函数式语言上强制使用特定于 OOP 的模式。恰恰相反,我想了解Haskell 如何解决 OOP 中通过工厂模式解决的需求。
我有一种感觉,即使这些需求一开始在 Haskell 中也没有意义,但我无法更好地表述这个问题。
所有(或部分)如何适用于 Haskell?
有几个不同的产品类实现一个通用的产品接口是 Haskell 中的一个东西,接口是一个类型class,产品是类型(datas/ newtypes/现有类型)。例如,从链接的视频参考飞船和小行星的例子,我们可以有一个类型class定义Obstacles任何提供size,speed和position,
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
我有许多课程对一系列价格实施平滑技术。
我试图找出在__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) factory-pattern ×10
c# ×3
java ×2
oop ×2
php ×2
python ×2
.net ×1
.net-core ×1
architecture ×1
ef-core-2.2 ×1
factory ×1
haskell ×1
phpunit ×1