Mission Impossible / How to create datatypes which cannot contain invalid state
adrianimboden
22.5K views
The problem
This example represents a production control thingy, which optionally compares the quality of the produced item to a given reference.
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <cstdint>
#include <iostream>
class ProductProducer {
public:
explicit ProductProducer(bool quality_check_enabled, int32_t quality_reference, int32_t maximal_difference)
: quality_check_enabled_{quality_check_enabled}
, quality_reference_{quality_reference}
, maximal_difference_{maximal_difference} {
}
bool produce_one(int32_t quality) {
if (quality_check_enabled_) {
std::cout << "checking quality..." << std::endl;
const auto difference = quality - quality_reference_;
return difference <= maximal_difference_;
}
std::cout << "not checking quality..." << std::endl;
return true;
}
private:
bool quality_check_enabled_;
int32_t quality_reference_;
int32_t maximal_difference_;
};
void do_one_production_cycle() {
{
// 3 parameters, 2 unused
auto producer = ProductProducer{false, 1, 3};
producer.produce_one(5);
}
{
// 3 parameters, 0 unused
auto producer = ProductProducer{true, 1, 3};
producer.produce_one(5);
}
}
The problem here is, that a subset of the state is only used based on never-changing facts. The user of this class has to provide quality reference data, even if that data is not used at all.
When someone tries to change the code later to always use the quality data, he may never be sure if the data passed into the constructor is valid or not. He has to check all calling sites to verify that.
Try to refactor the example program using std::optional, so that the class ProductProducer never contains unused members.
Create your playground on Tech.io
This playground was created on Tech.io, our hands-on, knowledge-sharing platform for developers.