• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Knute Snortum
  • Bear Bibeault
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Tim Holloway

Calling a method with different parameters and iterate

 
Ranch Hand
Posts: 491
10
Android Open BSD Slackware
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a method that inserts into the Android Calendar an event. You can see q simplified snippet the two steps: 1)declare the variables 2) I put them into a kind of array that in the end will insert it into the calendar, and it works flawlessy:

   
Now my use case is that I need to insert the same event at different times. So I am wondering which design pattern I should use to do that to avoid duplications. Basically I need to change the point "1)" the 2 variables of the time startMillis and endMillis, and maintain iterating i guess the point "2)" so that the two different time variables go into the point "2" and different events get inserted

I thought different approaches 1)REALLY BAD. Repeat all the code every time writing consecutive methods as



2)Split the insertCalendarEvent in two methods, somehow refactoring the code in another class, maybe using a POJO, ArrayList with Map<>, but I am not sure how to implement

3) Create more classes to maintain the Single Responsibility but I do not know how to do it

What is the way a good architect would proceed with this use case?
Is quite frustrating to write this post, because I am sure is something I saw a lot of times, I truly guess is the number 2 the solution.

 
Sheriff
Posts: 13517
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Giovanni Montano wrote:I am wondering which design pattern I should use to do that to avoid duplications
...
1)REALLY BAD. Repeat all the code every time writing consecutive methods as


I doubt there's a named design pattern specifically for something like this. It's good you recognize that the above code is bad though. I'm guessing you saw a "pattern" of repetition in the names and thought "Well, this is bad because I'd have to duplicate a lot of code each time there was another point in time I need to insert."

When I see this kind of duplication, I immediately think "objectify and parameterize it."

To "objectify", I'd think in terms of what object would be responsible and what the conversation with that object might look like. To "parameterize", I'd look at the differences in the names and represent that as one or more parameters instead. Of course, I'd take care to limit the number of parameters to about three or four max. If there are more than four parameters, that's when I turn to the Parameter Object pattern.

I might start with something like this:

(Edit: accidentally clicked "Submit" instead of "Preview")



That seems pretty decent. Now I have a MyCalendar object to which I can say "Insert this event at this time and date". Through testing and carefully reading and considering the semantics of such code, I might think "Well, it's not clear whether the Calendar will reference the same event or not. Is it copying the event I pass in or just keeping a reference to the original object? Will any change to the event object outside the calendar be reflected in all the entries I inserted before? What behavior would be the least surprising? How can I design this API to make the semantics clearer?"

Then I'd probably experiment with something like this:

With this code in front of me, I'd ask the same questions I asked before, always going back to the fundamental questions of "Does this code make sense? Can someone read it and easily understand what's going on?" Then I just keep experimenting and refactoring until I can answer those questions satisfactorily.
 
Giovanni Montano
Ranch Hand
Posts: 491
10
Android Open BSD Slackware
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Giovanni Montano wrote:I am wondering which design pattern I should use to do that to avoid duplications
...
1)REALLY BAD. Repeat all the code every time writing consecutive methods as


I doubt there's a named design pattern specifically for something like this. It's good you recognize that the above code is bad though. I'm guessing you saw a "pattern" of repetition in the names and thought "Well, this is bad because I'd have to duplicate a lot of code each time there was another point in time I need to insert."


Correct, I want to avoid code duplication, would be really a smell.
Please take a pie, you are my favorite mentor ever. Thanks


Junilu Lacar wrote:
When I see this kind of duplication, I immediately think "objectify and parameterize it."

To "objectify", I'd think in terms of what object would be responsible and what the conversation with that object might look like. To "parameterize", I'd look at the differences in the names and represent that as one or more parameters instead. Of course, I'd take care to limit the number of parameters to about three or four max. If there are more than four parameters, that's when I turn to the Parameter Object pattern.


I did not know this pattern it is very interesting,
as far as I can see the Parameter Object Pattern allows me to move a method and some parameters in another class, and this is fantastic because do not need to use any `static`awkward method:




I have only two parameters/variables/fields that I need to "objectify"(like this name): `startMillis` and `endMillis`, because `editTextValue`remains the same

Junilu Lacar wrote:
I might start with something like this:

(Edit: accidentally clicked "Submit" instead of "Preview")



That seems pretty decent. Now I have a MyCalendar object to which I can say "Insert this event at this time and date". Through testing and carefully reading and considering the semantics of such code, I might think "Well, it's not clear whether the Calendar will reference the same event or not. Is it copying the event I pass in or just keeping a reference to the original object? Will any change to the event object outside the calendar be reflected in all the entries I inserted before? What behavior would be the least surprising? How can I design this API to make the semantics clearer?"


Interesting questions, definitely useful when one builds libraries. I need just to maintain the single responsibility principle, so I want one class that does one thing, so want to get rid of the calendar business logic away from the view, and building a class `MyCalendar` looks nice to me as you suggest.As consequence I do not need to copy the event but just pass a reference to make my view class semantically clearer because more short and with one only responsibility, namely showing the user interface. This is also the 'least surprising behavior" that means to me the code will be easy to read by others and by myself.

So I am going to build a class `MyCalendar` with all the needed android imports
and this class will have a method called insert( Event event, LocalDataTime moment){}


Junilu Lacar wrote:

Then I'd probably experiment with something like this:

