这是一个例子。
假设以下约束:
我有以下课程:
AbstractShop
AbstractProduct
功能:
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."
如何避免检查产品类型,看它是否可以添加到商店?我想避免这种情况,因为这是一种难闻的气味。我尝试使用Double Dispatch来解决它,但它似乎使代码更难以维护。
答案 0 :(得分:6)
您也可以使用双重调度执行此操作:
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
关于你的用例,我想说最好有一系列支持的项目,你可能会有很多商店有不同的项目组合。但是,通过双重发送,您永远不会检查类型。
答案 1 :(得分:2)
这是我们多次使用的模式。该类声明了哪些事物(或哪些类的实例)可以处理。
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
您不应重新定义addProduct。
但是如果气味有所说明,那么也应该提取容量检查中的魔术常数5,并且您应该将产品的验证与添加分开。
我从不喜欢称之为AbstractSomething,这也是一种难闻的气味。在您的情况下,仅使用商店和产品是足够抽象的。