文章来自于刘光聪,实践了一把,觉得在代码设计上自己有如下收益:
- 多级容器封装;
- 分离变化方向;
- 依赖于稳定;
- C++私有继承堪称C++的必杀技之一。
原文章里面代码有编译错误,这里重新整理了一下,方便大家看。重构的思路可以看原文章:一次正交设计之旅
重构前的代码:
static vector<vector<int>> getFlaggedCells(vector<vector<int>>& board)
{
vector<vector<int>> result;
for (auto x : board)
{
if (x[0] == 4)
{
result.push_back(x);
}
}
return result;
}
int countFlaggedCells(vector<vector<int>>& board)
{
vector<vector<int>> result = getFlaggedCells(board);
return result.size();
}
static vector<vector<int>> getUnflaggedCells(vector<vector<int>>& board)
{
vector<vector<int>> result;
for (auto x : board)
{
if (x[0] == 3)
{
result.push_back(x);
}
}
return result;
}
int countUnflaggedCells(vector<vector<int>>& board)
{
vector<vector<int>> result = getUnflaggedCells(board);
return result.size();
}
static vector<vector<int>> getAliveCells(vector<vector<int>>& board)
{
vector<vector<int>> result;
for (auto x : board)
{
if (x[0] == 2)
{
result.push_back(x);
}
}
return result;
}
int countAliveCells(vector<vector<int>>& board)
{
vector<vector<int>> result = getAliveCells(board);
return result.size();
}
// global variable
vector<vector<int>> store;
void saveAliveCells(vector<vector<int>>& board)
{
store = getAliveCells(board);
}
重构后的代码:
enum State
{ INIT,SELECTED,ALIVE,FLAGGED };
struct Cell
{
bool flagged() const
{
return master() == FLAGGED;
}
bool alive() const
{
return master() == ALIVE;
}
private:
State master() const
{
return states.front();
}
private:
vector<State> states;
};
struct CellCollector
{
virtual void add(const Cell& cell) = 0;
virtual ~CellCollector()
{
}
};
// 公有继承
template<typename Pred>
struct CellCounter :CellCollector
{
CellCounter(Pred pred) :num(0), pred(pred)
{
}
int get() const
{
return num;
}
private:
void add(const Cell& cell)
{
if (pred(cell))
++num;
}
private:
int num;
Pred pred;
};
struct GameBoard
{
int countFlaggedCells() const
{
return count([](const Cell& cell){
return cell.flagged();
});
}
int countUnflaggedCells() const
{
return count([](const Cell& cell){
return !cell.flagged();
});
}
int countAliveCells() const
{
return count([](const Cell& cell){
return cell.alive();
});
}
void List(CellCollector& col) const
{
for (auto &cell : cells)
{
col.add(cell);
}
}
private:
template<typename Pred>
int count(Pred pred) const
{
CellCounter<Pred> counter(pred);
List(counter);
return counter.get();
}
private:
vector<Cell> cells;
};
// 私有继承
struct CellStore :private CellCollector
{
void save(const GameBoard& board)
{
board.List(*this);
}
private:
void add(const Cell& cell)
{
if (cell.alive())
cache.push_back(cell);
}
private:
vector<Cell> cache;
};
网友评论