Quellcode durchsuchen

Refactored creation of Cargo into a CargoFactory.

peter_backlund vor 17 Jahren
Ursprung
Commit
1a71fe0549

+ 12
- 17
dddsample/src/main/java/se/citerus/dddsample/application/impl/BookingServiceImpl.java Datei anzeigen

1
 package se.citerus.dddsample.application.impl;
1
 package se.citerus.dddsample.application.impl;
2
 
2
 
3
+import org.apache.commons.lang.Validate;
3
 import org.apache.commons.logging.Log;
4
 import org.apache.commons.logging.Log;
4
 import org.apache.commons.logging.LogFactory;
5
 import org.apache.commons.logging.LogFactory;
5
 import org.springframework.transaction.annotation.Transactional;
6
 import org.springframework.transaction.annotation.Transactional;
16
 
17
 
17
 public final class BookingServiceImpl implements BookingService {
18
 public final class BookingServiceImpl implements BookingService {
18
 
19
 
20
+  private final RoutingService routingService;
21
+  private final CargoFactory cargoFactory;
19
   private final CargoRepository cargoRepository;
22
   private final CargoRepository cargoRepository;
20
   private final LocationRepository locationRepository;
23
   private final LocationRepository locationRepository;
21
-  private final RoutingService routingService;
22
   private final Log logger = LogFactory.getLog(getClass());
24
   private final Log logger = LogFactory.getLog(getClass());
23
 
25
 
24
-  public BookingServiceImpl(final CargoRepository cargoRepository,
25
-                            final LocationRepository locationRepository,
26
-                            final RoutingService routingService) {
26
+  public BookingServiceImpl(final RoutingService routingService,
27
+                            final CargoFactory cargoFactory,
28
+                            final CargoRepository cargoRepository,
29
+                            final LocationRepository locationRepository) {
30
+    this.routingService = routingService;
31
+    this.cargoFactory = cargoFactory;
27
     this.cargoRepository = cargoRepository;
32
     this.cargoRepository = cargoRepository;
28
     this.locationRepository = locationRepository;
33
     this.locationRepository = locationRepository;
29
-    this.routingService = routingService;
30
   }
34
   }
31
 
35
 
32
   @Override
36
   @Override
34
   public TrackingId bookNewCargo(final UnLocode originUnLocode,
38
   public TrackingId bookNewCargo(final UnLocode originUnLocode,
35
                                  final UnLocode destinationUnLocode,
39
                                  final UnLocode destinationUnLocode,
36
                                  final Date arrivalDeadline) {
40
                                  final Date arrivalDeadline) {
37
-    // TODO modeling this as a cargo factory might be suitable
38
-    final TrackingId trackingId = cargoRepository.nextTrackingId();
39
-    final Location origin = locationRepository.find(originUnLocode);
40
-    final Location destination = locationRepository.find(destinationUnLocode);
41
-    final RouteSpecification routeSpecification = new RouteSpecification(origin, destination, arrivalDeadline);
42
-
43
-    final Cargo cargo = new Cargo(trackingId, routeSpecification);
44
-
41
+    final Cargo cargo = cargoFactory.newCargo(originUnLocode, destinationUnLocode, arrivalDeadline);
45
     cargoRepository.store(cargo);
42
     cargoRepository.store(cargo);
46
     logger.info("Booked new cargo with tracking id " + cargo.trackingId().idString());
43
     logger.info("Booked new cargo with tracking id " + cargo.trackingId().idString());
47
 
44
 
64
   @Transactional
61
   @Transactional
65
   public void assignCargoToRoute(final Itinerary itinerary, final TrackingId trackingId) {
62
   public void assignCargoToRoute(final Itinerary itinerary, final TrackingId trackingId) {
66
     final Cargo cargo = cargoRepository.find(trackingId);
63
     final Cargo cargo = cargoRepository.find(trackingId);
67
-    if (cargo == null) {
68
-      throw new IllegalArgumentException("Can't assign itinerary to non-existing cargo " + trackingId);
69
-    }
70
-
64
+    Validate.notNull(cargo, "Can't assign itinerary to non-existing cargo " + trackingId);
71
     cargo.assignToRoute(itinerary);
65
     cargo.assignToRoute(itinerary);
72
     cargoRepository.store(cargo);
66
     cargoRepository.store(cargo);
73
 
67
 
78
   @Transactional
72
   @Transactional
79
   public void changeDestination(final TrackingId trackingId, final UnLocode unLocode) {
73
   public void changeDestination(final TrackingId trackingId, final UnLocode unLocode) {
80
     final Cargo cargo = cargoRepository.find(trackingId);
74
     final Cargo cargo = cargoRepository.find(trackingId);
75
+    Validate.notNull(cargo, "Can't change destination of non-existing cargo " + trackingId);
81
     final Location newDestination = locationRepository.find(unLocode);
76
     final Location newDestination = locationRepository.find(unLocode);
82
 
77
 
83
     final RouteSpecification routeSpecification = cargo.routeSpecification().withDestination(newDestination);
78
     final RouteSpecification routeSpecification = cargo.routeSpecification().withDestination(newDestination);

+ 34
- 0
dddsample/src/main/java/se/citerus/dddsample/domain/model/cargo/CargoFactory.java Datei anzeigen

1
+/**
2
+ * Purpose
3
+ * @author peter
4
+ * @created 2009-jun-14
5
+ * $Id$
6
+ */
7
+package se.citerus.dddsample.domain.model.cargo;
8
+
9
+import se.citerus.dddsample.domain.model.location.Location;
10
+import se.citerus.dddsample.domain.model.location.LocationRepository;
11
+import se.citerus.dddsample.domain.model.location.UnLocode;
12
+
13
+import java.util.Date;
14
+
15
+public class CargoFactory {
16
+
17
+  private final CargoRepository cargoRepository;
18
+  private final LocationRepository locationRepository;
19
+
20
+  public CargoFactory(CargoRepository cargoRepository, LocationRepository locationRepository) {
21
+    this.cargoRepository = cargoRepository;
22
+    this.locationRepository = locationRepository;
23
+  }
24
+
25
+  public Cargo newCargo(UnLocode originUnLocode, UnLocode destinationUnLocode, Date arrivalDeadline) {
26
+    final TrackingId trackingId = cargoRepository.nextTrackingId();
27
+    final Location origin = locationRepository.find(originUnLocode);
28
+    final Location destination = locationRepository.find(destinationUnLocode);
29
+    final RouteSpecification routeSpecification = new RouteSpecification(origin, destination, arrivalDeadline);
30
+
31
+    return new Cargo(trackingId, routeSpecification);
32
+  }
33
+
34
+}

+ 24
- 7
dddsample/src/main/java/se/citerus/dddsample/domain/model/cargo/RouteSpecification.java Datei anzeigen

57
     return new Date(arrivalDeadline.getTime());
57
     return new Date(arrivalDeadline.getTime());
58
   }
58
   }
59
 
59
 
60
+  /**
61
+   * @param newDestination destination of new route specification
62
+   * @return A copy of this route specification but with new destination
63
+   */
64
+  public RouteSpecification withDestination(Location newDestination) {
65
+	  return new RouteSpecification(origin, newDestination, arrivalDeadline);
66
+  }
67
+
68
+  /**
69
+   * @param newOrigin origin of new route specification
70
+   * @return A copy of this route specification but with the new origin
71
+   */
72
+  public RouteSpecification withOrigin(Location newOrigin) {
73
+    return new RouteSpecification(newOrigin, destination, arrivalDeadline);
74
+  }
75
+
76
+  /**
77
+   * @param newArrivalDeadline arrival deadline of new route specification
78
+   * @return A copy of this route specification but with the new arrival deadline
79
+   */
80
+  public RouteSpecification withArrivalDeadline(Date newArrivalDeadline) {
81
+    return new RouteSpecification(origin, destination, newArrivalDeadline);
82
+  }
83
+
60
   @Override
84
   @Override
61
   public boolean isSatisfiedBy(final Itinerary itinerary) {
85
   public boolean isSatisfiedBy(final Itinerary itinerary) {
62
     return itinerary != null &&
86
     return itinerary != null &&
96
   RouteSpecification() {
120
   RouteSpecification() {
97
     // Needed by Hibernate
121
     // Needed by Hibernate
98
   }
122
   }
99
-
100
-public RouteSpecification withDestination(Location newDestination) {
101
-
102
-	return new RouteSpecification(origin, newDestination, arrivalDeadline);
103
-	
104
-}
105
-  
106
 }
123
 }

+ 29
- 29
dddsample/src/main/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingViewAdapter.java Datei anzeigen

57
   }
57
   }
58
 
58
 
59
   /**
59
   /**
60
-   * @return A translated string describing the cargo status. 
60
+   * @return A translated string describing the cargo status.
61
    */
61
    */
62
   public String getStatusText() {
62
   public String getStatusText() {
63
     final Delivery delivery = cargo.delivery();
63
     final Delivery delivery = cargo.delivery();
66
     final Object[] args;
66
     final Object[] args;
67
     switch (delivery.transportStatus()) {
67
     switch (delivery.transportStatus()) {
68
       case IN_PORT:
68
       case IN_PORT:
69
-        args = new Object[] {getDisplayText(delivery.lastKnownLocation())};
69
+        args = new Object[]{getDisplayText(delivery.lastKnownLocation())};
70
         break;
70
         break;
71
       case ONBOARD_CARRIER:
71
       case ONBOARD_CARRIER:
72
-        args = new Object[] {delivery.currentVoyage().voyageNumber().idString()};
72
+        args = new Object[]{delivery.currentVoyage().voyageNumber().idString()};
73
         break;
73
         break;
74
       case CLAIMED:
74
       case CLAIMED:
75
       case NOT_RECEIVED:
75
       case NOT_RECEIVED:
78
         args = null;
78
         args = null;
79
         break;
79
         break;
80
     }
80
     }
81
-    
81
+
82
     return messageSource.getMessage(code, args, "[Unknown status]", locale);
82
     return messageSource.getMessage(code, args, "[Unknown status]", locale);
83
   }
83
   }
84
 
84
 
107
     Date eta = cargo.delivery().estimatedTimeOfArrival();
107
     Date eta = cargo.delivery().estimatedTimeOfArrival();
108
 
108
 
109
     if (eta == null) return "?";
109
     if (eta == null) return "?";
110
-	else {
111
-		Location destination = cargo.routeSpecification().destination();
112
-		SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);
113
-		dateFormat.setTimeZone(destination.timeZone());
114
-		return dateFormat.format(eta);
115
-	}
110
+    else {
111
+      Location destination = cargo.routeSpecification().destination();
112
+      SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);
113
+      dateFormat.setTimeZone(destination.timeZone());
114
+      return dateFormat.format(eta);
115
+    }
116
   }
116
   }
