我正在寻找一种更好的方法来调用基于Python中的变量的函数与使用if/else语句(如下所示).每个状态代码都有相应的功能
if status == 'CONNECT':
return connect(*args, **kwargs)
elif status == 'RAWFEED':
return rawfeed(*args, **kwargs)
elif status == 'RAWCONFIG':
return rawconfig(*args, **kwargs)
elif status == 'TESTFEED':
return testfeed(*args, **kwargs)
...
Run Code Online (Sandbox Code Playgroud)
我认为这将需要某种工厂功能,但不确定语法
我正在测试工厂类.其中一个方法必须将数据加载到另一个方法将实例化的对象的数组中.
该方法包含SQL查询,该查询包含必须测试的严重条件.(在这种情况下,只询问"已发布"的记录.例如:WHERE published = 1).SQL Query中的这种区别是使该方法与另一种方法不同的唯一细节,我想测试查询执行行为.
现在,我无法模拟我的PDO对象并要求它返回一个固定的结果,因为我不会测试mySQL执行查询.这将是一个无用的测试.
这让我觉得我需要在其中设置一个带有固定测试数据的静态数据库.我是对的还是我错过了什么?
我应该将需要"测试数据库"的测试与自主测试分开吗?
我已经看到了使用静态方法的Factory实现.像这样的东西:
public class MyFactory {
public static Product1 createProduct1() {}
public static Product2 createProduct2() {}
}
p1 = MyFactory.createProduct1();
p2 = MyFactory.createProduct2();
Run Code Online (Sandbox Code Playgroud)
我不确定我是否可以将其称为抽象工厂,但这不是问题.我对抽象工厂的理解是,它为我们提供了轻松更改产品系列的灵活性.
Factory factory = new MyFactory(); // might be a global or Singleton
p1 = factory.createProduct1();
p2 = factory.createProduct2();
Run Code Online (Sandbox Code Playgroud)
如果我想改变MyFactory,YourFactory那么只需要改变一行.我也可以在运行时更改它.但它们是否可以作为静态方法实现?我需要将所有调用更改为静态工厂.如果我们想在运行时决定,还需要在每个地方使用if-else检查.
p1 = YourFactory.createProduct1();
p2 = YourFactory.createProduct2();
Run Code Online (Sandbox Code Playgroud)
那么使用静态方法实现工厂的好处是什么?我们不是失去了主要的灵活性吗?我错过了什么?
请注意,不承担任何特定语言.任何帮助表示赞赏.
static design-patterns factory factory-pattern abstract-factory
我正在创建一些类来处理各种类型的文件共享(nfs,afp,s3,本地磁盘)等文件名.我得到一个用户输入一个标识数据源(即"nfs://192.168.1.3"或"s3://mybucket/data")等的字符串.
我从具有公共代码的基类继承特定文件系统.我困惑的地方是对象创建.我所拥有的是以下内容:
import os
class FileSystem(object):
class NoAccess(Exception):
pass
def __new__(cls,path):
if cls is FileSystem:
if path.upper().startswith('NFS://'):
return super(FileSystem,cls).__new__(Nfs)
else:
return super(FileSystem,cls).__new__(LocalDrive)
else:
return super(FileSystem,cls).__new__(cls,path)
def count_files(self):
raise NotImplementedError
class Nfs(FileSystem):
def __init__ (self,path):
pass
def count_files(self):
pass
class LocalDrive(FileSystem):
def __init__(self,path):
if not os.access(path, os.R_OK):
raise FileSystem.NoAccess('Cannot read directory')
self.path = path
def count_files(self):
return len([x for x in os.listdir(self.path) if os.path.isfile(os.path.join(self.path, x))])
data1 = FileSystem('nfs://192.168.1.18')
data2 = FileSystem('/var/log')
print type(data1)
print type(data2)
print data2.count_files() …Run Code Online (Sandbox Code Playgroud) 我的LayoutInflater.Factory(下面的代码示例)调用onCreateView并使用'com.android.support:support-v4:22.0.0'正常工作的主要问题.但是onCreateView当我转到'com.android.support:support-v4:22.1.0'或更高版本时,不会调用它.我不明白为什么?
//From many fragments i Call hintManager.inflate
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
layout = hintManager.inflate(inflater, R.layout.generate_code);
...
//here is HintManager method called from various fragments.
public View inflate(LayoutInflater inflater, int layoutResourceId) {
AttributeParser attributeParser = new AttributeParser();
LayoutInflater layoutInflater = attributeParser.getLayoutInflater(inflater);
final View v = layoutInflater.inflate(layoutResourceId, null);
//here AttributeParserFactory#onCreateView should be called, but it fails with 22.1+ support lib, but works with 22.0
attributeParser.setViewAttribute(v);
return v;
}
...
//example …Run Code Online (Sandbox Code Playgroud) 为了避免new在我的JavaScript代码中使用,我编写工厂来创建对象.
我尝试了很多组合,给我最满意的结果如下:
/**
* Document module
* @module app/document
*/
(function () {
'use strict';
/**
* Factory that creates a document object.
* @alias module:app/document.factory
* @return {document}
*/
function document() {
/**
* Get document id
* @method id
* @return {String}
*/
var id = function id() {...},
api = {
id: id
};
return api;
}
/**
* This module exports the {@link module:app/document.factory|factory} function.
*/
module.exports = document;
}());
Run Code Online (Sandbox Code Playgroud)
这些注释的问题是没有document定义对象.因此,我无法在另一个对象中引用此对象,并且在扩展此对象时无法继承其文档.
记录此类对象的适当方法是什么? …
正确实现依赖注入的一种方法是将对象创建与业务逻辑分开.通常,这涉及使用Factory进行对象创建.
到目前为止,我从未认真考虑过使用工厂,所以如果这个问题看起来有点简单,我会道歉:
在我遇到的工厂模式的所有示例中,我总是看到没有参数化的非常简单的示例.例如,这是一个工厂从Misko Hevery偷来的优秀如何思考"新"操作员文章.
class ApplicationBuilder {
House build() {
return new House(new Kitchen(
new Sink(),
new Dishwasher(),
new Refrigerator())
);
}
}
但是,如果我希望我建造的每个房子都有名字,会发生什么?如果我按如下方式重新编写此代码,我还在使用工厂模式吗?
class ApplicationBuilder {
House build( const std::string & house_name) {
return new House( house_name,
new Kitchen(new Sink(),
new Dishwasher(),
new Refrigerator())
);
}
}
请注意我的Factory方法调用已更改为:
ApplicationBuilder builder; House * my_house = builder.build();
对此:
ApplicationBuilder builder;
House * my_house = builder.build("Michaels-Treehouse");
顺便说一句:我认为将对象实例化与业务逻辑分离的概念很棒,我只想弄清楚如何将它应用于我自己的情况.令我困惑的是,我看到的Factory模式的所有示例都没有将任何参数传递给build()函数.
要清楚:在我需要实例化它之前,我不知道房子的名称.
在使用工厂模式时,工厂应该包含验证逻辑还是应该留给调用类来处理传递上下文数据之前的验证?
我有一个简单的工厂方法,但它依赖于传递给它的配置树来决定要实例化的对象.
可能存在这样的情况:配置xml可能形成良好,但不是工厂期望的正确格式,我不知道应该在哪里验证.
我知道有很多关于不同工厂模式的差异的问题,但答案是如此不同和令人困惑.我读过的书籍使用不清楚和(简化)简化的例子.即使在阅读维基百科的解释之后,我也有很多问题,以及关于它们的大量在线解释,包括所有这些网站上的解释.我正在阅读的这本书是Head First Design Patterns.
在Simple Factory中,客户端使用单独的类(Creator)和工厂方法(可以是静态的)来返回Products.
在工厂方法模式中,创建者和客户端是相同的东西,他们在同一个类中使用抽象方法来创建新的产品,它们在同一个类中运行.当然,造物主(或客户)是抽象的,因此关于制作混凝土产品的决定被推迟到子类.
我的理解是否正确(例如,FMP中的客户端和创建者是同一件事,我从未在FMP图中看到客户端)?
在Factory Method Pattern中,它表明create方法不能在Creator之外重用,所以它只能在创建一个新的Creator时重用?
在哪种情况下我可以选择一个而不是另一个?
(PS请不要将此标记为重复,我希望在此网站上明确这一点)
基本上我希望通过工厂方法创建所有子类型(我有一个高大的域层次结构,有200多个类).
因为new,这不是问题,因为这可以在A(new私有)中被覆盖.
class A{
protected:
A();
public:
template<class T, typename... ARGUMENTS>
static T* create(ARGUMENTS&&... arguments);
};
class B : public A {
public:
B();
};
void test() {
B b;//compile error wanted here - but as a consequence of inheriting A
}
Run Code Online (Sandbox Code Playgroud)
这里A是"库/框架"类.而B是"用户创建的类".在B上要求typedef或类似可能没问题.
更新:我在A上添加了'create'函数,我打算用它来创建对象.