Как я могу разрешить конфликт между слабой связью / внедрение зависимости и богатой моделью предметной области?

Я не уверен, будет ли это работать вообще, это не проверено, но, может быть, оно приведет вас в правильном направлении? Итак, вот мои 2 цента

withSplash.js

const withSplash = MyAppComponent => 
  class extends React.Component {
    state = {
      showSplash: true
    }

    componentDidMount () {
      handleSplashComponent(); 
    }

    componentWillUnmount () {
      if (this.timer) {
        this.timer = null;
      }
    }

    handleSplashComponent = () => {
      this.timer = setTimeout(()=> {
        this.setState({
          showSplash: false
        })
      }, 3000)
    }

    render () {
      return this.state.showSplash
        ? <SplashComponent />
        : <MyAppComponent />
    }
  }

App.js

class App extends Component {
  ...
}

export default withSplash(App);

[119 ] AnotherComponent.js

class AnotherComponent extends Component {
  ...
}

export default withSplash(AnotherComponent);
16
задан Robert Campbell 30 March 2009 в 09:47
поделиться

6 ответов

Я нашел ответ, по крайней мере, для тех, кто использует Spring:

6.8.1. Использование AspectJ для добавления зависимостей в доменные объекты с помощью Spring

2
ответ дан 30 November 2019 в 23:18
поделиться

Regardinig

Что если ваш ордер нужно отправить электронное письмо каждый раз, когда итог рассчитывается?

Я бы использовал события.
Если он имеет какое-то значение для вас, когда заказ вычисляет его общую сумму, позвольте ему вызвать событие как eventDispatcher.raiseEvent (new ComputedTotalEvent (this)).
Затем вы прослушиваете события такого типа и отзываете свой заказ, как было сказано выше, чтобы он смог отформатировать шаблон электронной почты, и отправляете его.
Ваши доменные объекты остаются худыми, не зная об этом вашем требовании.
Короче говоря, разбейте вашу проблему на 2 требования:
- Я хочу знать, когда заказ вычисляет его общую сумму;
- Я хочу отправить электронное письмо, когда заказ имеет (новый и другой) итог;

2
ответ дан 30 November 2019 в 23:18
поделиться

Я рисковал бы сказать, что существует много оттенков серого между наличием "анемичной модели предметной области" и зубрежкой все Ваши сервисы в Ваши объекты области. И довольно часто, по крайней мере, в бизнес-доменах и по моему опыту, объект мог бы на самом деле быть не чем иным как просто данными; например, каждый раз, когда операции, которые могут быть выполнены на том конкретном объекте, зависят от множества других объектов и некоторого локализованного контекста, говорят адрес, например.

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

Рассмотрите старый пример Заказов и OrderItems. "Анемичная" модель предметной области посмотрела бы что-то как:

class Order {
    Long orderId;
    Date orderDate;
    Long receivedById;  // user which received the order
 }

 class OrderItem {
     Long orderId;      // order to which this item belongs
     Long productId;    // product id
     BigDecimal amount;
     BigDecimal price;
 }

По-моему, точка управляемого доменом дизайна должна использовать классы для лучше моделирования отношений между объектами. Так, неанемичная модель посмотрела бы что-то как:

class Order {
   Long orderId;
   Date orderDate;
   User receivedBy;
   Set<OrderItem> items;
}

class OrderItem {
   Order order;
   Product product;
   BigDecimal amount;
   BigDecimal price;
}

Предположительно, Вы использовали бы решение ORM сделать отображение здесь. В этой модели Вы смогли бы записать метод такой как Order.calculateTotal(), это подвело бы итог весь amount*price для каждого объекта порядка.

Так, модель была бы богата, в некотором смысле что операции, которые имеют смысл с бизнес-точки зрения, как calculateTotal, был бы помещен в Order объект области. Но по крайней мере по моему мнению, управляемый доменом дизайн не означает что Order должен знать о Ваших сервисах персистентности. Это должно быть сделано в отдельном и независимом слое. Операции персистентности не являются частью бизнес-домена, они - часть реализации.

И даже в этом простом примере, существует много ловушек для рассмотрения. Если все Product будьте загружены каждым OrderItem? Если существует огромное количество объектов порядка, и Вам нужен сводный отчет для огромного количества заказов, был бы Вы использовать Java, загружаемые объекты в памяти и вызове calculateTotal() на каждом порядке? Или SQL-запрос намного лучшее решение, от каждого аспекта. Именно поэтому достойному решению ORM нравится, в спящем режиме, механизмы предложений для решения точно подобных практических проблем: ленивая загрузка с прокси для первого и HQL для последнего. Какова хороший была бы теоретически звуковая модель быть, если поколение отчета берет возрасты?

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

