Compass : East Oriented
#1
Bonjour,

J'ai découvert il y a quelques jours une nouvelle "méthode" de programmation, de structurer et d'architecturer son code.

Je vous invite à la découvrir en lisant ceci : http://jamesladdcode.com/?p=12
Puis, pour ceux qui sont intéressé pas East et veulent développer en suivant le principe "East" d'en parler et échanger ici.
Répondre
#2
Intéressant. Est-ce que tu pourras montrer quelques exemples de tes propres refactoring sur du vrai code ?
Répondre
#3
Justement, je ne suis pas sûr de bien l'utiliser 2

Mais pour le moment j'ai un code qui ressemble à ça :

// dans CityRepository.php
public function getZCountryWithLotsPopulation()
{

$query = new Query(
"select * from T_CITY_CIT as a where cit_name like :name and cit_population > :population limit 3",
array('name' => 'Z%', 'population' => '200000')
);

return $this->execute($query);
}


// Dans Repository.php
public function execute(Query $query, Collection $collection = null, ConnectionPool $connectionPool = null)
{

if ($connectionPool === null) {
$connectionPool = ConnectionPool::getInstance();
}

if ($collection === null) {
$collection = new Collection();
}

$connectionPool->connect($this->meta['connection'], $this->meta['database'],
function ($driver) use($query, $collection) {
$query->execute($driver, $this->meta['columns'], $collection);
}
);

return $collection;
}



// Dans ConnectionPool.php
public function connect($connectionName, $database, callable $callback)
{
if (isset($this->connections[$connectionName]) === false) {
if (isset($this->connectionConfig[$connectionName]) === false) {
throw new Exception("Can't find connection: " . $connectionName);
}

$driverClass = $this->connectionConfig[$connectionName]['namespace'] . '\\Driver';
$driver = new $driverClass();
$driver->connect(
$this->connectionConfig[$connectionName]['host'],
$this->connectionConfig[$connectionName]['user'],
$this->connectionConfig[$connectionName]['password'],
$this->connectionConfig[$connectionName]['port']);
$this->connections[$connectionName] = $driver;
}

$this->connections[$connectionName]->setDatabase($database);

$callback($this->connections[$connectionName]);

return $this;
}


// Dans Query.php
public function execute(
DriverInterface $driver,
$columnsMeta,
Collection $collection = null
)
{
$params = array();
foreach ($this->params as $key => $value) {
if (isset($columnsMeta[$key]['type']) === false) {
$type = 'string';
} else {
$type = $columnsMeta[$key]['type'];
}

$params[$key] = array(
'type' => $type,
'value' => $value
);
}

if ($collection === null) {
$collection = new Collection();
}


$driver->prepare(
$this->sql,
function ($statement, $driverStatement) use($driver, $params, $collection) {
$statement->execute($driverStatement, $params, $collection);
},
$statement
);

return $this;
}


// dans Driver.php
public function prepare($sql, callable $callback, StatementInterface $statement = null)
{
$sql = preg_replace_callback(
'/:([a-zA-Z0-9_-]+)/',
function ($match) use (&$paramsOrder) {
$paramsOrder[$match[1]] = null;
return '?';
},
$sql
);

if ($statement === null) {
$statement = new Statement();
}

$driverStatement = $this->connection->prepare($sql);

if ($driverStatement === false) {
$this->ifIsError(function () use($sql) {
throw new QueryException($this->connection->error . ' (Query: ' . $sql . ')', $this->connection->errno);
});
}

$callback($statement, $driverStatement);

return $this;
}


// Dans Statement.php
public function execute($driverStatement, $params, Collection $collection = null)
{

$this->driverStatement = $driverStatement;

$types = '';
$values = array();
foreach (array_keys($params) as $key) {
switch ($params[$key]['type']) {
case 'int':
case 'integer':
$type = 'i';
break;
case 'float':
$type = 'd';
break;
case 'blob':
$type = 'b';
break;
default:
$type = 's';
}

$types .= $type;
$values[] = &$params[$key]['value'];

}

array_unshift($values, $types);
call_user_func_array(array($driverStatement, 'bind_param'), $values);

$driverStatement->execute();
$this->setCollectionWithResult($driverStatement, $collection);

return $this;
}

