Observer pattern: notify with state - java

The examples I've seen on the internet only give notifyObservers() method to the Observable object. What if I want to also pass some data to the observers, so that they know if they should react to it or not? Does the observer pattern allow passing the data like maybe:
notifyObservers(Event e).
Or maybe the observers themselves should pull the change? Like maybe:
notifyObservers() -> call observer.update()
and then each observer decides if the new data is relevant for them, observable.getData(). However with this approach, it is unclear to me, how to get only the data that has changes, if it's at all needed.
Edit, example:
Say I want to make a taxi firm with operators, clients and taxi. As per #Pritam Banerjee's answer, I will say that taxi firm is a mediator between operators and clients (e.g. why - client can call for a taxi by phone, or online). Then my operators are subjects, and taxis are observers.
Operator ---observes---> TaxiFirm
TaxiFirm(waits for client) ---notifies one---> Operator (firm selects which operator is responsible, and passes a client to operator)
Taxi ---observes all---> Operators (need to somehow push data here, if the taxi is occupied, it can't accept new client)
Taxi ---notifies---> Operator (if taxi can accept a client it will notify operator about it, I am not concerned about any race conditions, because this event will be triggered manually. Also, maybe Taxi should notify the Firm and not operator?)
I think it's possible that TaxiFirm doesn't need to pass client to operator, but thinking about real life, it's really operators who speak to clients...
I've written down my thought process, please help me with figuring out the architecture for this model.

Of course the ObserverPattern allows you to pass information through its notify method. If a taxi needs the client info you can just pass:
observer.notify(ClientInfo info)
And of course the Observers could, instead, request the info:
observer.notify()
void notify() {
update();
}
Both are possible, but then, I would NOT say you really have the ObserverPattern here. According to this pattern, the Subject simply notifies all Observers. But what you described is that the Subject should notify one of the taxis, wait for its response (if the taxi is already carrying a passenger), and then possibly notify the next taxi. You could call that a variation of the ObserverPattern, but it's different.
A simple suggestion, for you to get started:
class Operator:
List<Taxi> taxis;
boolean chooseTaxi(RideNumber rideNumber) {
for (Taxi taxi : taxis) {
boolean isAccepted = taxi.notify(this, rideNumber);
if (isAccepted) {
markTaxiRideAsAccepted(taxi, rideNumber);
return true;
}
}
return false; // No taxi accepted the ride.
}
class Taxi:
boolean notify(Operator operator, RideNumber rideNumber) {
if (isTaxiAlreadyCarryingPassenger()) return false;
ClientInfo clientInfo = operator.getClientInfo(this, rideNumber);
startClientProcess(clientInfo);
return true;
}
Note: The RideNumber is just an identification number that the taxi later uses to request the client info from the operator. You could instead send the clientInfo through the notify method, but then all taxis would get this info, which is terrible for security, and could also be confusing (sending information which should not be used).
Update:
If this is a homework assignment, and you must use the exact ObserverPattern, you can do this:
class Operator:
List<Taxi> taxis;
void notifyAllTaxis(RideNumber rideNumber) {
for (Taxi taxi : taxis) {
taxi.notify(this, rideNumber);
}
}
}
ClientInfo getClientInfo(this, rideNumber) {
if (isRideNotYetAccepted(rideNumber)) {
markRideAsAccepted(taxi, rideNumber);
return getClientInfo(rideNumber);
}
else return null;
}
class Taxi:
void notify(Operator operator, RideNumber rideNumber) {
if (!isTaxiAlreadyCarryingPassenger()) {
ClientInfo clientInfo = operator.getClientInfo(this, rideNumber);
if (clientInfo != null) startClientProcess(clientInfo);
}
}

You can use Observer Design Pattern with Mediator Pattern so that the application can also subscribe and publish data to the other related applications.
For an example of this you can look over here.
For more details on Mediator Design Patterns you can read this article.

Related

Which state machine design to use if your target state is not the next one?

