Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: NAV-52 - First throw at defining interfaces for a public transport interface. #19

Merged
merged 5 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/main/java/ch/naviqore/service/ArrivalTime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;

import java.time.LocalDate;

public interface ArrivalTime {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this? LocalDateTime and the variable name arrival or departure time should be sufficient in my opinion.

@NotNull LocalDate getArrivalTime();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we introduce / use this annotation? It gets quite verbose...

Until now we just marked @nullable fields and assumed that fields without annotations are never null.

}
30 changes: 30 additions & 0 deletions src/main/java/ch/naviqore/service/Connection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public interface Connection {
@NotNull List<Leg> getLegs();

@NotNull Location getStartLocation();

@NotNull Location getEndLocation();

@Nullable Stop getStartStop();

@Nullable Stop getEndStop();

@NotNull ArrivalTime getArrivalTime();

@NotNull DepartureTime getDepartureTime();

int getDuration();

int getBeeLineDistance();

int getNumTransfers();

int getWalkingDistance();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ch.naviqore.service;

public interface ConnectionQueryConfiguration {
int getMaximumWalkingDuration();

int getMinimumTransferDuration();

int getMaximumTransferNumber();

int getMaximumTravelTime();
}
9 changes: 9 additions & 0 deletions src/main/java/ch/naviqore/service/DepartureTime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;

import java.time.LocalDate;

public interface DepartureTime {
@NotNull LocalDate getDepartureTime();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I would not wrap a single data type. We can achieve clarity here by using the variable name "departueTime". Or is there a benefit I don't see yet?

}
22 changes: 22 additions & 0 deletions src/main/java/ch/naviqore/service/Leg.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public interface Leg {
@NotNull Location getDepartureLocation();

@NotNull Location getArrivalLocation();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not return the location separately... the location can be retrieved via the stop.getLocation()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A leg can be from a random coordinate to the nearest stop. So there are cases where stop will be null


@Nullable Stop getDepartureStop();

@Nullable Stop getArrivalStop();

@NotNull DepartureTime getDepartureTime();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use normal LocalTime here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mainly an idea to allow method overrides for getConnections() / earliestArrivals() specifying the direction of travel. But this could of course also be moved to the QueryConfig interface.


@NotNull ArrivalTime getArrivalTime();

@Nullable Trip getTrip();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could split Legs in WalkingLeg and RouteLeg? Then have an order Integer which stores the position in the complete connection? Somehow I feel like avoiding nullable fields, which introduce a lot of null checks and potentially NullPointerExceptions?

I not sure yet what the alternative could look like though...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now it's suboptimal but I couldn't think of any other way to handle it. All alternatives will also always require some kind of extra logic.


@Nullable Walk getWalk();
}
7 changes: 7 additions & 0 deletions src/main/java/ch/naviqore/service/Location.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ch.naviqore.service;

public interface Location {
double getLatitude();

double getLongitude();
}
4 changes: 4 additions & 0 deletions src/main/java/ch/naviqore/service/NotFoundException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ch.naviqore.service;

public class NotFoundException extends Exception{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to have checked exception? I think this could be a good way, or we just return nullable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally like custom exceptions, but I'm ok with all approaches. I now in web engineering I received an adverse reaction to having all kinds of custom exceptions, so I'm open to both

}
31 changes: 31 additions & 0 deletions src/main/java/ch/naviqore/service/PublicTransportService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

public interface PublicTransportService {
@NotNull List<StopTime> getNextDepartures(@NotNull Stop stop, @NotNull LocalDate from, @Nullable LocalDate until, int limit);

@NotNull List<Stop> getStops(@NotNull String like, @NotNull SearchType searchType);

@Nullable Stop getClosestStop(@NotNull Location location);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep the wording the consistent: Nearest vs. closest - I would go for nearest 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the interface as lean as possible, I would not force the service implementation to offer methods with default values, since then it is not anymore on the layer of the service to control the default values and every implementation will set their own default. Just enforce the fully specified method with all parameters, we can then set default in the REST API and they will stay the same, independent of the service implementation we use.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do you see a default value?


@NotNull List<Stop> getClosestStops(@NotNull Location location, int searchRadius, int limit);

@NotNull List<Connection> getJourneys(@NotNull Location departureLocation, @NotNull Location arrivalLocation, @NotNull DepartureTime departureTime,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getConnections(...)

ConnectionQueryConfiguration config);

@NotNull List<Connection> getJourneys(@NotNull Location departureLocation, @NotNull Location arrivalLocation, @NotNull ArrivalTime arrivalTime,
ConnectionQueryConfiguration config);

@NotNull Map<Stop, Connection> getShortestPossibleJourneyToStops(@NotNull Location departureLocation, @NotNull DepartureTime departureTime,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the isoline service, if yes, I would suggest naming it isoline(Stop source, LocalDateTime departureTime, ConnectionQueryConfig config);

Should we pass a Location and not a Stop as source?

@Nullable ConnectionQueryConfiguration config);

Stop getStopById(@NotNull String stopId) throws StopNotFoundException;
Trip getTripById(@NotNull String tripId) throws TripNotFoundException;
Route getRouteById(@NotNull String routeId) throws RouteNotFoundException;
}
12 changes: 12 additions & 0 deletions src/main/java/ch/naviqore/service/Route.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;

public interface Route {
@NotNull String getRouteId();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid Route in the method name, it is already clear from the class name :)

@NotNull String getRouteName();
@NotNull String getRouteShortName();
@NotNull String getRouteDescription();
@NotNull String getRouteType();
@NotNull String getAgency();
}
4 changes: 4 additions & 0 deletions src/main/java/ch/naviqore/service/RouteNotFoundException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ch.naviqore.service;

