2009-11-16 2 views
1

У меня есть класс SalesOrder, который наследуется несколькими различными типами заказов на продажу. Он имеет метод под названием ValidateItems (OrderItemList, itemAdditionalValidation), который принимает список элементов заказа и делегат для дополнительной проверки в позиции заказа. Различные заказы клиента определяют собственную версию делегата, а затем передают его, когда они вызывают ValidateItems родительского класса SalesOrder. Делегат принимает объект OrderItem. Класс OrderItem имеет метод Validate(). Метод ValidateItems проходит через список и вызывает проверку на каждый OrderItem, а затем вызывает делегат itemAdditionalValidation и передает его в OrderItem.Рефакторинг некоторых из моего кода

До сих пор, когда я хотел проверить элементы, я всегда создавал бы добавление всех элементов в соответствующий заказ, а затем заказ вызывал бы ValidateItems и заботился обо всех проверках. Однако теперь я хочу иметь возможность напрямую вызвать OrderItem.Validate, не создавая при этом порядок, однако я не знаю, как реорганизовать делегат. В основном я хочу, чтобы OrderItem мог знать, какие делегаты должны звонить на основе типа заказа, с которым он имеет дело. Есть идеи? Также будут с благодарностью оценены любые советы о том, как улучшить мою текущую архитектуру.

ответ

0

Конкретные подклассы SalesOrder каждый предоставляют валидатор orderItem, который используется методе ValidateItems()? Если это метод SalesOrder, вам не нужно передавать дополнительныйValidator в качестве параметра, у вас уже есть его.

Похоже, что SalesOrder также предлагает метод isThisOrderItemValid (item). Он применяет свой валидатор к поставляемому элементу. Или, может быть, метод addOrderItem (item), который добавляет его, если он действителен, но в противном случае создает исключение.

Как только мы рассматриваем валидацию как принадлежащую SalesOrder, я не вижу проблемы. Использование делегатов или любой другой техники - это реализация детали SalesOrder.

+0

Да, но мне нужно иметь возможность самостоятельно проверить элемент заказа, не введя его в порядок. Причина этого в том, что у меня есть форма, которая должна проверять каждую строку элемента заказа, когда клиент переходит к следующему, но я не хочу, чтобы он каждый раз проверял все позиции заказа в заказе. Я только хочу проверить один элемент заказа в тот момент, когда это произойдет. – Riz

+0

На самом деле ваш второй абзац имеет смысл. Я это сделаю! – Riz

0

Я не совсем уверен, если я понимаю вашу проблему правильно, но только как предположение, возможно, вы могли бы сделать что-то вроде этого:

  • Используйте маркер интерфейсов объявить, какой тип OrderItem вы имеете дело с , Так, например, вы можете иметь два различных типа ТоварыЗаказа:

    GoodOrderItemImpl implements GoodOrderItem { } 
    BadOrderItemImpl implements BadOrderItem { } 
    
  • GoodOrderItem и BadOrderItem интерфейсы, вероятно, расширяющие интерфейс OrderItem, который на самом деле имеет метод Validate(); определяемый в нем

  • Затем вы можете создать класс знаний, который знает, какой тип дополнительного валидатора соответствует рассматриваемому интерфейсу маркера, например.

    public final class ValidatorGuru { 
        // A map that maps GoodOrderItem.class with GoodOrderValidator and BadOrderItem.class with BadOrderValidator 
    } 
    
  • Затем, когда вы хотите проверить GoodOrderItemImpl, например, вы можете использовать интерфейс маркер, чтобы узнать, что он использует GoodOrderValidator в качестве дополнительной проверки подлинности (т.е. от ValidatorGuru), а затем вызвать goodOrder.validate() ; а затем goodOrderValidator.validate (goodOrder);