I've been reading up on State Machines since its likely I need to use for my next project. Most examples I find online show how to go from StateA to StateB. But what if your next desired state is not an adjacent state? Are there any common patterns/practices to achieve this? Ideally in Java, but I can read other programming languages just as well.
# Example States
WakeUp->Get Dressed->Get Car Keys->Get in Car->Drive to Work->Work
Current State: Get in Car
Problems to solve
# Scenario 1: Desired State == Work
Forgot car keys, so you have to return to previous state and then move forward in states again.
# Scenario 2: Desired State == Work
Have car keys, so move forward in states to get to Desired State.
It's very likely that State Machine may not solve this problem elegantly and I just need to hand-craft the logic, I don't mind, but thought I'd follow a common design pattern to help others understand it.
From the example above, I do not need to worry about 'internal' states, which is also true for the project I'm tackling; just in case that makes a difference in possible solutions.
Here is a simple way to define a state machine.
Define in an enum all the states that you want.
enum StateType {
WAKE_UP, GET_DRESSED, GET_CAR_KEYS, GET_IN_CAR, DRIVE_TO_WORK, WORK
}
Have a statemachine which controls states, and a state interface which performs an action on the statemachine. The state then returns the next state to go to.
interface State {
StateType next(StateMachine sm);
}
Implement this state for multiple types
class GetInCarState implements State {
#Override
public StateType next(StateMachine sm) {
if (sm.hasKeys()) {
return StateType.DRIVE_TO_WORK;
}
return StateType.GET_CAR_KEYS;
}
}
Now define the State Machine
class StateMachine {
private Map<StateType, State> states = new HashMap<StateType, State>() {{
put(StateType.WAKE_UP, new WakeUpState());
put(StateType.GET_DRESSED, new GetDressedState());
put(StateType.GET_CAR_KEYS, new GetCarKeysState());
put(StateType.GET_IN_CAR, new GetInCarState());
put(StateType.DRIVE_TO_WORK, new DriveToWorkState());
put(StateType.WORK, new WorkState());
}};
private StateType currentState = StateType.WAKE_UP;
private boolean hasCarKeys;
public boolean hasKeys() {
return hasCarKeys;
}
public void setHasKeys(boolean hasKeys) {
hasCarKeys = hasKeys;
}
public void update() {
currentState = states.get(currentState).next(this);
}
}

Java 8 Stateful consumer

