Зависимости / Business Logic In Data Mapper (ООП)

Я уже некоторое время пишу код PHP, но только недавно заявил, что знакомлюсь с подходом ООП, и я пытаюсь понять, какие вещи принадлежат приложению.

Я написал приведенный ниже код, который представляет собой средство отображения данных для обработки информации команды в базу данных и из базы данных в моем приложении, но я не совсем понимаю, где и как я должен применять свою бизнес-логику / правила.

Например, если вызывается метод delete в классе teamMapper, он должен приступить к запуску SQL для удаления команды из базы данных, только если эта команда не участвует ни в одном совпадении. Как бы я поступил так, не нарушая каких-либо правил ООП или не усложняя классу юнит-тестирование?

Я гуглил это довольно много, но пока безрезультатно, у всех картографов данных, которые я видел, просто есть оператор SQL для команды удаления и нет логики относительно того, может ли действие фактически выполняться или нет.

Я полагаю, я мог бы внедрить экземпляр, скажем, MatchesMapper в мой класс TeamMapper через метод конструктора, а затем перейти к выполнению таких команд, как $ this-> matchMapper-> hasMatches ($ team_id) или, в качестве альтернативы, иметь статический метод в отдельном классе, который выполняет то же самое, но как правильно это сделать?

Любая помощь будет принята с благодарностью, спасибо.

interface TeamMapperInterface
{
public function findById($id);
public function insert(TeamInterface $team);
public function update(TeamInterface $team);
public function delete($id);
public function isTeamByName($name);
}

class TeamMapper implements TeamMapperInterface {

private $db;

public function __construct($db)
{
// Assign the database connection to a variable which can be used throughout the class
$this->db = $db;
}

/**
* Find By Id
*
* This function retrieves a team's information from the database and returns it as an object of "team".
*
* @param $id
* @return null|Team
*/
public function findById($id)
{
// Prepare an SQL statement for attempting to retrieve the team's information from the database
$sql = 'SELECT `id`, `name`, `country`, `league`, `active` FROM `#` WHERE `id` = ? LIMIT 1';

// Execute the SQL statement
$query = $this->db->query($sql, array($id));

// Check to see whether the database query returned a record or not
if(is_object($query) === false || $query->num_rows() == 0)
{
// Return null as either the database query failed or no record could be found for the given id
return null;
}

// If a team was found then attempt to load it into an a new instance of the team class
return $this->loadTeam($query->row_array());
}

/**
* Insert
*
* This function takes a team interface object and inserts it into the database.
*
* @param TeamInterface $team
* @return mixed
* @throws Exception
*/
public function insert(TeamInterface $team)
{
// Verify that all of the variables in the object passed to this function have been set before attempting to insert the data into the database
if(is_null($team->getName()) || is_null($team->getCountry()) || is_null($team->getLeague()) || is_null($team->getActive()))
{
// Throw an exception because a certain event happened
throw new Exception('The team\'s information is incomplete and therefore cannot be added to the database.');
}

// Check to see if there is already a team in the database with the given name
if($this->isTeamByName($team->getName()))
{
// Throw an exception because a certain event happened
throw new Exception('The team name specified already exists in the database.');
}

// Prepare an SQL statement for inserting the team's information into the database
$sql = 'INSERT INTO `#` (`id`, `name`, `country`, `league`, `active`) VALUES (?,?,?,?,?)';

// Execute the SQL statement and then return whether it was successful or not
return $this->db->query($sql, array('', $team->getName(), $team->getCountry(), $team->getLeague(), $team->getActive()));
}

/**
* Update
*
* This function takes a team interface object and uses it to update the relevant information on the database.
*
* @param TeamInterface $team
* @return mixed
* @throws Exception
*/
public function update(TeamInterface $team)
{
// Todo!
}

/**
* Delete
*
* This function delete's a team from the database using the id specified.
*
* @param $id
* @return mixed
* @throws Exception
*/
public function delete($id)
{
// Determine if the variable passed to this function was an instance of team interface instead of the expected integer for the id
if($id instanceof TeamInterface)
{
$id = $id->getId();
}

// The team can only be deleted if it doesn't have any matches assigned to it
if(MatchesMapper::numMatchesByTeam($id) > 0)
{
// Throw an exception because a certain event happened
throw new Exception('The team can only be deleted when it doesn\'t have any matches assigned to it.');
}

// Prepare an SQL statement for deleting the team's information from the database
$sql = 'DELETE FROM `#` WHERE `id` = ?';

// Execute the SQL statement and then return whether it was successful or not
return $this->db->query($sql, array($id));
}

/**
* Is Team By Name
*
* This function queries the database to determine whether a team exists for a given name
*
* @param $name
* @return bool
*/
public function isTeamByName($name)
{
// Prepare an SQL statement for checking whether a team already exists in the database
$sql = 'SELECT `id` FROM `#` WHERE `name` = ? LIMIT 1';

// Execute the SQL statement
$query = $this->db->query($sql, array($name));

// Return the relevant result depending on whether a team was found or not
return ($query->num_rows() == 1) ? true : false;
}

/**
* Load Team
*
* This function takes an array containing some information about a given team and returns it as an object of "team"*
* @param array $row
* @return Team
*/
private function loadTeam(array $row)
{
// Create a new object to hold the information for the team
$team = new Team($row['name'], $row['country'], $row['league'], $row['active']);

// Set the team's id as this can't be done through the constructor method of the team class
$team->setId($row['id']);

// Return the new team object
return $team;
}
}

2

Решение

Вы можете использовать ограничения внешнего ключа InnoDB, чтобы остановить удаление, если существуют зависимые записи. Специально ОГРАНИЧЕНИЕ.

Увидеть:
http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html

0

Другие решения

Других решений пока нет …