Править: Оценка PriceQuery сервис и пример отправки электронного письма после общего количества были вычислены, я сделаю различие между:

  1. то, что электронное письмо должно быть послано после калькуляции цен
  2. какая часть порядка должна быть отправлена? (это могло также включать, скажем, почтовые шаблоны),
  3. фактический метод отправки электронного письма

Кроме того, нужно задаться вопросом, отправляет электронного письма свойственную способность Order, или еще одна вещь, которая может быть сделана с ним, как сохранение его, сериализация к различным форматам (XML, CSV, Excel) и т.д.

Что я сделал бы, и что я полагаю, что хороший подход ООП следующий. Определите инкапсуляцию интерфейса операции подготовки и отправки электронного письма:

 interface EmailSender {
     public void setSubject(String subject);
     public void addRecipient(String address, RecipientType type);
     public void setMessageBody(String body);
     public void send();
 }

Теперь, внутри Order класс, определите операцию, которой порядок "знает", как отправить себя как электронное письмо, с помощью почтового отправителя:

class Order {
...
    public void sendTotalEmail(EmailSender sender) {
        sender.setSubject("Order " + this.orderId);
        sender.addRecipient(receivedBy.getEmailAddress(), RecipientType.TO);
        sender.addRecipient(receivedBy.getSupervisor().getEmailAddress(), RecipientType.BCC);
        sender.setMessageBody("Order total is: " + calculateTotal());
        sender.send();
    }

Наконец, у Вас должен быть фасад к Вашей работе приложения, точка, где фактический ответ на пользовательское действие происходит. По-моему, это - то, где необходимо получить (Spring DI) фактическую реализацию сервисов. Это может, например, быть Spring MVC Controller класс:

public class OrderEmailController extends BaseFormController {
   // injected by Spring
   private OrderManager orderManager;  // persistence
   private EmailSender emailSender;    // actual sending of email

public ModelAndView processFormSubmission(HttpServletRequest request,
                                          HttpServletResponse response, ...) {
    String id = request.getParameter("id");
    Order order = orderManager.getOrder(id);
    order.sendTotalEmail(emailSender);

    return new ModelAndView(...);
}

Вот то, что Вы получаете с этим подходом:

  1. объекты области не содержат сервисы, они используют их
  2. объекты области отделяются от реализации практической эксплуатации (например, SMTP, отправляющий в отдельном потоке и т.д.), природой интерфейсного механизма
  3. сервисные интерфейсы являются универсальными, допускающими повторное использование, но не знают ни о каких фактических объектах области. Например, если порядок получает дополнительное поле, Вы должны измениться только Order класс.
  4. можно дразнить сервисы легко и протестировать объекты области легко
  5. можно протестировать реализации практической эксплуатации легко

Я не знаю, ли это по стандартам определенных гуру, но этого практичный подход, который работает обоснованно хорошо на практике.

4
ответ дан 30 November 2019 в 23:18
поделиться

Самый простой подход, что я могу думать, должен добавить некоторую логику на Ваш уровень доступа к данным, который введет объект области с его зависимостями прежде, чем возвратить его более высокому слою (обычно названный уровнем служб). Вы могли аннотировать свойства каждого класса для указания что потребности быть обеспеченными электричеством. Если Вы не находитесь на Java 5 +, Вы могли бы реализовать интерфейс для каждого компонента, который должен быть введен или даже объявить это все в XML и канале, что данные к контексту, который сделает проводное соединение. Если бы Вы хотели стать необычными, то Вы могли бы вытащить это в аспект и применить его глобально через Ваш уровень доступа к данным так все методы, которые выходят, объекты области обеспечат электричеством их сразу после того, как они будут возвращены.

1
ответ дан 30 November 2019 в 23:18
поделиться

Возможно, то, что Вы хотите, является видом на ссылочном объекте, который сериализировал бы как глобальная ссылка (URI, например), и это сможет возродиться как прокси когда десериализованный в другом месте.

0
ответ дан 30 November 2019 в 23:18
поделиться

Шаблон Карты Идентификационных данных может помочь с Вашим сценарием. Проверьте статью Patterns In Practice, записанную Jeremy Miller, где он обсуждает об этом шаблоне.

0
ответ дан 30 November 2019 в 23:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: