1
votes

Est-il approprié si Builder Pattern construit un objet à partir de la valeur de la base de données au lieu de l'entrée de paramètre

Vous prévoyez d'utiliser un modèle de générateur, mais je ne suis pas sûr de sa bonne façon de l'utiliser ou non. Ici, 1) extraire les données de la base de données ou de l'API et construire l'objet 2) publier sur l'API

donc, il ressemble à cette suite au modèle de conception Builder comme suit:

Je n'ai pas vu d'exemple où le modèle de générateur est utilisé pour construire un objet en lisant les données de la base de données. Est-ce un modèle approprié tout en restreignant l'objet de la base de données ou des données récupérées par l'API OrElse, sa mauvaise conception? Exemple:

public class ResultBuilder
{

    private IList<Parts> _parts; 
    private IList<Dealers> _dealers;

private int resultSetId;
    public ResultBuilder(int resultSetId)
    {
        this.resultSetId = resultSetId;
    }

    public ResultBuilder PrepareParts()
    {
        //call to PartsService and pull from database based on resultSetId and prepare List<Parts>.

    }
public ResultBuilder PrepareDealer()
    {
        //call to DealerService and pull from database and prepare List<Dealer>.

    }

    public IList<Dealers> Build()
    {
        //Build Dealers and Parts mapping for Dealer.Parts and return;
        //submit to another service.
    }
}

client: ResultBuilder.PrepareParts().PrepareDealer().Build();


0 commentaires

3 Réponses :


1
votes

Le principal problème avec le fait que le générateur remplisse l'objet de cette manière est que votre générateur ne pourra que créer des éléments de cette manière.

Par exemple, le mois prochain, vous constaterez peut-être que vous devrez créer l'un de ces objets avec des données similaires provenant d'un autre endroit.

Il serait plus flexible de conserver une séparation des préoccupations (ou "principe de responsabilité unique" : le S de SOLID ) en conservant le constructeur en tant que constructeur, et en utilisant une classe différente pour coordonner la récupération des données et leur transmission au constructeur.

Est-ce "mauvaise conception" de le faire comme vous l'avez décrit? Les décisions de conception sont très subjectives et doivent être basées sur les exigences connues et attendues à ce moment-là. Par exemple, les principes de conception contre ce que j'ai suggéré sont YAGNI et Règle de trois .

En d'autres termes, vous devez équilibrer l'augmentation de la flexibilité avec l'augmentation de la quantité de code.


2 commentaires

ici, sur la méthode client, tirez d'abord le resultSetId , puis passez à resultBuilder pour construire Parts, Dealers et Build to (soumettre et renvoyer la réponse). En interne, PrepareParts appellera le PartsService pour interagir avec le référentiel et extraire les données et même pour PrepareDealers. Mais, la méthode client (Main []) ne passera que resultSetId et aucun autre paramètre pour construire l'objet. Est-ce un scénario réaliste Ou, je dois appeler partsService ou dealerService à partir de la méthode client (Main []) elle-même et ne pas utiliser avec Builder Pattern?


En gros, voici également un objet à construire et à préparer en appelant différents serviceRepository .



1
votes

Je ne suis pas sûr de pouvoir «créer» un concessionnaire à moins qu'il ne s'agisse d'une boutique. Ayez plutôt le Dealer comme objet Director qui appelle sa propre méthode Construct qui accepte un objet Builder comme paramètre.

Un modèle de générateur nécessite une classe Director composée d'une ou plusieurs classes de générateur. Les classes Builder produisent des Parts.

Vous pouvez créer une classe de constructeur abstrait et avoir des constructeurs bétonnés pour des pièces de moto, de voiture ou de bateau. Ces générateurs fournissent une méthode pour renvoyer le produit qu'ils hébergent qui sont les parties dans cette instance.


0 commentaires

0
votes

Vous devez vous demander si les étapes PrepareParts (). PrepareDealer () sont obligatoires ou non, et si elles peuvent être omises ou non. Et, d'ailleurs, si l'ordre des opérations est important.

Si toutes les étapes sont obligatoires et si vous devez le faire dans l'ordre, alors un constructeur n'est pas une bonne solution.

La prochaine chose à considérer est de savoir si vous souhaitez changer le fournisseur des données pour vos étapes. Ensuite, vous avez besoin d'une sorte d'injection de dépendances dans votre générateur. Vous voudrez peut-être vous approvisionner à partir d'une base de données, d'un disque ou d'un service Web, par exemple.

Enfin, vous devriez réfléchir à ce que ce code doit faire:

var rb1 = ResultBuilder.PrepareParts()
var rb2 = rb1.PrepareDealer();
var rb1Built = rb1.Build();
var rb2Built = rb2.Build();

Souvent, vous voyez beaucoup de renvoyer ceci; dans une conception fluide. Cela conduit à un comportement inattendu. Si vous créez un pipeline d'actions qui est exécuté lorsque vous appelez Build () et que vous faites toujours un return new ResultBuilder (...); alors vous pouvez construire un solide conception fluide.


0 commentaires