views:

79

answers:

2

I have a SalesOrder class which is inherited by several different types of sales orders. It has a method called ValidateItems(OrderItemList, itemAdditionalValidation), which takes in a list of order items and a delegate for additional validation on an order item. The different sales orders each define their own version of the delegate and then pass it in when they call ValidateItems of the parent SalesOrder class. The delegate takes in an OrderItem object. OrderItem class has a Validate() method. The ValidateItems method goes through the list and calls Validate on each OrderItem and then calls itemAdditionalValidation delegate and passes it in the OrderItem.

So far, when I wanted to validate items, I would always create add all the items to the respective order and then the order would call ValidateItems and take care of all the validation. However, now I want to be able to call OrderItem.Validate directly without creating an order as well, however I don't know how to refactor the delegate. Basically I want the OrderItem to be able to know which delegates to call based on the Order type it's dealing with. Any ideas? Also any tips on how to improve on my current architecture would be greatly appreciated.

A: 

The specific SalesOrder subclasses each provide an orderItem validator, that is used by the ValidateItems() methoid? If that's a method of SalesOrder then you don't need to pass the additionalValidator as a parameter, you already have it available.

It seems quite reasonable for SalesOrder to also offer a isThisOrderItemValid(item) method. It applies its validator to the supplied item. Or maybe an addOrderItem(item) method which adds it if its valid, but otherwise throws an exception.

Once we treat the validation as owned by SalesOrder then I don't see the problem. The use of delegates or any other technique is an implementaiton detail of the SalesOrder.

djna
Yeah, but I need to be able to validate an order item on its own without putting it into an order. The reason for this is that I have a form which is supposed to validate each row of order item as the customer moves on to the next one, but I don't want it to validate all the order items in the order every time. I only want to validate one order item at a time when it happens.
actually your second paragraph makes good sense. I'll do that!
A: 

I'm not entirely sure if I understand your problem correctly, but just as a guess perhaps you could do something like this:

  • Use marker interfaces to declare what type of OrderItem you are dealing with. So for example, you could have a two different types of OrderItems:

    GoodOrderItemImpl implements GoodOrderItem { }
    BadOrderItemImpl implements BadOrderItem { }
    
  • GoodOrderItem and BadOrderItem interfaces would probably extend the interface OrderItem which actually has the method validate(); defined in it

  • Then you could create some all knowing class that knows what type of additional validator corresponds to the marker interface in question, e.g.

    public final class ValidatorGuru {
        // A map that maps GoodOrderItem.class with GoodOrderValidator and BadOrderItem.class with BadOrderValidator
    }
    
  • Then when you want to validate GoodOrderItemImpl for example, you can use the marker interface to find out that it uses the GoodOrderValidator as its additional validator (i.e. from the ValidatorGuru) and then call goodOrder.validate(); and then goodOrderValidator.validate(goodOrder);

digiarnie