117
 
117
 
118
   public String getNextExpectedActivity() {
118
   public String getNextExpectedActivity() {
119
-      HandlingActivity activity = cargo.delivery().nextExpectedActivity();
120
-      if (activity == null) {
121
-        return "";
122
-      }
119
+    HandlingActivity activity = cargo.delivery().nextExpectedActivity();
120
+    if (activity == null) {
121
+      return "";
122
+    }
123
 
123
 
124
     String text = "Next expected activity is to ";
124
     String text = "Next expected activity is to ";
125
     HandlingEvent.Type type = activity.type();
125
     HandlingEvent.Type type = activity.type();
126
     if (type.sameValueAs(HandlingEvent.Type.LOAD)) {
126
     if (type.sameValueAs(HandlingEvent.Type.LOAD)) {
127
-        return
128
-          text + type.name().toLowerCase() + " cargo onto voyage " + activity.voyage().voyageNumber() +
127
+      return
128
+        text + type.name().toLowerCase() + " cargo onto voyage " + activity.voyage().voyageNumber() +
129
           " in " + activity.location().name();
129
           " in " + activity.location().name();
130
-      } else if (type.sameValueAs(HandlingEvent.Type.UNLOAD)) {
131
-        return
132
-          text + type.name().toLowerCase() + " cargo off of " + activity.voyage().voyageNumber() +
130
+    } else if (type.sameValueAs(HandlingEvent.Type.UNLOAD)) {
131
+      return
132
+        text + type.name().toLowerCase() + " cargo off of " + activity.voyage().voyageNumber() +
133
           " in " + activity.location().name();
133
           " in " + activity.location().name();
134
-      } else {
135
-        return text + type.name().toLowerCase() + " cargo in " + activity.location().name();
136
-      }
134
+    } else {
135
+      return text + type.name().toLowerCase() + " cargo in " + activity.location().name();
136
+    }
137
   }
137
   }