public class RouteNotFoundException extends NotFoundException {
}
8 changes: 8 additions & 0 deletions src/main/java/ch/naviqore/service/SearchType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ch.naviqore.service;

public enum SearchType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool :)

STARTS_WITH,
ENDS_WITH,
CONTAINS,
EXACT
}
8 changes: 8 additions & 0 deletions src/main/java/ch/naviqore/service/Stop.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;

public interface Stop extends Location {
@NotNull String getStopId();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getId()

@NotNull String getName();
}
4 changes: 4 additions & 0 deletions src/main/java/ch/naviqore/service/StopNotFoundException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ch.naviqore.service;

public class StopNotFoundException extends NotFoundException {
}
13 changes: 13 additions & 0 deletions src/main/java/ch/naviqore/service/StopTime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;

public interface StopTime {
@NotNull Trip getTrip();

@NotNull Stop getStop();

@NotNull ArrivalTime getArrivalTime();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LocalDateTime


@NotNull DepartureTime getDepartureTime();
}
17 changes: 17 additions & 0 deletions src/main/java/ch/naviqore/service/Trip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;

import java.util.List;

public interface Trip {
@NotNull String getTripId();

@NotNull Route getRoute();

@NotNull StopTime getStartStop();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is redundant, since information can be retrieved via stop times.


@NotNull StopTime getEndStop();

@NotNull List<StopTime> getStopTimes();
}
4 changes: 4 additions & 0 deletions src/main/java/ch/naviqore/service/TripNotFoundException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ch.naviqore.service;

public class TripNotFoundException extends NotFoundException {
}
18 changes: 18 additions & 0 deletions src/main/java/ch/naviqore/service/Walk.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ch.naviqore.service;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public interface Walk {
@NotNull Location getStart();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant, since can be retrieved via Stop. Except we support walks from random locations to stops. E.g. from an address to the station. But I would keep it simple and extend the interface if we need it.


@NotNull Location getEnd();

@Nullable Stop getStartStop();

@Nullable Stop getEndStop();

int getDistance();

int getDuration();
}
Loading