public function setCollectionWithResult($driverStatment, Collection $collection)
{

$result = $driverStatment->get_result();
if ($result === false) {
throw new QueryException($driverStatment->error, $driverStatment->errno);
}

$collection->set(new Result($result));
return $this;
}
Répondre
#4
Pourquoi faire simple ...
Répondre
#5
Si tu te contentes de lire le code oui c'est ce que tu peux te dire.
Mais quelqu'un qui coderait en procédurale et lirait un code POO pourrait dire la même phrase que toi ;-)

En fait, en lisant l'article et/ou te renseignant, tu apprends qu'en gros la POO que l'on fait (pour la très grande majorité d'entre nous), n'est pas de la POO, mais juste du procédurale codé en Objet.

De plus l'exemple que j'ai donné n'est pas forcément parlant, car sans doute pas super bien codé et extrait d'une application ORM (qui de toute façon même codé en POO sale) est une application qui peut vite devenir complexe.
Répondre
#6
Pour l'instant, je reste un peu sceptique. En fait, je pense exactement la même chose que l'un des commentaires.

Oleg a écrit :Your examples are nice and educating in what is possible. Your code definitively promotes reuse and DRY.

My concern is understandability/readability/overengineering. Examples 8 and 9 are easily readable. Example 10 and 11 are worse. In Ex 8 you needed 1 class, which did all things. In Ex 10 you need MovieAction, Selector, Finder(?) and in Ex 11 all those subclasses.
I’m struggling to find justification for that complexity. How about adding some rationale, when this design should and shouldn’t be used.
Répondre
#7
(08-10-2014, 10:01 AM)oxman a écrit : En fait, en lisant l'article et/ou te renseignant, tu apprends qu'en gros la POO que l'on fait (pour la très grande majorité d'entre nous), n'est pas de la POO, mais juste du procédurale codé en Objet.

Mais ça je l'ai toujours dit, pas besoin de lire un nieme article qui le découvre et qui propose comme solution de rajouter... ...encore plus de classes. Mais c'est pas "certains d'entre nous", c'est les langages style PHP ou C++ qui font ça, ou on doit nous meme s'assurer que le paradigme objet est respecté.

(08-10-2014, 11:06 AM)Arnadus a écrit : Pour l'instant, je reste un peu sceptique. En fait, je pense exactement la même chose que l'un des commentaires.

Oleg a écrit :Your examples are nice and educating in what is possible. Your code definitively promotes reuse and DRY.

My concern is understandability/readability/overengineering. Examples 8 and 9 are easily readable. Example 10 and 11 are worse. In Ex 8 you needed 1 class, which did all things. In Ex 10 you need MovieAction, Selector, Finder(?) and in Ex 11 all those subclasses.
I’m struggling to find justification for that complexity. How about adding some rationale, when this design should and shouldn’t be used.

Overengineering résume assez bien l'article a mon sens aussi. Pourquoi faire simple ...
Répondre
#8
2 Je vais pouvoir réciter mes cours de 5e année:

POO, "Orienté" n'est pas là pour rien: cette histoire de "boussole qui pointe à l'Est" est simplement la redécouverte du concept objet pur, dans lequel les objets du code échangent des messages et rien d'autre.

Si objet1 appelle la méthode objet2.methode(arguments,...), alors cela correspond effectivement à l'envoie d'un message de type methode() avec les paramètres arguments,... de la part de objet1 à destination de objet2. En revanche, return n'est pas un échange de message entre objets puisque objet2 renvoie une entité (objet, variable,...) au flot d'exécution d'objet1, et non un message "typé" à destination de l'objet lui-même. Une fois le message envoyé par objet1, celui-ci ne devrait pas attendre de retour de la méthode (peut-être uniquement en attendre la fin et encore, là, je n'en suis plus certain), et il devrait poursuivre son chemin.

D'où le getTruc() remplacé par putTruc() dans l'article.

[Doublé d'un cheveu par Niahoo 34]
Répondre
#9
(Suite de mon post) Je vais dire un truc un peu pédant mais depuis que je fais du FP et de l'objet en erlang, ma façon de coder objet en php s'est nettement éloignée de ce genre de considerations sur la syntaxe ou la façon d'ecrire.
Répondre
#10
(08-10-2014, 01:12 PM)niahoo a écrit : (Suite de mon post) Je vais dire un truc un peu pédant mais depuis que je fais du FP et de l'objet en erlang, ma façon de coder objet en php s'est nettement éloignée de ce genre de considerations sur la syntaxe ou la façon d'ecrire.

C'est à dire ?
FP pour functional programming je suppose ?
Répondre




Utilisateur(s) parcourant ce sujet : 2 visiteur(s)