Design pattern for interface that determines order of method invocation - java

I want to create a Java interface with a number methods. But I want the user of the interface to only be able to invoke methods in the sequence or order that I define. For instance buyTicket() should not be called before reserveTicket(). Q: Is there a design pattern or any tips on how to go about this?
I considered:
A)
Interface is wrapped, only showing the next possible method. Each invocation of a method returns a new operation that can be called after it, and so on.
So ReserveTicketOperation has public BuyTicketOperation execute();
Then BuyTicketOperation has public RenderTicketOperation execute();
B)
Use some kind of context state machine that records the position of execution using enums and has a factory for obtaining the next operation.
Any thoughts or suggestions are greatly appreciated. Thanks

My immediate feeling: this is the don't do it at all pattern.
If the inner logic of your methods requires them to always call them in a certain order; then you are exposing an implementation detail that will make it very easy to use your interface to do something wrong.
Meaning: instead of trying to somehow force your "client code" to adhere to some specific order you should design your interfaces in a way that the client code doesn't need to care about "order".
In your particular example the problem seems to be that a ticket object can be "reserved" or "bought"; and of course, only "bought" tickets can be turned back, refunded, ...
In this case, the "solution" could be to have actually different classes for "reserved" tickets and "bought" tickets. Then you don't need to worry that somebody tries to refund a ticket that is only "reserved".

Have a look at the Fluent Builder pattern.
One example of this is here.
http://blog.crisp.se/2013/10/09/perlundholm/another-builder-pattern-for-java
The idea is that you have an 'tree of allowable methods'. Each level of the tree is defined in one interface. So you have an 'order of interfaces'. All the methods in each interface do their job (which has to be void) and then returns another interface, corresponding to the next level of the tree.

Uh, the answer to this one is simple: there is a pattern for this already amongst the 23 in the Gang of Four: Template Method.
The whole idea is that you are codifying exactly what you are talking about a sequence of operations, but you are allowing each individual operation to be, in Meyer's terms 'open to extension.'
If you are not sure what those operations are until runtime, then TM will not work.

Perhaps Template Method Pattern, where your public interface defines the program skeleton of an algorithm in a public method, called template method, which defers some steps to private methods.
Or perhaps Command Pattern, where
an object is used to represent and encapsulate all the information
needed to call a method at a later time. This information includes the
method name, the object that owns the method and values for the method
parameters.

Related

UML/OOP: Using an interface for similar methods in different classes

Suppose I have two different classes that need to print different things:
OrderManager wants to print the order history, and MenuManager wants to print perhaps a menu. Since both want to do a similar function (but actual implementation is different), is it advisable to use an interface like this? The problem is that the function "print" is not very well-defined and self-explanatory as opposed to "printOrderHistory", and I can only implement the method with the exact name as defined in the interface.
Is there a workaround to this or am I using the interface concept wrongly? In fact, nothing seems to be stopping me from just defining their own print functions for each class without an interface...
This is the purpose of an interface! It defines a set of operations, and any class that implements this interface needs to implement these operations. This allows then to refer to a Printable object and call print(), knowing that it will perform as relevant for that object.
Your UML diagram, is therefore ambiguous: as OrderManager realizes (in java, "implements") Printable it should have its own print(). There are three solutions in UML and in Java:
Comply to the interface, as your diagram promises, and rename printOrderHistory() into print(). This makes sense if there is only one meaningfull way to print and order manager, and if there are no other constraints.
Add a print() operation (in java, "method") to OrderManager(), that just forwards the call to printOrderHistory(). But this looks like overcomplicated. It's justifiable only if the order manager would really e a printable, and if print() would add some relevant functionality such as selecting the right printing function depending on some factors.
Use the adapter pattern and leave the OrderManager clean, using an intermediate object for the dirty things. This makes especially sense if the name of OrderManager's printing function is constrained, or if there are different printing functions for different purposes. THis is the most flexible approach
Here a possible diagram for solution 3:
The idea with interfaces is to have a contract to fullfill. That means, that you have to you use method names and parameters defined in the interface when you build an implementation.
From my personal experience, it's always a bad idea to force an interface on classes, that are not similar, as in they do have a different purpose. While you could work with print() in both classes, it only makes sense if they are exchangeable in your code.

Why do we need interfaces if it only declares the method signature?