Is conditional composition of Consumers possible in Java 8? Basically I'm looking to create a custom Lambda interface similar to Consumer but that only works with one type of object. Let's call it, Stateful and it contains multiple statuses (we'll say two for the purpose of this example):
public class Stateful {
private int status1;
private int status2;
}
We have a lot of areas in our code where we do an operation on a Stateful and, if the status has changed, we would do another operation. I was wondering if we could use composition to handle this in a more compact and elegant manner. Right now we would do something like:
SimpleEntry<Integer, Integer> oldStates = new SimpleEntry(stateful.getStatus1(), stateful.getStatus2());
applyLogicOnStateful(stateful); //do some operation that may change state values
if(isStatusChanged(oldStates, stateful) { //compare oldStates integers to status integers
doSomethingElse(stateful);
}
where I think something like this would look better:
statefulConsumer
.accept((stateful)->applyLogicOnStateful(stateful))
.ifStatusChanged((stateful)->doSomethingElse(stateful));
but I don't know if we would be able to track the change in status from before the first consumer to after. Maybe I need to create a lambda that takes two consumers as input?
I'm definitely looking to do this without the assistance of a 3rd party library, although you're welcome to promote one here if it is helpful.
Here is a function that will return a Consumer<Stateful> that will extract the former state, do the change, compare results, and conditionally operate on the changed object.
public static Consumer<Stateful> getStatefulConsumer(
Function<Stateful,SimpleEntry<Integer,Integer>> getStatus, // extract status from Stateful
Consumer<Stateful> applyLogic, // apply business logic
BiPredicate<SimpleEntry<Integer,Integer>,SimpleEntry<Integer,Integer>> compareState, // test statuses for change
Consumer<Stateful> onChange) // doSomethingElse
{
return stateful -> {
SimpleEntry<Integer,Integer> oldStatus = getStatus.apply(stateful);
applyLogic.accept(stateful);
if(!compareState.test(oldStatus, getStatus.apply(stateful))){
onChange.accept(stateful);
}
};
}
You might use it like this:
Consumer<Stateful> ifChanged = getStatefulConsumer(s -> new SimpleEntry<> ( s.status1, s.status2 ),
s -> changeSomething(s), Objects::equals, s->doSomething(s));
You could generify the extracted status so that different stateful types could have different extracted status types, or even use Stateful::clone to copy the status.
The solution I am working with right now is to create a Lambda interface that takes the Stateful instance and two Consumers as input:
public interface StatefulConsumer {
void accept(Stateful stateful, Consumer<Stateful> consumer, Consumer<Stateful> ifStateChangedConsumer);
}
and an implementation:
final StatefulConsumer IfStateChanges = new StatefulConsumer() {
#Override
public void accept(Stateful stateful, Consumer<Stateful> consumer, Consumer<Stateful> ifStateChangedConsumer) {
SimpleEntry<Integer, Integer> oldStates = new SimpleEntry(stateful.getStatus1(), stateful.getStatus2());
consumer.accept(stateful); //do some operation that may change state values
if(isStatusChanged(oldStates, stateful) { //compare oldStates integers to status integers
ifStateChangedConsumer.accept(stateful);
}
}
};
which could be called like this:
IfStateChanges.accept(stateful,
(Stateful s)->applyLogicOnStateful(stateful),
(Stateful s)->doSomethingElse(stateful))
It could also be implemented as a Predicate or a Function that takes a stateful and a consumer as input and returns a boolean for use in an if Statement

ArrayList concurrency across socket connections

I have an issue. My belief is that is has something to do with concurrency or synchronization of threads, though I cannot put the finger on just what is happening.
Here is my description of the data-flow for our FriendRequestList object.
From the client side we send a friend request to another user(worker).
So we send the request and add our own username to their User.incFriendReq-list. The instance is an ArrayList just for nice-to-have reference.
So now we send the request to the server to receive our own list of friend requests (FriendRequestList.java).
So now the problem. If I use this code below the user won't see the friend request before he terminates his connection (logout), which will close the connection. When he logs in, he will only then see the request in his list.
Server side code:
... Worker.java ...
private Object getFriendRequests() {
User me = Data.getUser(myUserName);
if ( me == null ) {
return new NoSuchUserException(); // Don't worry about it ;)
}
return new FriendRequestList(me.getFriendReq());
}
... User.java ...
private List<String> incFriendReq;
public List<String> getFriendReq() {
return incFriendReq;
}
Client side
... Communication.java ...
public FriendRequestList getRequests() {
sendObject(new GetRequests());
return inputHandler.containsRequests();
}
... MessageListener.java ...
public void run() {
...
FriendRequestList requests = communication.getRequests();
update(requestList, requests);
// Here we have the problem. requests.size is never different from 0
}
How ever, if I update Worker.java to do this instead:
private Object getFriendRequests() {
User me = Data.getUser(myUserName);
if ( me == null ) {
return new NoSuchUserException();
}
return new FriendList(me.getFriends().stream().collect(Collectors.toList()));
}
The instant the other user requests my friendship, I see the request on my list.
What gives? This sounds to me like the underlying datastructure is not updated, race conditions or something.
But the fix is how I retrieve the data on the server side, by using a stream.
Please someone explain and also how this would be done in Java 7 before streams would solve my, to me, curious problem.
On a note
I want to add that the users are placed inside an LinkedBlockingDeque and retrieve from the Data object, a shared resource for the workers.
Looks to me like returning the incFriendReq list directly in getFriendReq is one of the sources of your problem. When you use java 8 and stream that list into a new list, you are just making a copy, so there is no useful addition. If this is the case, your server-side code should also work then by using new ArrayList<>(me.getFriends()).
I would verify that all accesses to the list are properly synchronized and that you know where and when that list is being mutated.

Web Service Return Function Specification Instead of Object?

Apologies if this question is a duplicate (or if it has an obvious answer that I'm missing) -->
Is there a practice or pattern that involves a web service returning a function definition to the client, instead of a value or object?
For an extra rough outlining example:
I'm interested in the results of some statistical model. I have a dataset of 100,000 objects of class ClientSideClass.
The statistical model sits on a server, where it has to have constant access to a large database and be re-calibrated/re-estimated frequently.
The statistical model takes some mathematical form, like RESULT = function(ClientSideClass) = AX + BY + anotherFunction(List(Z))
The service in question takes requests that have a ClientSideClass object, performs the calculation using the most recent statistical model, and then returns a result object of class ModelResultClass.
In pseudo OOP (again, sorry for the gnarly example) :
My program as a client :
static void main() {
/* assume that this assignment is meaningful and that all
the objects in allTheThings have the same identifying kerjigger */
SomeIdentifier id = new SomeIdentifier("kerjigger");
ClientSideClass[100000] allTheThings = GrabThoseThings(id);
for (ClientSideClass c : allTheThings) {
ModelResult mr = Service.ServerSideMethod(c);
// more interesting things
}
}
With my client side class :
ClientSideClass {
SomeIdentifier ID {}
int A {}
double[] B {}
HashTable<String,SomeSimpleClass> SomeHash {}
}
On the server, my main service :
Service {
HashTable<SomeIdentifier,ModelClass> currentModels {}
ModelClass GetCurrentModel(SomeIdentifier id) {
return currentModels.get(id);
}
ModelResultClass ServerSideMethod(ClientSideClass clientObject) {
ModelClass mc = GetCurrentModel(clientObject.ID);
return mc.Calculate(clientObject);
}
}
ModelClass {
FormulaClass ModelFormula {}
ModelResultClass Calculate(ClientSideClass clientObject) {
// apply formula to client object in whatever way
ModelResult mr = ModelFormula.Execute(clientObject);
return mr;
}
}
FormulaClass {
/* no idea what this would look like, just assume
that it is mutable and can change when the model
is updated */
ModelResultClass Execute(clientObject) {
/* do whatever operations on the client object
to get the forecast result
!!! this method is mutable, it could change in
functional form and/or parameter values */
return someResult;
}
}
This form results in a lot of network chatter, and it seems like it could make parallel processing problematic because there's a potential bottleneck in the number of requests the server can process simultaneously and/or how blocking those calls might be.
In a contrasting form, instead of returning a result object, could the service return a function specification? I'm thinking along the lines of a Lisp macro or an F# quotation or something. Those could be sent back to the client as simple text and then processed client-side, right?
So the ModelClass would instead look something like this? -->
ModelClass {
FormulaClass ModelFormula {}
String FunctionSpecification {
/* some algorithm to transform the current model form
to a recognizable text-formatted form */
string myFuncForm = FeelTheFunc();
return myFuncForm;
}
}
And the ServerSideMethod might look like this -->
String ServerSideMethod(SomeIdentifier id) {
ModelClass mc = GetCurrentModel(id);
return mc.FunctionSpecification;
}
As a client, I guess I would call the new service like this -->
static void main() {
/* assume that this assignment is meaningful and that all
the objects in allTheThings have the same identifier */
SomeIdentifier id = new SomeIdentifier("kerjigger");
ClientSideClass[100000] allTheThings = GrabThoseThings(id);
string functionSpec = Service.ServerSideMethod(id);
for (ClientSideClass c : allTheThings) {
ModelResult mr = SomeExecutionFramework.Execute(functionSpec, c);
}
}
This seems like an improvement in terms of cutting the network bottleneck, but it should also be readily modified so that it could be sped up by simply throwing threads at it.
Is this approach reasonable? Are there existing resources or frameworks that do this sort of thing or does anyone have experience with it? Specifically, I'm very interested in a use-case where an "interpretable" function can be utilized in a large web service that's written in an OO language (i.e. Java or C#).
I would be interested in specific implementation suggestions (e.g. use Clojure with a Java service or F# with a C#/WCF service) but I'd also be stoked on any general advice or insight.

Index Service Design - Sync / Async

I have a requirement to index items. This service should run Sync or Async.
I started designing an Interface
public interface IndexService{
public void index();
}
And two implementation, one for a Async Index:
public class AsyncIndex implements IndexService {
public void index(){
//... Creates a Thread and index the items
}
}
And the other one to the Sync Index
public class SyncIndex implements IndexService {
public void index(){
//... Creates a Thread and index the items
}
}
But now there is another design that is having a IndexService, who has a flag to execute as a async service or as a sync service:
public interface IndexService{
public void index(int mode);
}
So now the implementation will know how to run base on that flag.
I know that the first design is better, but I need pros and cons to explain why.
I go for first approach because
1- code is cleaner AsyncInex class only has codes related to async call and syncIndex would has its own code.
2- you can avoid else if
...
public void runService(IndexService service) {
service.index()
}
// some where in your code
runService(new AsyncIndex());
// or
runService(new SyncIndex());
as you are working with interface "IndexService" you can always change implementation without changing clients code.
specially if you are using DI frameworks you can have the kick of it ;).
this is so important to not allowing client code know about the implementation. suppose situation where you are indexing, for instance, a database.
you want to do async index when data is huge or sync index when data is small.
caller should has no knowledge about the way Index is called. this way you can have different strategy in different situations without changing callers code. if you take the second approach you have to do some extra work.
I say both.
Assume, you plan to use the second approach. Your implmentation may look like:
public SyncOrAsyncIndex implements IndexService {
public void index(int mode) {
if(mode == 0) {
//sync processing code
} else if (mode == 1) {
//async procesisng code
}
}
That said, are you going to write all the implementation within this index method or SyncOrAsyncIndex class. That will possibly end up being unmanageable.
So, the index method may end up like this:
public void index(int mode) {
if(mode == 0) {
new SyncIndex().index(); //for example
} else if (mode == ) {
new AsyncIndex().index(); //for example
}
}
Assume, you decide on supporting a third mode. Imagine the plight of the index method or SyncOrAsyncIndex class. So, the first approach is needed.
So, as per "code to the interface" strategy the first approach is suggested. If the invoker is aware of the type of indexing, they can just instantiate the particular type and use it.
Else, along with the first approach the second one may be required as a factory or strategy to calculate which type of indexing to use based on the passed parameter. The invoker would then use the SyncIndex or AsyncIndex via SyncOrAsyncIndex.

Categories

Resources