138
 
138
 
139
   /**
139
   /**
170
      * @return Time when the event was completed.
170
      * @return Time when the event was completed.
171
      */
171
      */
172
     public String getTime() {
172
     public String getTime() {
173
-		SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);
174
-		dateFormat.setTimeZone(handlingEvent.location().timeZone());
173
+      SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT);
174
+      dateFormat.setTimeZone(handlingEvent.location().timeZone());
175
 
175
 
176
       return dateFormat.format(handlingEvent.completionTime());
176
       return dateFormat.format(handlingEvent.completionTime());
177
     }
177
     }
204
       switch (handlingEvent.type()) {
204
       switch (handlingEvent.type()) {
205
         case LOAD:
205
         case LOAD:
206
         case UNLOAD:
206
         case UNLOAD:
207
-          args = new Object[] {
207
+          args = new Object[]{
208
             handlingEvent.voyage().voyageNumber().idString(),
208
             handlingEvent.voyage().voyageNumber().idString(),
209
             handlingEvent.location().name(),
209
             handlingEvent.location().name(),
210
             handlingEvent.completionTime()
210
             handlingEvent.completionTime()
213
 
213
 
214
         case RECEIVE:
214
         case RECEIVE:
215
         case CLAIM:
215
         case CLAIM:
216
-          args = new Object[] {
216
+          args = new Object[]{
217
             handlingEvent.location().name(),
217
             handlingEvent.location().name(),
218
             handlingEvent.completionTime()
218
             handlingEvent.completionTime()
219
           };
219
           };
220
           break;
220
           break;
221
 
221
 
222
         default:
222
         default:
223
-          args = new Object[] {};
223
+          args = new Object[]{};
224
       }
224
       }
225
 
225
 
226
       String key = "deliveryHistory.eventDescription." + handlingEvent.type().name();
226
       String key = "deliveryHistory.eventDescription." + handlingEvent.type().name();
227
 
227
 
228
-      return messageSource.getMessage(key,args,locale);
228
+      return messageSource.getMessage(key, args, locale);
229
     }
229
     }