All the methods declared in interfaces are abstract and we have to re-write the method with signature and body in the class that implements the interface. So what's the point of using the interface?
Generally interfaces are considered to be contracts between developers. By this I mean, let's say you are developing a proprietary API for public use. Now you don't want everyone to be able to directly see your source code of how you implemented something, because that is your whole product. What you do instead is expose an interface which shows other developers what parameter types and return values to expect, and guarantees that your code will accomplish the purpose that it is being used for, without having to reveal how it works.
This also allows for the extensibility of code, because by allowing a certain method to accept an interface, rather than a specific implementation, you then allow the implementation to be changed or possibly improved, as long as it still implements the same interface and therefore adheres to the same guarantees.
Defining an interface is like saying "I expect to be able to have these functions that I can call that accept these parameters and return these values, but I don't care how you do it"
Interface just like the name suggest provides interface to something. So let's say I want an application that takes input from user and stores it in a database and later on fetches data from database on request to display from user. I can simply have an interface that declares methods to store and fetch from the database. So the user form that takes input and displays data can use these methods.
This gives me flexibility to change the implementation if I decide to change the database. And I would not have to change the part using the methods declared in the interface. Since all implementation will have those methods.
I think this doc(https://docs.oracle.com/javase/tutorial/java/concepts/interface.html) also will be helpful.
I think I can add one more thing here, let's say I want to use the interface provided by facebook(or some other app if you like). I can go through the list of methods provided to see which one works for me. It makes things simpler than having to go through all the implementation details. That's what I think #Tarun also said in above answer.

Best way to name methods that returns list of objects

I have a class named ActivityLog. This class holds a list of ActivityRecords. I want to return a list of ActivityRecords by these criterias: Environment and Condition. Should the method name include the "criteria"? See example:
activityLog.allRecords();
activityLog.allRecordsBy(Environment environment);
activityLog.allRecordsBy(Condition condition);
activityLog.allRecordsBy(Condition condition, Environment environment);
or
activityLog.allRecordsByEnvironment(Environment environment);
activityLog.allRecordsByCondtion(Condition condition);
I probably think the first is better because you will read the method name and you will understand from the parameter what it does, but I may be wrong? Which is the best, or are there even better alternatives?
I could have named the methods records(), recordsBy etc. too, but I want to have a consitency through my API where you always start writing all for lists of objects so you get help from for example Intelli Sense.
I like putting the criteria in the actual method name. So I would use:
activityLog.allRecordsByEnvironment(Environment environment);
To me proper method naming expresses a small summary of what the method does. Since the parameters are included in the method signature I would not consider the parameters to be part of the actual name, therefore not placing the criteria in the name gives the user of an api incomplete information about the methods functionality. (IMO)
I applaud your effort to practice self documenting code, great practice.
I like the overloaded variant (your first example), because it communicates that the methods are all related and provide largely the same functionality, aka, you are returning records, filtered by some criteria. You will see examples of this in many open source libraries and even the SDK itself.
I'd treat it the same as static factory methods, which are named constructors. And there not only parameter says what this method does, its name itself does it. So I'd choose 2nd option.
#Bob, about names being too long - even if you would put 2 parameters into its name, it still would be ok for me. Anyway you should avoid having methods with more than 3 parameters. Following this rule will prevent your methods' names from being enormous long.
I would take the first one.
If these methods are doing the same thing or providing the same functionality then they should have the same name. But be aware of Effective Java Item 41 and 42. You've to ensure that at least one corresponding param of overloaded method are having radically different types.
The 2nd approach becomes ugly very fast with every param added. I see this in often in Broker classes at work. There are people writing methods like findByFirstnameAndLastnameAndBirthdayOrderByUgliness(blablub). No comment.
Methods in OOP represent behavior, so I would name all of them getRecords() and made them overloaded.
In my opinion, specifying criteria in the name of method looks like naming heirarchy classes like this
Car -> BMW_Car -> X5_BMW_Car

In a Java interface, how can I *not* use one particular method inherited from a parent interface?

I have a hierarchy of three interfaces, grandparent, parent and child. Parent and child have a method "add", which requires different input parameters in the child. While it's no problem to add the required signature in the child, the inherited method will be pointless, so is there a way to not have it in there at all? The other methods work fine.
Maybe, to achieve what I want, I can improve the design altogether, so I'll shortly outline what the interfaces are about:
I collect meter readings that consist of a time and a value. The grandparent interface is for a single reading. I also have classes that represent a number of consecutive readings (a series), and one that contains multiple series running over the same period of time (let's just call that a table).
The table can be viewed as a series (which aggregates the values orthogonally to the time axis), and both table and series can be viewed as a single reading (the implementations providing different means of aggregation), hence the inheritance. This seems to work out fine, but for the add method. (I can add a single point to the series, but for the table I need an additional parameter to tell me to which series it belongs.)
No, you cannot avoid inheriting a method, since doing so would violate the Liskov substitution principle.
In practice, you could have implementations throw an UnsupportedOperationException, but that would be pretty nasty.
Can't you implement the inherited method with some sort of default value for the series?
Maybe it would make sense to break the interface inheritance all together. Just have specific interfaces for specific types of behaviors. Whatever classes you have that implement these interfaces can just pick the ones that make sense, and won't have to worry about implementing methods that don't make sense.
The problem with inheritance is that the focus on the language mechanism makes people think about implementation rather than semantics.
When B inherits from A, it means that every instance of B is also an instance of A. In OOP, being an instance of something means typically that you should have a sensible response to its methods and at least support their messages.
If you feel that B should not support one of the messages of A, then as far as I am concerned you have two options:
BAD - Throw an "Unimplemented" exception as you would get with the collections framework. However, this is in my opinion poor form.
Good - Accept that B is not a type of A and avoid the inheritance, or restructure it (e.g., using composition and/or interfaces) so that you don't have to rewrite the code but you do not use a subtyping relation. If your application will live over time, you don't want to have semantic issues in your hierarchies.
Thanks for putting me on the right track, I upvoted the posts I found most helpful. Since my solution was inspired by the posts, but is not posted, I'll share what I decided to do:
As the hierarchy was inspired by how the data should be viewed, while the problems arise on the semantics of how you add data, I'm going to split up the interfaces for series and table into a read and a write interface each. The write interfaces have nothing to do with each other, and the read interfaces can inherit without conflicts.
I'll make this wiki, in case someone wants to expand on this.
You might want to look at the Refused Bequest code smell.
An interface is a contract. It means that anything that implements that interface will necessarily implement the methods defined. You could technically just implement it as a dummy method (no body, simply return, whatever) but to my knowledge, it must be implemented.
You can always implement the method as empty, for example:
class A implements B{ void add(A) { /*Goes Nowhere Does Nothing*/ return;} }
but really, it's not a good idea. A better solution would be for all of your grandparents, parents, and children all be the same class with two extra methods- hasParent():boolean and hasChild():boolean. This has the benefit of being a liskov substition compatible change as well as a cleaner design.

Object Conversion Pattern

I have several different classes coming from external sources (unmodifiable) that represent the same concept. For example Address. I have com.namespace1.Address (with fields houseNum, street, city), com.namespace2.Address (with fields h, s, c), namespace3.com.CoolAddress (with fields house_num, street, city).
The problem is that certain web services I use require certain Address object types so I am required to create a com.namespace1.Address given a namespace3.com.CoolAddress. The fields are easy enough to map but I'm looking for a pattern on how to do it.
From my point of view, an instance object AddressConverter doesn't make sense as there is no state (only behaviour) and when classes only have behaviour it boils down to static methods in a utility class. In the long term, anytime I need to map new objects to one another, I have one place to add/modify/remove methods. How it's done might change, but I know where the code sits (in once place) and can change the mapping when I need to.
Thoughts?
I think what you're looking for is a factory class. The factory pattern is used when you need to be able to instantiate one of several related classes, to be determined by the factory, not the developer.
See http://en.wikipedia.org/wiki/Factory_method_pattern
You're right to try to keep all this business logic in one place instead of doing ClassOne.toClassTwo(), ClassOne.toClassThree(),...
The most flexible way I can think of implementing this (but not the easiest by far) would be to have the factory start with a simple class with only basic common methods in it, and add handlers to a Hashtable or other container. That way you don't need concrete implementations of every possible combinations of features.
Of course it would be quicker to have a concrete implementation for each possible address variant, but there would be a fair amount of duplicated code, and it would be a little harder to add new address class types.
Since you can't modify the classes themselves, I'd suggest an implementation of the Adapter pattern for each direction. As you said, the adapter methods themselves can be static, but you can group both directions inside a single class so that the logic is all in one place.
At the end of the day you're going to be performing the same task no matter what you call it, or where you put the code. I'd suggest that both directions live in the same file, as they'll often both need updating when either direction changes.
If you are always converting to the same Class I would keep it simple and put all you conversion code in that Class and not worry about factories and the like, especially if you are only dealing with a couple of different classes. Why does there always have to be a complicated pattern for these things?!
public class A {
...
public static A convertB(B b) {
...
}
}
Are the classes you need to output final? If not, you could subclass them to create proper Adapters. Otherwise I'd go with dj_segfault's suggestion of a Factory with a table of handlers.
Or, wait -- is it just a web service you need to talk to? If so, there should be no reason your implementations of its datatypes can't be Adapters wrapping the input datatypes, or some intermediate object of your own.

Categories