With this code in front of me, I'd ask the same questions I asked before, always going back to the fundamental questions of "Does this code make sense? Can someone read it and easily understand what's going on?" Then I just keep experimenting and refactoring until I can answer those questions satisfactorily.


I do not get the Event class, maybe  should be a wrapper for
the Android SDK ContentProvider(Facade pattern that interact internally with an SQL db) instructions I furnished as point 2 in my first post(please see snippet below under method `setSchedule`, but
I do not get how you can use a second constructor of Event that pass as well event as parameter! is that possible?:
because you wrote:

myCal.insert(event);
myCal.insert(new Event(event, now.plusHours(15)));


here my understanding of the class  `Event`:

 
Junilu Lacar
Sheriff
Posts: 13517
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Giovanni Montano wrote:so I want one class that does one thing, so want to get rid of the calendar business logic away from the view, and building a class `MyCalendar` looks nice to me as you suggest.As consequence I do not need to copy the event but just pass a reference to make my view class semantically clearer because more short and with one only responsibility, namely showing the user interface (1).

So I am going to build a class `MyCalendar` with all the needed android imports
and this class will have a method called insert( Event event, LocalDataTime moment){} (2)


The statement marked (1) is contradictory to (2) -- If the responsibility is to simply show the user interface, then why do you have method that changes the internal state of the Calendar? Managing state seems like it's the responsibility of a Model layer class, not a View/Presentation layer class. The view/presentation simply handles the visual representation of the model.  I would imagine you'd have at least two classes: Calendar and CalendarView.
 
Giovanni Montano
Ranch Hand
Posts: 491
10
Android Open BSD Slackware
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Giovanni Montano wrote:so I want one class that does one thing, so want to get rid of the calendar business logic away from the view, and building a class `MyCalendar` looks nice to me as you suggest.As consequence I do not need to copy the event but just pass a reference to make my view class semantically clearer because more short and with one only responsibility, namely showing the user interface (1).

So I am going to build a class `MyCalendar` with all the needed android imports
and this class will have a method called insert( Event event, LocalDataTime moment){} (2)


The statement marked (1) is contradictory to (2) -- If the responsibility is to simply show the user interface, then why do you have method that changes the internal state of the Calendar? Managing state seems like it's the responsibility of a Model layer class, not a View/Presentation layer class. The view/presentation simply handles the visual representation of the model.  I would imagine you'd have at least two classes: Calendar and CalendarView.




Anyway yes we are on the same page, Managing state it's the responsibility of the Model layer. I have a small god class at the moment with the smallest use case (passing the event to the calendar,) because I started in the MainClass the first implementation, now I am going to refactor in other classes. I definitely want the view to make only the view

I got another solution by another great dev, and was based on my suggestion to create a POJO, a Collection subclass (List/Map) and Iterate:
(please consider that Events is a class of the Android library


A)Create a MyEvent class for representing the subset of events you want to create (e.g. year, month, day, starthr, startmin, endhr, endmin, title, etc.).
B)Change your InsertCalendarEvent() to take a MyEvent as argument: so this function becomes general purpose.
C)reate an InsertCalendarEvents() method with a Collection of MyEvents as argument. This method would just iterate through the collection (using an iterator) and call InsertCalendarEvent().
D)When you need to insert the events, you would just have to generate a collection of MyEvents (for example an ArrayList) and invoke  InsertCalendarEvents().
(Here, MyEvent plays a passive DTO role. But you could also opt for an active record approach and let MyEvent save itself to the calendar (in this case you should sore the ID returned in the URI in case the event should be modified later on).)



It looks really immediate and easy to decouple, and is quite a recurrent way to use Android( I do not know why I always found Android has really complex architectural patterns, while backend  friends usually use only "simple" MVC)

Well case solved, and thank you for your help, I liked the questions to ask,  and your solution to implement a Parameter Object Pattern.
 
Giovanni Montano
Ranch Hand
Posts: 491
10
Android Open BSD Slackware
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
EDIT: @Junilu for future reference if somebody looks into this post to find solutions.

I was risking to overarchitecting everything, even easier for my use case, i could resolve like that, eventually adding a static Utility class if want to separate. No need to create a POJO or iterate collections.





 
Junilu Lacar
Sheriff
Posts: 13517
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That solution wouldn't be my choice. The semantics are still vague and the story that method call tries to tells seems awkward to me.

1. An "offset" is relative to some baseline. The call does not make it clear what is that baseline.

2. The "withOffset" part of the method name strongly suggests a desire for something to be expressed as a parameter instead. It's like the code really wants to be written like this:



If good names are used, the kind of API makes the code very explicit. The API you have chosen to go with is not as expressive.

3. Using a static method also does not help to clarify the context for the reader and it raises more questions for me as to the overall fitness of the design you've settled on. Why would the method be attached to the class, assuming this was in some kind of MyCalendar class, instead of an instance of the class? Seems to me like that's not the best choice to make.
 
Giovanni Montano
Ranch Hand
Posts: 491
10
Android Open BSD Slackware
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, I eliminate offset, makes semantically sense what you say, names are really important, good code have to tell a story, a novel, and definetly is better to leave at the parameter the expression of the meaning, otherwise looks as an abstract baseline.

I hate static methods but they make sense when one want to use a static class, if the view get too busy, and you do not use the presenter. by the way I suggest the books of Martin Fowler, I am starting to like them a lot, this nice cheatsheet is fantastic at this purpose
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!