230
 
230
 
231
   }
231
   }
232
-  
232
+
233
 }
233
 }

+ 2
- 1
dddsample/src/main/resources/context-application.xml Datei anzeigen

5
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
5
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
6
 
6
 
7
   <bean id="bookingService" class="se.citerus.dddsample.application.impl.BookingServiceImpl">
7
   <bean id="bookingService" class="se.citerus.dddsample.application.impl.BookingServiceImpl">
8
+    <constructor-arg ref="cargoFactory"/>
9
+    <constructor-arg ref="routingService"/>
8
     <constructor-arg ref="cargoRepository"/>
10
     <constructor-arg ref="cargoRepository"/>
9
     <constructor-arg ref="locationRepository"/>
11
     <constructor-arg ref="locationRepository"/>
10
-    <constructor-arg ref="routingService"/>
11
   </bean>
12
   </bean>
12
 
13
 
13
   <bean id="cargoInspectionService" class="se.citerus.dddsample.application.impl.CargoInspectionServiceImpl">
14
   <bean id="cargoInspectionService" class="se.citerus.dddsample.application.impl.CargoInspectionServiceImpl">

+ 5
- 0
dddsample/src/main/resources/context-domain.xml Datei anzeigen

10
     <constructor-arg ref="locationRepository"/>
10
     <constructor-arg ref="locationRepository"/>
11
   </bean>
11
   </bean>
12
 
12
 
13
+  <bean id="cargoFactory" class="se.citerus.dddsample.domain.model.cargo.CargoFactory">
14
+    <constructor-arg ref="cargoRepository"/>
15
+    <constructor-arg ref="locationRepository"/>
16
+  </bean>
17
+
13
 </beans>
18
 </beans>

+ 2
- 1
dddsample/src/test/java/se/citerus/dddsample/application/BookingServiceTest.java Datei anzeigen

4
 import static org.easymock.EasyMock.*;
4
 import static org.easymock.EasyMock.*;
5
 import se.citerus.dddsample.application.impl.BookingServiceImpl;
5
 import se.citerus.dddsample.application.impl.BookingServiceImpl;
6
 import se.citerus.dddsample.domain.model.cargo.Cargo;
6
 import se.citerus.dddsample.domain.model.cargo.Cargo;
7
+import se.citerus.dddsample.domain.model.cargo.CargoFactory;
7
 import se.citerus.dddsample.domain.model.cargo.CargoRepository;
8
 import se.citerus.dddsample.domain.model.cargo.CargoRepository;
8
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
9
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
9
 import se.citerus.dddsample.domain.model.location.LocationRepository;
10
 import se.citerus.dddsample.domain.model.location.LocationRepository;
25
     cargoRepository = createMock(CargoRepository.class);
26
     cargoRepository = createMock(CargoRepository.class);
26
     locationRepository = createMock(LocationRepository.class);
27
     locationRepository = createMock(LocationRepository.class);
27
     routingService = createMock(RoutingService.class);
28
     routingService = createMock(RoutingService.class);
28
-    bookingService = new BookingServiceImpl(cargoRepository, locationRepository, routingService);
29
+    bookingService = new BookingServiceImpl(routingService, new CargoFactory(cargoRepository, locationRepository), cargoRepository, locationRepository);
29
   }
30
   }
30
 
31
 
31
   public void testRegisterNew() {
32
   public void testRegisterNew() {