- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我倾向于只使用我已经在应用程序代码的各个地方使用的映射器模式。但我认为在这种特殊情况下它实际上可能不是最合适的:
任务:
最佳答案
实现目标
我们将编写一个自动翻译器。 假设我们有一个代表我们的有线格式的对象:
JsonObject wire_data;
JsonObject
有一个
add_field
成员函数:
wire_data.add_field("name", "value");
JsonObject
的实际接口(interface)实际上无关紧要,本文的其余部分不依赖于它以任何特定方式实现。
template<class Car>
void add_car_info(JsonObject& object, Car car) {
// Stuff goes here
}
Car
有一个字段,例如Car::getMake()
, 我们的函数 add_car_info
应该自动将该字段添加到 json 对象 Car
没有字段,我们的函数不需要做任何事情。 Car
派生自任何事物,或成为任何事物的基类 struct Car1
{
std::string getMake() { return "Toyota"; }
std::string getModel() { return "Prius"; }
int getYear() { return 2013; }
};
struct Car2
{
std::string getMake() { return "Toyota"; }
int getYear() { return 2017; };
};
struct Car3
{
std::string getModel() { return "Prius"; }
int getYear() { return 2017; }
};
struct Car4
{
long long getSerial() { return 2039809809820390; }
};
JsonObject wire_data;
Car1 car1;
add_field(wire_data, car1);
Car1 car1;
wire_data.add_field("car make", car1.getMake());
wire_data.add_field("car model", car1.getModel());
wire_data.add_field("year", car1.getYear());
Car2 car2;
add_field(wire_data, car2);
Car2 car2;
wire_data.add_field("car make", car2.getMake());
wire_data.add_field("year", car2.getYear());
add_car_info
以一种通用的方式?
C++
没有动态反射,但我们可以使用静态反射来实现(而且效率也会更高)!
template<class Car>
void add_car_info(JsonObject& wire_object, Car car) {
auto translator = getCarTranslator();
// This lambda adds the inputs to wire_object
auto add_field = [&](std::string const& name, auto&& value) {
wire_object.add_field(name, value);
};
// Add the car's fields.
translator.translate(add_field, car);
}
translator
对象只是踢,可以在路上,但是有一个
translator
对象将使书写变得容易
translator
用于汽车以外的东西。
getCarTranslator
开始.对于汽车,我们可能会关心四件事:制造型号、年份和序列号。
auto getCarTranslator() {
return makeTranslator(READ_FIELD("car make", getMake()),
READ_FIELD("car model", getModel()),
READ_FIELD("year", getYear()),
READ_FIELD("serial", getSerial()));
}
// This class is used to tell our overload set we want the name of the field
class read_name_t
{
};
#define READ_FIELD(name, field) \
overload_set( \
[](auto&& obj) -> decltype(obj.field) { return obj.field; }, \
[](read_name_t) -> decltype(auto) { return name; })
template <class Base1, class Base2>
struct OverloadSet
: public Base1
, public Base2
{
OverloadSet(Base1 const& b1, Base2 const& b2) : Base1(b1), Base2(b2) {}
OverloadSet(Base1&& b1, Base2&& b2)
: Base1(std::move(b1)), Base2(std::move(b2))
{
}
using Base1::operator();
using Base2::operator();
};
template <class F1, class F2>
auto overload_set(F1&& func1, F2&& func2)
-> OverloadSet<typename std::decay<F1>::type, typename std::decay<F2>::type>
{
return {std::forward<F1>(func1), std::forward<F2>(func2)};
}
template <class Reader>
class OptionalReader
{
public:
Reader read;
template <class Consumer, class Object>
void maybeConsume(Consumer&& consume, Object&& obj) const
{
// The 0 is used to dispatch it so it considers both overloads
maybeConsume(consume, obj, 0);
}
private:
// This is used to disable maybeConsume if we can't read it
template <class...>
using ignore_t = void;
// This one gets called if we can read the object
template <class Consumer, class Object>
auto maybeConsume(Consumer& consume, Object& obj, int) const
-> ignore_t<decltype(consume(read(read_name_t()), read(obj)))>
{
consume(read(read_name_t()), read(obj));
}
// This one gets called if we can't read it
template <class Consumer, class Object>
auto maybeConsume(Consumer&, Object&, long) const -> void
{
}
};
template <class... OptionalApplier>
class Translator : public OptionalApplier...
{
public:
// Constructors
Translator(OptionalApplier const&... appliers)
: OptionalApplier(appliers)... {}
Translator(OptionalApplier&&... appliers)
: OptionalApplier(appliers)... {}
// translate fuction
template <class Consumer, class Object>
void translate(Consumer&& consume, Object&& o) const
{
// Apply each optional applier in turn
char _[] = {((void)OptionalApplier::maybeConsume(consume, o), '\0')...};
(void)_;
}
};
makeTranslator
现在功能真的很简单。我们只是带了一堆读者,然后用它们来制作
optionalReader
s。
template <class... Reader>
auto makeTranslator(Reader const&... readers)
-> Translator<OptionalReader<Reader>...>
{
return {OptionalReader<Reader>{readers}...};
}
auto getImagesTranslator() {
// Width and height might be implemented as `getWidth` and `getHeight`,
// Or as `getRows` and `getCols`
return makeTranslator(READ_FIELD("width", getWidth()),
READ_FIELD("height", getHeight()),
READ_FIELD("width", getCols()),
READ_FIELD("height", getRows()),
READ_FIELD("location", getLocation()),
READ_FIELD("pixel format", getPixelFormat()),
READ_FIELD("size", size()),
READ_FIELD("aspect ratio", getAspectRatio()),
READ_FIELD("pixel data", getPixelData()),
READ_FIELD("file format", getFileFormat()));
}
关于java - 模式 : Create and translate between data objects and wire formats,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55367816/
我正在研究 netwire 包,试图了解 FRP,我有一个简单的问题。 从以下简单的线路开始,我能够每 5 秒(大约)发出一个事件 myWire :: (Monad m, HasTime t s) =
我正在尝试“正确”地在 netwire 5 中实现一组动态电线。我已阅读wires of wires的答案问题,而且我不太喜欢示例中的代码如何依赖于转换为行为的 Event 在恰好一次执行上显示非空>
本文整理了Java中org.fabric3.spi.wire.Wire.getInvocationChains()方法的一些代码示例,展示了Wire.getInvocationChains()的具体用
本文整理了Java中org.apache.commons.httpclient.Wire.wire()方法的一些代码示例,展示了Wire.wire()的具体用法。这些代码示例主要来源于Github/S
我用 Google 搜索了很多次,看来我不是唯一一个在真正理解 Wire.write() 和 Wire.read() 方面遇到问题的人。作为新手,我几乎从不使用别人已经编写的库,我尝试为模块创建我的类
我正在尝试启动我的一个 bundle ,但一启动它,我就收到以下异常。我不确定是什么问题。 org.osgi.framework.BundleException: Unresolved constra
我一直在尝试关注“使用 OSGi 构建模块化云应用程序”。在“创建第一个 OSGi 应用程序”一书的第 3 章中,作者描述了如何使用 bndtools 在 eclipse 中创建一个带有服务的简单 O
我正在编译一个使用org.json的Java插件。在添加此插件之前,该插件已能够编译并正确运行。我在stackoverflow上看到了类似的问题,但是没有一个问题使用gradle解决。 在我的类顶部,
我是 Java/Karaf 4.0.9/Maven/Pom/Camel 的新手,我无法解决问题 pom.xml文件中的Json部分,这里我改了很多Json version , 但没有用。
我正在使用最新版本的 atlassian SDK 为 JIRA 开发插件。我已经编写了大部分代码,并向我的项目的 pom.xml 文件添加了一些我需要的依赖项(见下文)。 不幸的是,在运行 atlas
我下载了 Camel CXF 示例“camel-example-cxf-osgi ”,并且能够毫无问题地运行 mvn install 命令(根据 readme.md 文件),然后当我尝试安装时它在 F
我正在使用 maven-bundle-plugin 构建一个 war 文件作为一个包,我想在 Felix 中部署它。这是相同的 POM 文件。 4.0.0 net.java jvnet-p
Wired's移动 View (将您的用户代理设置为 iOS Safari 以在桌面上查看它)具有对标准带下划线超链接样式的优雅转折: 我认为这是完全通过 CSS 实现的,没有外部图形,但不是: ba
我最近注意到 Wired 杂志的链接有一条蓝色下划线,该下划线很粗,横跨文本下行部分,并且颜色与文本不同。这是一个 random page举个例子。 我不认为这是用 bottom-border 完成的
我正在创建一个 8 位无符号 javascript 数组: var myArray = Uint8Array(64); 在客户端和服务器上操作这个数组,然后通过 socket.io 连接发送它。我们
我想在 selenium-wire 中获取一个响应主体作为字符串,我最终会将其解析为 JSON。selenium-wire 中的 response.body 给出字节字符串。我尝试将其解码为 resp
我在Linux服务器上安装seleniumwire库时遇到问题,它向我发送密码时出现了错误,我已经尝试解决它,但是我没有能力,有什么想法吗? Caused by: process didn
我正在尝试(在本地)运行 AngularJS 中的第三个示例 http://angularjs.org/new称为“Wire up a Backend”,运气不好(在 Chrome 上)。 它提示:
我有几个不同的部署。Deployment A: export port 3333Deployment B: export port 4444我想使用单个服务(具有 LoadBalancer 类型)来导
我使用 eclipse 为 arduino 制作项目。我将“Wire.h”包含到一个新类中,并且在 arduinocore 库项目中,我在 Wire.h header 处收到错误。错误在于该行76 最
我是一名优秀的程序员,十分优秀!