L'exemple ci-dessous est totalement artificiel et son seul but est de faire passer mon message.
Supposons que j'ai une table SQL:
CREATE TABLE rectangles (
width int,
height int
);
Classe de domaine:
public class Rectangle {
private int width;
private int height;
/* My business logic */
public int area() {
return width * height;
}
}
Supposons maintenant que j'ai l'obligation de montrer à l'utilisateur la surface totale de tous les rectangles de la base de données. Je peux le faire en récupérant toutes les lignes du tableau, en les transformant en objets et en les itérant. Mais cela semble juste stupide, car j'ai beaucoup, beaucoup de rectangles dans ma table.
Alors je fais ça:
SELECT sum(r.width * r.height)
FROM rectangles r
C'est simple, rapide et utilise les points forts de la base de données. Cependant, il introduit une logique dupliquée, car j'ai également le même calcul dans ma classe de domaine.
Bien sûr, pour cet exemple, la duplication de la logique n'est pas du tout fatale. Cependant, je suis confronté au même problème avec mes autres classes de domaine, qui sont plus complexes.
la source
Réponses:
Comme l'a souligné lxrec, cela variera d'une base de code à l'autre. Certaines applications vous permettront d'intégrer ce type de logique métier dans des fonctions SQL et / ou des requêtes et vous permettront de les exécuter à tout moment pour montrer ces valeurs à l'utilisateur.
Parfois, cela peut sembler stupide, mais il vaut mieux coder pour l'exactitude que la performance comme objectif principal.
Dans votre exemple, si vous affichez la valeur de la zone pour un utilisateur dans un formulaire Web, vous devez:
C'est stupide pour des choses simples comme celle de l'échantillon, mais il peut être nécessaire de faire des choses plus complexes comme le calcul du TRI d'un investissement d'un client dans un système bancaire.
Code de correction . Si votre logiciel est correct, mais lent, vous aurez des chances d'optimiser où vous en avez besoin (après profilage). Si cela signifie conserver une partie de la logique métier dans la base de données, tant pis. C'est pourquoi nous avons des techniques de refactoring.
Si cela devient lent ou ne répond plus, vous pouvez avoir des optimisations à faire, comme violer le principe DRY, ce qui n'est pas un péché si vous vous entourez des tests unitaires et des tests de cohérence appropriés.
la source
Vous dites que l'exemple est artificiel, donc je ne sais pas si ce que je dis ici convient à votre situation réelle, mais ma réponse est - utilisez une couche ORM (Object-relationnel mapping) pour définir la structure et l'interrogation / manipulation de votre base de données. De cette façon, vous n'avez pas de logique dupliquée, car tout sera défini dans les modèles.
Par exemple, en utilisant le framework Django (python), vous définiriez votre classe de domaine rectangle comme le modèle suivant :
Pour calculer la superficie totale (sans aucun filtrage), vous devez définir:
Comme d'autres l'ont mentionné, vous devez d'abord coder pour l'exactitude et n'optimiser que lorsque vous rencontrez vraiment un goulot d'étranglement. Donc, si à une date ultérieure vous décidez, vous devez absolument optimiser, vous pouvez passer à la définition d'une requête brute, telle que:
la source
J'ai écrit un exemple stupide pour expliquer une idée:
Donc, si vous avez une logique:
Vous pouvez le réutiliser dans les classes de domaine:
Ou dans votre couche de génération SQL:
Et, bien sûr, vous pouvez le changer facilement. Essaye ça:
la source
Comme l'a dit @Machado, la façon la plus simple de le faire est de l'éviter et de faire tout votre traitement dans votre java principal. Cependant, il est toujours possible d'avoir à coder la base avec un code similaire sans se répéter soi-même en générant le code pour les deux bases de code.
Par exemple, en utilisant cog enable pour générer les trois extraits à partir d'une définition commune
extrait 1:
extrait 2:
extrait 3:
à partir d'un fichier de référence
la source