2016-12-26 2 views
3

Ceci est un exemple.Smalltalk - Comment éviter les typechecks dans cette situation?

Supposons que les contraintes suivantes:

  • Une boutique ne peut avoir 5 produits.
  • Un magasin d'alimentation peut seulement ajouter des produits alimentaires.
  • Un magasin de vêtements ne peut ajouter que des vêtements.
  • Un magasin mixte peut ajouter les deux produits.

Je les classes suivantes:

  • AbstractShop

    • Foodshop
    • ClothesShop
    • MixedShop
  • AbstractProduct

    • Vêtements
    • alimentaire

fonctionnalité:

AbstractShop>>addProduct: aProduct 
    (products size < 5) 
    ifTrue:[^ products add:aProduct] 
    ifFalse:[ self error: 'A shop can only have five products' ] 

    FoodShop>>addProduct: aProduct 
    (aProduct isMemberOf: Food) 
    ifTrue:[^ super addProduct: aProduct] 
    ifFalse:[ self error: 'You can only add food products to a foodshop' ] 

    ClothesShop>>addProduct: aProduct 
    (aProduct isMemberOf: Clothing) 
    ifTrue:[^ super addProduct: aProduct] 
    ifFalse:[ self error: 'You can only add clothing products to a clothes shop' ] 

"ClothesShop doesn't override the addProduct, because it can add them both." 

Comment puis-je éviter de vérifier le type du produit, pour voir si elle peut être ajouté à la boutique? Je veux éviter cela, car c'est une mauvaise odeur. J'ai essayé de le découvrir avec Double Dispatch, mais cela semble rendre le code plus difficile à maintenir.

+2

Mais le double dispatching est le moyen le plus propre. –

+0

Deux livres qui montrent la façon de faire Smalltalk sont http://stephane.ducasse.free.fr/FreeBooks/BestSmalltalkPractices/Draft-Smalltalk%20Best%20Practice%20Patterns%20Kent%20Beck.pdf et http: // sdmeta. gforge.inria.fr/FreeBooks/SmalltalkDesignPatternCompanion/Ce sont les deux brouillons du livre final, le meilleur pour acheter le livre physique, mais ceux-ci sont le deuxième meilleur choix. –

Répondre

2

Ceci est un modèle que nous avons utilisé plusieurs fois. La classe déclare quelles choses (ou instances de quelles classes) peuvent gérer.

AbstractShop class >> allowedProducts 
    self subclassResponsibility 

FoodShop class >> allowedProducts 
    ^#(Food) 

ClothesShop class >> allowedProducts 
    ^#(Clothing) 

MixedShop class >> allowedProducts 
    ^AbstractProduct subclasses 

AbstractShop >> isAllowed: aProduct 
    ^self class allowedProducts includes: aProduct class 

AbstractShop>>addProduct: aProduct 
    products size < 5 
     ifFalse:[ self error: 'A shop can only have five products' ]. 
    (self isAllowed: aProduct) 
     ifFalse: [self error: 'Product not allowed in this shop' ]. 
    ^products add:aProduct 

Et vous ne devez pas redéfinir addProduct.

Mais si les odeurs disent quelque chose, la constante magique 5 dans le contrôle de capacité doit également être extraite, et vous devriez avoir la validation du produit séparée de l'addition.

Je n'ai jamais aimé appeler une classe Résumé Quelque chose, c'est aussi une mauvaise odeur. Dans votre cas, l'utilisation juste de la boutique et du produit est assez abstraite.

6

Vous pouvez aussi le faire avec double expédition:

AbstractShop>>addProduct: aProduct 
    (products size < 5) 
    ifTrue:[^aProduct addToShop: self ] 
    ifFalse:[ self error: 'A shop can only have five products' ] 

AbstractShop>>addFoodProduct: aProduct 
^self subclassResponsibility 

AbstractShop>>addClothingProduct: aProduct 
^self subclassResponsibility 

FoodShop>>addFoodProduct: aProduct 
^products add: aProduct 

FoodShop>>addClothingProduct: aProduct 
    self error: 'You can only add clothing products to a clothes shop' 

AbstractProduct>>addToShop: aShop 
^self subclassResponsibility 

Food>>addToShop: aShop 
^aShop addFoodProduct: self 

Clothing>>addToShop: aShop 
^aShop addClothingProduct: self 

En ce qui concerne votre cas d'utilisation, je dirais qu'il est préférable d'avoir une collection d'éléments pris en charge, un vous pouvez potentiellement avoir de nombreux magasins avec différentes combinaisons des articles. Mais avec double expédition, vous ne vérifiez jamais les types.

+0

Ceci est la meilleure réponse IMO –