I will explain with an example. My GWT project has a Company module, which lets a user add, edit, delete, select and list companies.
Of these, the add, edit and delete operations lands back the user on the CompanyList page.
Thus, having three different events - CompanyAddedEvent, CompanyUpdatedEvent and CompanyDeletedEvent, and their respective event handlers - seems overkill to me, as there is absolutely not difference in their function.
Is it OK to let a single event manage the three operations?
One alternative I think is to use some event like CompanyListInvokedEvent. However, somewhere I think its not appropriate, is the event actually is not the list being invoked, but a company being added/updated/deleted.
If it had been only a single module, I would have get the task done with three separate events. But other 10 such modules are facing this dilemma. It means 10x3 = 30 event classes along with their 30 respective handlers. The number is large enough for me to reconsider.
What would be a good solution to this?
UPDATE -
#ColinAlworth's answer made me realize that I could easily use Generics instead of my stupid solution. The following code represents an event EntityUpdatedEvent, which would be raised whenever an entity is updated.
Event handler class -
public class EntityUpdatedEvent<T> extends GwtEvent<EntityUpdatedEventHandler<T>>{
private Type<EntityUpdatedEventHandler<T>> type;
private final String statusMessage;
public EntityUpdatedEvent(Type<EntityUpdatedEventHandler<T>> type, String statusMessage) {
this.statusMessage = statusMessage;
this.type = type;
}
public String getStatusMessage() {
return this.statusMessage;
}
#Override
public com.google.gwt.event.shared.GwtEvent.Type<EntityUpdatedEventHandler<T>> getAssociatedType() {
return this.type;
}
#Override
protected void dispatch(EntityUpdatedEventHandler<T> handler) {
handler.onEventRaised(this);
}
}
Event handler interface -
public interface EntityUpdatedEventHandler<T> extends EventHandler {
void onEventRaised(EntityUpdatedEvent<T> event);
}
Adding the handler to event bus -
eventBus.addHandler(CompanyEventHandlerTypes.CompanyUpdated, new EntityUpdatedEventHandler<Company>() {
#Override
public void onEventRaised(EntityUpdatedEvent<Company> event) {
History.newItem(CompanyToken.CompanyList.name());
Presenter presenter = new CompanyListPresenter(serviceBundle, eventBus, new CompanyListView(), event.getStatusMessage());
presenter.go(container);
}
});
Likewise, I have two other Added and Deleted generic events, thus eliminating entire redundancy from my event-related codebase.
Are there any suggestions on this solution?
P.S. > This discussion provides more insight on this problem.
To answer this question, let me first pose another way of thinking about this same kind of problem - instead of events, we'll just use methods.
In my tiered application, two modules communicate via an interface (notice that these methods are all void, so they are rather like events - the caller doesn't expect an answer back):
package com.acme.project;
public interface CompanyServiceInteface {
public void addCompany(CompanyDto company) throws AcmeBusinessLogicException;
public void updateCompany(CompanyDto company) throws AcmeBusinessLogicException;
public void deleteCompany(CompanyDto company) throws AcmeBusinessLogicException;
}
This seems like overkill to me - why not just reduce the size of this API to one method, and add an enum argument to simplify this. This way, when I build an alternative implementation or need to mock this in my unit tests, I just have one method to build instead of three. This gets to be clearly overkill when I make the rest of my application - why not just ObjectServiceInterface.modify(Object someDto, OperationEnum invocation); to work for all 10 modules?
One answer is that you might want want to drastically modify the implementation of one but not the others - now that you've reduced this to just one method, all of this belongs inside that switch case. Another is that once simplified in this way, the inclination often to further simplify - perhaps to combine create and update into just one method. Once this is done, all callsites must make sure to fulfill all possible details of that method's contract instead of just the one specific one.
If the receivers of those events are simple and will remain so, there may be no good reason to not just have a single ModelModifiedEvent that clearly is generic enough for all possible use cases - perhaps just wrapping the ID to request that all client modules refresh their view of that object. If a future use case arises where only one kind of event is important, now the event must change, as must all sites that cause the event to be created so that they properly populate this new field.
Java shops typically don't use Java because it is the prettiest language, or because it is the easiest language to write or find developers for, but because it is relatively easy to maintain and refactor. When designing an API, it is important to consider future needs, but also to think about what it will take to modify the current API - your IDE almost certainly has a shortcut key to find all invocations of a particular method or constructor, allowing you to easily find all places where that is used and update them. So consider what other use cases you expect, and how easily the rest of the codebase can be udpated.
Finally, don't forget about generics - for my example above, I would probably make a DtoServiceInterface to simplify matters, so that I just declare the one interface with three methods, and implement it and refer to it as needed. In the same way, you can make one set of three GwtEvent types (with *Handler interfaces and possibly Has*Handlers as well), but keep them generic for all possible types. Consider com.google.gwt.event.logical.shared.SelectionEvent<T> as an example here - in your case you would probably want to make the model object type a parameter so that handlers can check which type of event they are dealing with (remember that generics are erased in Java), or source from one EventBus for each model type.
Related
I'm aware it's a complex question that cannot have a definite answer without posting a few hundreds of lines of code, which is why I'm looking for help through general ideas and pointers.
I have a Room #Query returning a RxJava3 Flowable<List<...>> which I subscribe to on RxJava thread Schedulers.io(), and observe from an activity-scoped ViewModel on RxJava thread AndroidSchedulers.mainThread(). The data is then stored in my ViewModel as LiveData, which plays better than RxJava when it comes to handle Android components' lifecycle.
The idea is to have a clean and immediate data update pattern, not to have to handle disposal and re-subscription separately on each activity or fragment lifecycle event such as onPaused and onResumed, and being updated in the background even when my activity is hidden in order to avoid that awful refresh lag when returning to my activity. I was pretty amazed at that design pattern. I still am, but I'm beginning to have doubts.
When starting another activity with the same design pattern, I do change a value and immediately get an updated List<...> from the other ViewModel. Different Activity, different ViewModel, same design, same database table. When returning to the first Activity, I find that the new data does never get updated: Room did not emit any update even though the data set has changed. I have to dispose and subscribe again in order to see the new data.
So my question is: any pointer on where the source of my problem might be?! Is there something rotten in the core of this design pattern? Something I misunderstood about all those things are supposed to work together? Is it just a mistake of mine due to some threading issue? Or should I fill a bug report for Room?
I tried to observe another non-Room RxJava3 observable from the ViewModel of my first Activity, and it does get updates when its data set is updated.
By the way, I also use Hilt in order to inject eveything as #Singleton.
Thank you for your time :-)
After a week of headaches, I have finally stumbled upon a solution, which happens to be clean and elegant.
The issue was RxJava, which, I just learnt, is not supposed to seamlessly handle multiple subscriptions to the same Observable. The solution is supposedly to make use of the publish(), connect(), refcount() operators, or better use the shortcut share(). I tried every way I could think of, without success (it actually made it worse). I also tried to subscribe() to the Room Flowable from my repository and proxy it through a BehaviorSubject.
There was this weird org.reactivestreams.Publisher in Room's documentation, whose added value I wouldn't know, and whose origin wasn't even my familiar io.reactivex.rxjava3. It turns out it that was the solution. Edit: It turns out Publisher is an interface that Flowable happens to implement.
build.gradle
implementation 'android.arch.lifecycle:reactivestreams:+'
Dao.java
#Query("...")
Flowable<List<...>> getFlowable();
ViewModel.java
public liveData;
#Inject
public ViewModel(#NonNull RoomDatabase roomDatabase) {
liveData = LiveDataReactiveStreams.fromPublisher(roomDatabase.dao().getFlowable());
}
It seems too easy to be true, but as far as I can see it seems to work perfectly better this way.
Edit:
It turns out the root of this issue was a slight little bit more vicious than I thought. I assumed #InstallIn(SingletonComponent.class) in my dependency injection #Module was enough, but apparently a #Singleton annotation on each #Provides method is also required.
#Module
#InstallIn(SingletonComponent.class)
public abstract class DependencyInjection
{
#Provides
#NonNull
#Singleton // do not omit this
public static DataDao provideDataDao(#NonNull RoomDatabase roomDatabase) {
return roomDatabase.dataDao();
}
#Provides
#NonNull
#Singleton // do not omit this
public static RoomDatabase provideRoomDatabase(#ApplicationContext Context applicationContext) {
return
BuildConfig.DEBUG ?
Room.databaseBuilder(applicationContext, RoomDatabase.class, "playground.db").fallbackToDestructiveMigration().build() :
Room.databaseBuilder(applicationContext, RoomDatabase.class, "playground.db").build() ;
}
}
I have a controller that is violating Open and Closed Principle. I'm trying to figure out how to solve this with certain conditions. Here is the implementation.
struct BasicRecording
{
void show() {}
void hide() {}
};
struct AdvanceRecording
{
void show() {}
void hide() {}
};
class NotSolidRecordingSettingsController
{
BasicRecording br;
AdvanceRecording ar;
public:
void swithToAR();
void swithToBR();
};
void NotSolidRecordingSettingsController::swithToAR()
{
br.hide();
ar.show();
};
void NotSolidRecordingSettingsController::swithToBR()
{
ar.hide();
br.show();
};
The problem here is if I have a new recording settings, I would need to go back inside settings controller and add that new recording settings. If I inject the BasicRecording and AdvanceRecording in NotSolidRecordingSettingsController, then the Object instantiating NotSolidRecordingSettingsController will need to do the instantiating of BasicRecording and AdvanceRecording. But then that Object then violates OCP. Somebody has to create the object.
How can I design this to be OCP without just off loading the Not OCP part to some other thing?
Is there a particular design pattern for this kind of problem?
In the SOLID principles, OCP is really a consequence of SRP -- a class should have a single responsibility, and its code should only change when its internal requirements -- the requirements associated with its one job -- change.
In particular, a class shouldn't have to change because it's clients change. It may have a lot of clients and you don't want to mess with its code every time it gets new clients or the existing clients need to do something different. Hence OCP. Note that in OCP, "closed for modification" means you don't mess with it when you change the stuff that uses it. You do modify it when its own internal requirements change. That's just maintenance.
So OCP is about how classes relate to their clients, BUT, there are classes that have no clients. Their job is not to be services, and they are not used by other classes or to implement APIs, etc. These classes do not need to worry about OCP, because they naturally have no reason to change other than a change to their internal requirements.
A great example of such a class is what is sometimes called a "composition root" (googlable). Its single responsibility is to define how the system is built from its components. This is the guy that creates all the objects and injects them into everywhere they're needed.
You need a composition root that injects the settings panes into the controller (and whatever triggers them, because you can't have a method called switchToAR anymore). This class' job is to define the system by creating the required objects. When the arrangement of objects needs to change, then, that is a change to its internal requirements and you can go ahead and modify its code without violating SOLID.
(or you can have all that stuff read from configuration instead, but that is just implementing the composition root in config instead of your programming language. Sometimes that is a good idea, and sometimes not)
Im designing a small library and sometimes i write a couple lines and it just doesn't feel right, so i'd like to get the opinions/advices of an experimented java programmer.
Ive got a listener which handle 3 differents events and in one of my class I implement the methods that will actually fire the events
So what i did at first was something like this:
protected final void fireOperationStarted(){
OperationEvent event = new OperationEvent(this);
for (OperationListener listener : listeners) {
listener.operationStarted(event);
}
}
protected final void fireOperationEnded(){
OperationEvent event = new OperationEvent(this);
for (OperationListener listener : listeners) {
listener.operationEnded(event);
}
//omitted the 3rd method on purpose
but this code felt wrong because if someone want to implement their own event, they will basically need access to the whole listener arraylist (CopyOnWriteArraylist) and write the logic again and again.
So what i opted for is a Fireable interface with a single method "fire". And this is what i've done:
protected final void fireOperationStarted(){
fireOperation(new Fireable(){
#Override
public void fire(OperationListener listener, OperationEvent event) {
listener.operationStarted(event);
}
});
}
protected final void fireOperationEnded(){
fireOperation(new Fireable(){
#Override
public void fire(OperationListener listener, OperationEvent event) {
listener.operationEnded(event);
}
});
}
protected void fireOperation(Fireable fireable){
OperationEvent event = new OperationEvent(this);
for (OperationListener listener : listeners) {
fireable.fire(listener, event);
}
}
I'd like to get your opinions, I personally think its better than the first implementation even there is still a lot of boilerplate code. Maybe there is a better way to do this ? I've looked in the java.awt.events package source code to see how they were dealing with multiple events and how they fire them, but it seem way too complicated for my needs.
One thing that i was wondering also is about the lambda expression in Java 8, if i use them without importing any Java 8 packages and i compile, will it work on the JRE7 ?
Could be great to use the JDK8 to make my codes cleaner eventually.
Thanks for your help !
I think your first example is better. listeners has got to be an instance field, and so readily available to everybody.
(You might have only one method in OperationListener and use a value in OperationEvent to determine which action is involved. Then your methods could all pass the proper event to one method that calls the one listener method.)
Your second idea is interesting, but for use inside one instance of one class, I think it's overkill.
There's all different kinds of ways to store listeners. If you're not adding and removing them too fast, ArrayList is good. If there's any chance of adding and removing them on different threads and you're calling the listeners frequently, CopyOnWriteArrayList is much better.
Don't worry too much about "boilerplate". Java tends to go with wordy-but-simple as regards low level code. The two for loops in your first example call out to be combined somehow, but it's not worth worrying about until you've got a lot more of them.
Lambdas will reduce your lines of code (if you use simple ones; my C# lambdas all end up running 20 lines or more; might as well be anonymous classes!), but they'll add plenty of pages to the language manual. However, lambdas aren't there till JRE 8.
I'm writing a turn-based strategy game. Each player in the game has a team of units which can be individually controlled. On a user's turn, the game currently follows a pretty constant sequence of events:
Select a unit -> Move the selected unit -> Issue a command -> Confirm
I could implement this by creating a game class that keeps track of which of these stages the player is in and providing methods to move from one stage to the next, like this:
interface TeamCommander {
public void select(Coordinate where);
public void move(Coordinate to);
public void sendCommand(String command);
public void execute();
}
However, that would allow the possibility of a method being called at the wrong time (for example, calling move() before calling select()), and I would like to avoid that. So I currently have it implemented statelessly, like this:
interface UnitSelector {
public UnitMover select(Coordinate where);
}
interface UnitMover {
public UnitCommander move(Coordinate to);
}
interface UnitCommander {
public CommandExecutor sendCommand(String command);
}
interface CommandExecutor {
public void execute();
}
However, I'm having difficulty presenting this information to the user. Since this is stateless, the game model does not store any information about what the user is currently doing, and thus the view can't query the model about it. I could store some state in the GUI, but that would be bad form. So, my question is: does anyone have an idea about how to resolve this?
First, there's something I'm not getting here: You have to be storing persistent state somewhere, even if it is only in the View / GUI. Without persistent state you cannot have a game. I'm guessing you're using either ASP or PHP; if so, use sessions to track state.
Secondly, build your state logic into that so it is known where in the input sequence you are for each player / each unit in that player's team. Don't try to get fancy with it. B requires A, C requires B and so on. While you're writing it, just give yourself a scaffold by throwing exceptions if the call order comes up incorrect (which you should be checking on every user input as I assume this is an event driven rather than loop-driven game), and debug it from there.
As an aside: I get suspicious when I see interfaces with a single method as in your second example above. An interface typically informs of there being a unique SET of functionalities which different classes each fulfill -- unless you are trying to construct multiple different classes which use slightly different sets of individual method signatures, don't do what you're doing there. It is all fine and good to say "code to an interface and not an implementation", but you need to first take the top down approach, saying, "How does my ultimate client code (in your root game logic class or method) need to call for such-and-such to occur?" and keep asking that question up the call stack (i.e. at each subsequent sub-call codepoint). If you try to build it from the bottom up, you will end up with the confusing and unnecessarily complicated code I see there. The only other exception to this which I see on a regular basis is the command pattern, and that is generally intended to look like
void execute();
or
void execute(Object data);
...But typically not a whole slew of slightly different method signatures (again possible, but unlikely). My gut feeling comes from my experience with such constructs in that they usually don't make sense and you end up completely refactoring code that uses them.
The Wikipedia article about encapsulation states:
"Encapsulation also protects the integrity of the component, by preventing users from setting the internal data of the component into an invalid or inconsistent state"
I started a discussion about encapsulation on a forum, in which I asked whether you should always clone objects inside setters and/or getters as to preserve the above rule of encapsulation. I figured that, if you want to make sure the objects inside a main object aren't tampered with outside the main object, you should always clone it.
One discussant argued that you should make a distinction between aggregation and composition in this matter. Basically what I think he ment is this:
If you want to return an object that is part of a composition (for instance, a Point of a Rectangle), clone it.
If you want to return an object that is part of aggregation (for instance, a User as part of a UserManager), just return it without breaking the reference.
That made sense to me too. But now I'm a bit confused. And would like to have your opinions on the matter.
Strictly speaking, does encapulation always mandate cloning?
PS.: I program in PHP, where resource management might be a little more relevant, since it's a scripted language.
Strictly speaking, does encapulation always mandate cloning?
No, it does not.
The person you mention is probably confusing the protection of the state of an object with the protection of the implementation details of an object.
Remember this: Encapsulation is a technique to increase the flexibility of our code. A well encapsulated class can change its implementation without impacting its clients. This is the essence of encapsulation.
Suppose the following class:
class PayRoll {
private List<Employee> employees;
public void addEmployee(Employee employee) {
this.employees.add(employee);
}
public List<Employee> getEmployees() {
return this.employees;
}
}
Now, this class has low encapsulation. You can say the method getEmployees breaks encapsulation because by returning the type List you can no longer change this detail of implementation without affecting the clients of the class. I could not change it for instance for a Map collection without potentially affecting client code.
By cloning the state of your object, you are potentially changing the expected behavior from clients. This is a harmful way to interpret encapsulation.
public List<Employee> getEmployees() {
return this.employees.clone();
}
One could say the code above improves encapsulation in the sense that now addEmployee is the only place where the internal List can be modified from. So If I have a design decision to add the new Employee items at the head of the List instead of at the tail. I can do this modification:
public void addEmployee(Employee employee) {
this.employees.insert(employee); //note "insert" is used instead of "add"
}
However, that is a small increment of the encapsulation for a big price. Your clients are getting the impression of having access to the employees when in fact they only have a copy. So If I wanted to update the telephone number of employee John Doe I could mistakenly access the Employee object expecting the changes to be reflected at the next call to to the PayRoll.getEmployees.
A implementation with higher encapsulation would do something like this:
class PayRoll {
private List<Employee> employees;
public void addEmployee(Employee employee) {
this.employees.add(employee);
}
public Employee getEmployee(int position) {
return this.employees.get(position);
}
public int count() {
return this.employees.size();
}
}
Now, If I want to change the List for a Map I can do so freely.
Furthermore, I am not breaking the behavior the clients are probably expecting: When modifying the Employee object from the PayRoll, these modifications are not lost.
I do not want to extend myself too much, but let me know if this is clear or not. I'd be happy to go on to a more detailed example.
No, encapsulation simply mandates the ability to control state by creating a single access point to that state.
For example if you had a field in a class that you wanted to encapsulate you could create a public method that would be the single access point for getting the value that field contains. Encapsulation is simply this process of creating a single access point around that field.
If you wish to change how that field's value is returned (cloning, etc.) you are free to do so since you know that you control the single avenue to that field.