Smalltalk - 在这种情况下如何避免类型攻击?

Ken*_*len 3 smalltalk typechecking object-oriented-analysis

这是一个例子.

假设以下约束:

  • 一家商店只能有5种商品.
  • 食品店只能添加食品.
  • 一家服装店只能添加服装产品.
  • 混合商店可以添加两种产品.

我有以下课程:

  • AbstractShop

    • 食品店
    • 服装店
    • MixedShop
  • 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."
Run Code Online (Sandbox Code Playgroud)

如何避免检查产品类型,看它是否可以添加到商店?我想避免这种情况,因为这是一种难闻的气味.我尝试使用Double Dispatch来解决它,但它似乎使代码更难以维护.

Uko*_*Uko 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
Run Code Online (Sandbox Code Playgroud)

关于你的用例,我会说拥有一系列支持的项目会更好,你可能会有许多商店有不同的项目组合.但是,通过双重发送,您永远不会检查类型.