Descripción general: una programación orientada a objetos
invariable se refiere a un conjunto de condiciones o afirmaciones que deben mantenerse durante la vida de un objeto de una clase. Estas afirmaciones deben mantenerse desde el momento en que se llama al constructor para un objeto, al final de cada llamada al método miembro (mutador) hasta el final de la llamada al destructor. Estas condiciones verifican que el comportamiento de un objeto esté justificado durante su vida útil y que el objeto mantenga su estado bien definido según lo previsto. Sin embargo, no es necesario que el invariante sea verdadero durante la ejecución de un método mutador, sino que debe serlo al final del mismo.
Ejemplo:
crear un juego de serpientes:
supongamos que estamos creando un juego de serpientes y nuestra serpiente tiene la capacidad de teletransportarse unas pocas cuadras en alguna dirección. Definamos también nuestro invariante de que la cabeza de nuestra serpiente no debe cruzar los límites del patio de recreo. Ahora, si nos aseguramos de que nuestro invariante se mantenga al final de la función en la que implementamos nuestra capacidad de teletransportación, estamos bien. De lo contrario, nuestras afirmaciones fallarán y descubriremos que probablemente haya un error en nuestro código.
Implementación de código en C++:
como buena práctica de programación, se crea un método de miembro privado invariable cuyo deber es verificar que todas las condiciones necesarias permanezcan intransigentes y que todos los métodos puedan hacer suposiciones razonables sobre el estado del objeto. Llamamos a este método miembro invariable al final de los constructores y cada método mutador.
Código –
C++
#include <bits/stdc++.h> using namespace std; // self defined struct to // hold the position of snake struct Pos { int x; int y; Pos(int _x = 0, int _y = 0) { this->x = _x; this->y = _y; } }; class Snake { private: int play_width; // right bound int play_height; // height bound Pos loc; // position of snake's head void Invariant() { assert(loc.x >= 0 && loc.x <= play_width); assert(loc.y >= 0 && loc.y <= play_height); } public: // initialise the snake object with _width ans _height bounds // ans posx, posy current position Snake(int _width, int _height, Pos _p) { this->play_width = _width; this->play_height = _height; this->loc.x = _p.x; this->loc.y = _p.y; // call the invariant to ensure the object // was constructed correctly Invariant(); } // teleport and add inc.x units to current X coordinate // ans inc.y units to Y coordinate of snake void TeleportAhead(Pos inc) { loc.x += inc.x; loc.y += inc.y; //ensure that our snake wasn't // teleported out of play bounds Invariant(); } // return current position // calling invariant is unnecessary // because this is an accessor method Pos GetLoc() { return loc; } }; int main() { Snake snek(30, 20, Pos(5, 5)); // will throw assert error because // our snake is teleported out of bound snek.TeleportAhead(Pos(20, 20)); // will also fail Invariant() assertion // because the snake is being spawned out // of bounds Snake snek2(10, 10, Pos(12, 8)); return 0; }
Publicación traducida automáticamente
Artículo escrito por ayush.verma16 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA