Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
1. Спрашивается, сколько внутренней информации о Бункере я открыл другим классам? Отвечаю: вообще ничего. Понимаете? Все члены класса — приватные. Никто извне не должен знать что у класса внутри.
2. При этом, он сам выводит себя в интерфейс, сам обрабатывает нажатия на свои контролы, сам выполняет всю работу, которая требует знания о том, как он устроен.
class Silo
{
private:
ComboBox type;
Button manualMeasure;
};
//хороший случай, когда фреймворк позволяет классу хранить контролы у себя
class Silo
{
public:
void InitializeGUI(Window *);
private:
Button manualMeasure;
};
//когда фреймворк этого не позволяет
class Silo
{
public:
void InitializeGUI(Button *manualMeasure);
private:
Button *manualMeasure;
};
class Silo : public UserLevel::Notify, public SiloParamsSourceNotify
{
public:
Silo(SiloListNotify *notify, int role, const int &serverAddr);
~Silo();
const Silo &operator= (const Silo &);
void InitRemoteBehaviour();
//settings window
void UpdateUI(ArrayCtrl *params, ArrayCtrl *sensorParams, DropList *sensorType);
double GetPercentage();
//main window
EdgedButtonOption * UpdateButton(int x, int y);
EdgedButtonOption * GetButton();
ButtonOption * UpdateSiloDetails(Label *); //возвращает указатель на кнопку "Измерить" для добавления в окно
bool IsError ();
bool IsWarning();
bool UpdateStatus();
void InitShutdown();
void WaitFinish();
virtual void OnUserLevel (int level, const String &user);
void Xmlize(XmlIO &xml);
virtual void OnSensorTypeChanged();
private:
String GetPercentageString();
String GetVolumeString();
String GetHeightString();
String GetMassString();
One<SiloCore> core; friend class SiloGroup;
One<SiloParams> params;
void ShutdownRemoteBehaviour();
void ManualSensorMeasure();
void UpdateNextMeasureTime();
SiloListNotify *notify;
EdgedButtonOption button;
ButtonOption manual;
SiloSensor *sensor;
bool shutdown;
void GetDHPic(double h, double *dp, double *hp);
void GetDHPicBig(double h, double *dp, double *hp);
int userLevel;
String user;
bool userLevelChanged;
};void testShouldAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything() {
throw new SkipTest()
}
void testShouldAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything() {
DeepThought supercomputer;
long answer;
answer = supercomputer.calculate();
assertEquals(42, answer);
}
class SelfTested
{
protected:
virtual void SelfTest() = 0;
};
class DeepThought : SelfTested
{
protected:
virtual void SelfTest()
{
int answer = Calculate();
assertEquals(42, answer);
}
private:
int Calculate();
};
Наружу открываются функции-члены, которые просят класс выполнить ту или иную работу: выведи себя в интерфейс, обработай нажатие мышки, сохрани себя в XML и т.д.
class Shape
{
public:
virtual void Paint(int x, int y) = 0;
};
Когда объект реального мира содержит другой объект реального мира (только один), в С++ применяется наследование классов.
Итак, Бункер не выдаёт наружу подробности своей реализации. При этом, он сам выводит себя в интерфейс, сам обрабатывает нажатия на свои контролы, сам выполняет всю работу, которая требует знания о том, как он устроен. Наружу открываются функции-члены, которые просят класс выполнить ту или иную работу: выведи себя в интерфейс, обработай нажатие мышки, сохрани себя в XML и т.д.
Но этого мало, когда речь идёт о сложных механизмах. Все сложные алгоритмы я записываю на бумагу. Невозможно написать на С++ то, что не можешь описать простым русским языком. Когда описываешь что-то словами, мозг натыкается на подводные камни и нестыковки. Они становятся видны в самом начале, а не в конце, когда код уже написан. Сам текст должен быть отшлифован, тонкие места — упомянуты. Ещё плюс: можно вернуться к проекту через год и не тратить недели на вспоминание почему это сделано именно так.
Каждый объект — сам себе жнец, швец, на дуде игрец.
10 лет практики. Часть 1: построение программы