1

I am writing applications in C++ using an sqlite database. Suppose I have a simple user system with a user database.

User Class

class User {
 private:
 void LoadFromDatabase(uint32_t id);
 public:
 std::string name;
 uint32_t age;
 void SayHello();
 void SetAge(uint32_t age);
};

User Table

+-------+-----+
| Name | Age |
+-------+-----+
| Billy | 22 |
| Bob | 44 |
+-------+-----+

When getting data from the database, I like to store things in row objects so it's super easy to figure out what's in the row (otherwise its a pointer to a char array and you'd have to know what each column index is). This is where the redundancy problem comes in.

User Row

class UserRow {
 public:
 std::string name;
 uint32_t age;
};

So now I have repeated the class properties between two classes. This is obviously a trivial example, but sometimes rows have 10 or more columns. One solution would be to get rid of UserRow and just pass around User, but the database shouldn't really know anything about User and be as dumb as possible. Another solution could be to have User.properties which is = to a UserRow, but that makes it less accessible.

What would be the best way to avoid these duplicate fields/classes?

asked Aug 30, 2018 at 20:50
5
  • 1
    Just use User where you would use UserRow. Both classes contain exactly the same data, and you don't have to call the SayHello and SetAge functions if you don't need to. Commented Aug 30, 2018 at 21:56
  • I don't want to post this as a full answer because it doesn't exactly answer the question, but note that if User is a domain object and UserRow a data transfer object, there's no architectural need to remove the redundancy. Sure, it's slightly annoying, but it has the advantage of being more flexible in light of future changes. Commented Aug 31, 2018 at 7:52
  • How are you binding the UserRow? with a TypeHandler? Commented Aug 31, 2018 at 8:22
  • @SebastianRedl: I don't believe that this kind of gained flexibility is worth the admittedly annoying redundancy in most cases. Shouldn't the database reflect the domain model. Why should anyone modify the database without modifying the domain objects as well? Yes, there might be special cases where it makes sense but should we build our software architecture around special cases? Commented Aug 31, 2018 at 10:06
  • @FrankPuffer The database might be independent of the application. Modification usually happens the other way round: the domain objects get modified, but the database stays the same to avoid the need for data migration. And finally, in DDD, there may be multiple object-based views of the same table, i.e. multiple user entities that reflect some part of the user table/DTO. Commented Aug 31, 2018 at 14:44

2 Answers 2

5

Look at this approach :

class User {
 private:
 UserRow userRow;
 void LoadFromDatabase(uint32_t id); // init userRow
 public:
 std::string GetName(){return userRow.name;}
 // implement setName in an analogous manner
 uint32_t getAge(){return userRow.age;}
 // setAge ...
 void SayHello();
 void SetAge(uint32_t age);
};

The advantage is, the code for UserRow can be created by some generator in a standard manner, just by utilizing the meta data from a database. UserRow then becomes your data access layer (DAL), User, however, is a class of your domain layer.

Moerover, you should consider to move LoadFromDatabase to another place, like into some repository class, to make the class User persistent-ignorant.

answered Aug 30, 2018 at 22:33
1

You could say that your User objects actually are row objects, since they already have the same information. Like you have done now, You have only created an unnecessary abstraction layer which doesn't provide anything useful.

answered Aug 30, 2018 at 21:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.