我正在处理一组消息对象,每个消息对象都有一个与之对应的唯一标识符.每条消息都可以从Map或ByteBuffer构建(消息是二进制的,但我们知道如何与二进制表示进行转换).
构建这些消息的当前实现大致如下:
public static Message fromMap(int uuid, Map<String, Object> fields) {
switch (uuid) {
case FIRST_MESSAGE_ID:
return new FirstMessage(fields);
.
.
.
default:
// Error
return null;
}
}
public static Message fromByteBuffer(int uuid, ByteBuffer buffer) {
switch (uuid) {
case FIRST_MESSAGE_ID:
return new FirstMessage(buffer);
.
.
.
default:
// Error
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,Josh Bloch的Effective Java讨论了第1项:考虑静态工厂方法而不是构造函数,这似乎是这个模式有用的地方(客户端不直接访问Message子类型的构造函数;相反,他们通过这个方法).但我不喜欢这样一个事实,即我们必须记住更新两个switch语句(违反DRY原则).
我很欣赏任何有关实现这一目标的最佳方法的见解; 我们不是缓存对象(每次调用fromMap或fromByteBuffer都会返回一个新对象),这会否定使用像这样的静态工厂方法的一些好处.关于这段代码的一些事情让我觉得错误,所以我很想听听社区关于这是否是构建新对象的有效方法的想法,或者如果不是更好的解决方案.
我想创建一个投票系统,可以对多个域对象进行投票:
所以我想我会Voteable为这些项创建一个接口:
interface Voteable
{
public function vote( User $user, $value );
}
Run Code Online (Sandbox Code Playgroud)
我认为这个vote方法会代理一个存储库方法,例如:
class VotingRepository
{
public function castVote( Voteable $item, User $user, $value )
{
// save the these values, along with the value
$itemId = $item->getId();
$userId = $user->getId();
}
}
Run Code Online (Sandbox Code Playgroud)
目前,存储库将是一个数据库.该数据库将具有每种投票类型的链接表:
因此,这实际上意味着每个域对象都需要另一个表来投票.这对工厂来说是个好人吗?一个VotingRepositoryFactory在这种情况下?换句话说,像:
class VotingRepositoryFactory
{
createVotingRepository( $type )
{
switch( $type )
{
case 'event':
// create a voting repository with EventVote table
return …Run Code Online (Sandbox Code Playgroud) 我有一个类工厂,我正在为c'tor参数使用可变参数模板(下面的代码).但是,当我尝试使用它时,我得到编译错误; 当我最初没有参数编写它时,它工作正常.
这是班级:
template< class Base, typename KeyType, class... Args >
class GenericFactory
{
public:
GenericFactory(const GenericFactory&) = delete;
GenericFactory &operator=(const GenericFactory&) = delete;
typedef Base* (*FactFunType)(Args...);
template <class Derived>
static void Register(const KeyType &key, FactFunType fn)
{
FnList[key] = fn;
}
static Base* Create(const KeyType &key, Args... args)
{
auto iter = FnList.find(key);
if (iter == FnList.end())
return 0;
else
return (iter->second)(args...);
}
static GenericFactory &Instance() { static GenericFactory gf; return gf; }
private:
GenericFactory() = default;
typedef std::unordered_map<KeyType, …Run Code Online (Sandbox Code Playgroud) 前几天我遇到了一些代码,我想知道这是否是最好的方法.我们有一个方法,它根据传入的字符串从一些Web表单数据中获取一个字符串对象.当前,它使用反射来计算要采取的操作,但我想知道switch语句是否会更好.
例:
编辑:我为Lucerno指出的代表添加了第三个选项
public class ObjectManipulator
{
private void DoX(object o) { }
private void DoY(object o) { }
private void DoZ(object o) { }
public void DoAction(string action, object o)
{
switch (action)
{
case "DoX":
DoX(o);
break;
case "DoY":
DoY(o);
break;
case "DoZ":
DoZ(o);
break;
default:
throw new Exception(string.Format(
"Cannot locate action:{0}", action));
}
}
public void DoActionViaReflection(string action, object o)
{
MethodInfo method = typeof(ObjectManipulator).
GetMethod(action, new Type[] { typeof(object) });
if (method == null)
{
throw …Run Code Online (Sandbox Code Playgroud) 我想控制一堆类的创建,这些类都共享一个公共接口,并且在构造中都需要一些逻辑.另外,我不希望除了类工厂之外的任何其他代码能够从这些类创建对象.
我的主要障碍是:
(1)对于能够创建类实例的泛型方法,我需要new()约束,这意味着我必须在类上有一个公共构造函数,这意味着它们可以公开创建.
(2)另一种方法是让类本身具有一个返回类实例的静态方法.但我无法从我的泛型类中调用它,因为我需要处理接口/类型,并且不能通过接口进行静态处理.
这是我目前得到的那种东西,但是它使用了new()约束,它允许公开创建我的类:
internal static class MyClassFactory
{
internal static T Create<T>(string args) where T : IMyType, new()
{
IMyType newThing = new T();
newThing.Initialise(string args);
return (T)newThing;
}
}
public interface IMyType
{
void Initialise(string args);
}
public class ThingA: IMyType
{
public void Initialise(string args)
{
// do something with args
}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助非常感谢:)
我想用SQL.factory()上传文件我只想维护我的代码当前的原始文件名
form = SQLFORM.factory(
Field('file_name', requires=IS_NOT_EMPTY()),
Field('file', 'upload',uploadfolder=upload_folder))
if form.accepts(request.vars, session): #.process().accepted:
response.flash = u'File uploaded'
session.your_name = form.vars.file_name
session.filename = request.vars.file
elif form.errors:
response.flash = 'form has errors'
return dict(form=form)
Run Code Online (Sandbox Code Playgroud)
我猜session.filename = request.vars.file是你设置文件名的地方.为什么我得到自动生成的文件名no_data.smth.23u8o8274823zu4i2.smth
谢谢
我想实现一个用于创建对象的工厂函数.我的对象模板如下所示:
template <typename TA, typename TB>
struct MyImpl : public MyInterface
{
// content
};
Run Code Online (Sandbox Code Playgroud)
我的工厂是这样的:
MyInterface* factory(char ta, char tb)
{
if(ta == 'c' && tb == 'c')
{
return new MyImpl<char, char>();
}
if(ta == 'c' && tb == 's')
{
return new MyImpl<char, short>();
}
if(ta == 's' && tb == 'c')
{
return new MyImpl<short, char>();
}
// and so on ....
}
Run Code Online (Sandbox Code Playgroud)
工厂函数必须接受非静态char数据(ta,tb),因为它无法在编译时确定,我认为这是该工厂的重点.事实上,ta并tb从文件(或网络)阅读.
我想要一个更简单的解决方案来避免烦人的2级开关.
我认为我的问题类似于how-would-one-write-a-meta-if-else-if-in-c,除了我不能使用静态参数. …
假设我有一个名为Guice服务的服务,这里是它的构造函数
public GuiceService(IPayment payment) {
this.payment = payment;
}
Run Code Online (Sandbox Code Playgroud)
我的代码用于使用Enum创建它
IPayment payment = new PaymentFactory.create(PaymentType.Cash);
NaiveService naiveService = new NaiveService(payment);
Run Code Online (Sandbox Code Playgroud)
而且我必须在某个地方进行工厂实施.像这样的东西
public IPayment create(PaymentType paymentType) {
IPayment cardPayment = null;
switch (paymentType) {
case Cash:
cardPayment = new CashPayment(100);
break;
case Card:
cardPayment = new CardPayment(10, 100);
break;
}
return cardPayment;
Run Code Online (Sandbox Code Playgroud)
现在我想使用Guice,我想我想使用FactoryModuleBuilder.
如果我有更多的IPayment实现,那么这样做的方法是什么.
(例如CardPayment,CashPayment)
这适用于一个
install(new FactoryModuleBuilder()
.implement(IPayment.class, CashPayment.class)
.build(IPaymentFactory.class));
Run Code Online (Sandbox Code Playgroud)谢谢
我正在尝试编写一个工厂类,它将具有如下所示的标准接口:
Register<MyBase, MyDerived> g_regDerived("myderived"); // register to factory
Run Code Online (Sandbox Code Playgroud)
现在打电话:
auto* d = Factory<MyBase>::instance().create("myderived", 1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
将调用构造函数MyDerived(1,2,3)并返回指向创建的对象的指针
这听起来像C++ 11应该是可能的,但我无法弄清楚如何做到这一点.
从标准类型擦除工厂开始:
template<typename BaseT>
class Factory {
public:
static Factory* instance() {
static Factory inst;
return &inst;
}
template<typename T>
void reg(const string& name) {
m_stock[name].reset(new Creator<T>);
}
BaseT* create(const string& name) {
return m_stock[name]->create();
}
private:
struct ICreator {
virtual BaseT* create() = 0;
};
template<typename T>
struct Creator : public ICreator {
virtual BaseT* create() {
return new …Run Code Online (Sandbox Code Playgroud) 在JavaScript中有三种创建对象的方法:
简单对象创建:
var ronaldo = {
name: "Ronaldo",
age: "35",
quote: "Hi I am Ronaldo",
salary: function(x){ return x+2500; }
};
Run Code Online (Sandbox Code Playgroud)工厂功能:
function human(x,y,z,i){
return{
name: x,
age: y,
quote: z,
salary: function(i){ return i+2500; }
}
};
var Zini = human('Zenidan','41','I am Zidane',7500);
Run Code Online (Sandbox Code Playgroud)构造函数:
var human = function(x,y,z,i){
this.name = x,
this.age = y,
this.quote = z,
this.salary = function(i){ return i+2500; }
};
var Lampd = new human('Frank Lampard','39','I am Frank J Lampard',5500);
Run Code Online (Sandbox Code Playgroud)有人可以提供简单的插图,说明何时使用这些方法中的哪一种以简单的方式创建对象,这样一个天真的人也可以理解?
我浏览了以下链接,但理解起来有点复杂: …
factory ×10
templates ×3
c# ×2
c++ ×2
c++11 ×2
java ×2
constructor ×1
generics ×1
guice ×1
javascript ×1
oop ×1
php ×1
reflection ×1
sql ×1
static ×1
type-erasure ×1
web2py ×1