Smalltalk - 在这种情况下如何避免类型检查?
Smalltalk - How to avoid typechecks in this situation?
这是一个例子。
假设以下约束:
- 一个店铺只能有5件商品。
- 食品店只能添加食品。
- 服装店只能添加服装商品。
- 混合商店可以添加两种产品。
我有以下 类:
抽象商店
- 食品店
- 服装店
- 综合店
抽象产品
- 服装
- 食物
功能:
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 解决这个问题,但它似乎使代码更难维护。
这是我们多次使用的模式。 class 声明哪些事物(或 classes 的实例)可以处理。
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 也应该被提取出来,并且你应该将产品的验证与添加分开。
我从来不喜欢称呼 class AbstractSomething,那也是一种难闻的气味。在您的情况下,仅使用 Shop 和 Product 就足够抽象了。
你也可以使用双重分派来做到这一点:
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
关于您的用例,我认为最好有一组受支持的商品,因为您可能有许多商店具有不同的商品组合。但是使用双重分派你永远不会检查类型。
这是一个例子。
假设以下约束:
- 一个店铺只能有5件商品。
- 食品店只能添加食品。
- 服装店只能添加服装商品。
- 混合商店可以添加两种产品。
我有以下 类:
抽象商店
- 食品店
- 服装店
- 综合店
抽象产品
- 服装
- 食物
功能:
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 解决这个问题,但它似乎使代码更难维护。
这是我们多次使用的模式。 class 声明哪些事物(或 classes 的实例)可以处理。
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 也应该被提取出来,并且你应该将产品的验证与添加分开。
我从来不喜欢称呼 class AbstractSomething,那也是一种难闻的气味。在您的情况下,仅使用 Shop 和 Product 就足够抽象了。
你也可以使用双重分派来做到这一点:
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
关于您的用例,我认为最好有一组受支持的商品,因为您可能有许多商店具有不同的商品组合。但是使用双重分派你永远不会检查类型。