I am doing a final project in a C++ class writing a very simple usenet-like clie
ID: 654318 • Letter: I
Question
I am doing a final project in a C++ class writing a very simple usenet-like client/server. I figure that since it's usenet-like I'll have a NewsGroup class and an Article class, I'm now working on my Article class. I can't really decide on a good design, though (this class is not about design patterns and I haven't taken any).
This is what I have:
class Article {
public:
const std::string author;
std::string title;
std::string text;
const uint32_t id;
system_clock::time_point timestamp;
Article(const std::string auth&,
const std::string tit&,
const std::string txt&,
const system_clock::time_point&);
private:
Article(const Article&);
void operator=(const Article&);
static uint32_t id_pool;
};
My motivation is this:
author should never change -> const
title could change if edited -> non-const
text could change if edited -> non-const
id should never change -> const
timestamp could change but probably shouldn't, I'm not sure what to do with it yet.
id_pool is just where I get IDs from. One specification is that IDs should never be reused so I just increment id_pool in the Article constructor.
Coming from Java with all the getters and setters that I really don't like, and then some Python with it's "Everything public" and properties, that I do like, I'm getting a bit confused here.
I mean, I could make the members private and have getters and setters (I can't think of any natural "verb-methods" that an Article can "do"), but it feels like I would gain very little.
I would be thankful for some pointers on good design in this case.
Explanation / Answer
Start with the interface you want the class to expose to its users. Do not think immediately about the implementation, e.g., whether to use std::string for the title, etc. I would come up with something like below:
class Article {
public:
typedef implementation_defined Id;
Article(const char* author, const char* title);
~Article();
Id GetId() const;
const char* GetAuthor() const;
const char* GetTitle() const;
const char* GetText() const;
system_clock::time_point GetTime() const;
void SetTitle(const char* text);
void SetText(const char* text);
void SetTime(system_clock::time_point timestamp);
};
The intention is that the caller should use the type Article::Id instead of something like int. I assume the Id is uniquely generated on creation, the text can be empty, and the default timestamp is the current time.
As you are not exposing the implementation to the caller, you are free to change the implementation later. E.g., maybe the interface dictates the UTF-8 encoding, but the real implementation uses UTF-16 (wchar_t) on Windows (just to show, not that it is something you should/want to do). You can also make some checks in the Set... methods.
This might be trivial, but I think the principle is that you need to: 1) think from the user of the class; 2) make it flexible and reduce the dependency.
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.