Skip to content

Commit ccfa19d

Browse files
committed
Add decoupling exercise
2 parents 294f127 + 40402bb commit ccfa19d

File tree

6 files changed

+105
-0
lines changed

6 files changed

+105
-0
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,11 @@ script:
6666
- cmake ..
6767
- make
6868
- ./cpp11training
69+
- cd ../..
70+
- cd coupling
71+
- mkdir build && cd build
72+
- cmake ..
73+
- make
74+
- ./coupled_program
75+
- cd ../..
6976

coupling/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

coupling/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
cmake_minimum_required(VERSION 3.0.0)
2+
3+
set(CMAKE_CXX_STANDARD 17)
4+
project(coupled_program)
5+
6+
add_library(graphs coupled_program/graphs/graph.cpp)
7+
8+
add_executable(coupled_program coupled_program/deps.cpp)
9+
target_link_libraries(coupled_program LINK_PUBLIC graphs)

coupling/coupled_program/deps.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <iostream>
2+
#include "graphs/graph.hpp"
3+
4+
int main(int argc, const char **args) {
5+
Graph graph;
6+
7+
auto n1 = graph.addNode({"A"});
8+
auto n2 = graph.addNode({"B"});
9+
auto n3 = graph.addNode({"C"});
10+
11+
graph.connect(n1, n2)->name = "a-b";
12+
graph.connect(n1, n3)->name = "a-c";
13+
14+
graph.dump_to(std::cout);
15+
return 0;
16+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include "graph.hpp"
2+
3+
Node *Graph::addNode(Node n) {
4+
nodes.push_back(std::make_unique<Node>(std::move(n)));
5+
return nodes.back().get();
6+
}
7+
8+
Edge *Graph::connect(Node *a, Node *b) {
9+
std::unique_ptr<Edge> edge{new Edge{"", a, b}};
10+
edges.push_back(std::move(edge));
11+
return edges.back().get();
12+
}
13+
14+
std::ostream &Graph::dump_to(std::ostream &o) const {
15+
o << "Graph: " << "\n";
16+
for(const auto &n: nodes){
17+
o << "node " << n->name << ":\n";
18+
for(const auto &e: edges) {
19+
if(e->a == n.get()) {
20+
o << " -> " << e->b->name << "(" << e->name << ")\n";
21+
}
22+
}
23+
}
24+
return o;
25+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#pragma once
2+
3+
#include <vector>
4+
#include <string>
5+
#include <memory>
6+
#include <ostream>
7+
8+
struct Node {
9+
std::string name;
10+
};
11+
12+
struct Edge {
13+
std::string name;
14+
Node *a;
15+
Node *b;
16+
};
17+
18+
// TODO:
19+
//
20+
// 1. install a compilation firewall around
21+
// the graph representation.
22+
//
23+
// In other words, client does not see
24+
// the actual representation of the contained
25+
// members.
26+
//
27+
// Nor does it need to know what a `vector` is
28+
// or a `unique_ptr`.
29+
//
30+
// This removes the coupling to the STL of this class,
31+
// and to the std::unique_ptr C++11 addition.
32+
//
33+
// 2. decouple the client code from the representation
34+
// by making the Node and Edge opaque types (handles) too.
35+
//
36+
// ADVANCED:
37+
// You may attempt to even use this class
38+
// from a C program.
39+
//
40+
struct Graph {
41+
Node * addNode(Node n);
42+
Edge * connect(Node *, Node *);
43+
std::ostream & dump_to(std::ostream &o) const;
44+
private:
45+
std::vector<std::unique_ptr<Node>> nodes;
46+
std::vector<std::unique_ptr<Edge>> edges;
47+
};

0 commit comments

Comments
 (0)