Writing methods in interface with specific or variadic arguments? - java

I'm writing an integration with a 3rd party API Gateway, and in an effort to make it as decoupled as possible (and to be able to change the provider in the future), I created 3 interfaces that will contain methods for reading, writing and deleting from the gateway (because there are a lot of methods that I need to use so I don't want to cram everything in one large interface and violate interface segregation principle). The API Gateway is used to handle app creation and other CRUD operations.
And I'm not sure what is the best way to move forward. I can create an interface like this
interface Api_Gateway_Create {
public function create_app( string $organization, string $developer_id, string $body );
// other methods.
}
And then, when doing a concrete implementation, I will create a class that implements this, and when I need to use it, I need to provide the three arguments.
This seems a bit constricting. What if, when I replace the provider, I no longer need the $developer_id? I could set all the arguments with some default value
interface Api_Gateway_Create {
public function create_app( string $organization,
string $developer_id = 'some-default-value',
string $body = 'some-default-value' );
// other methods.
}
But that means that I'll end up with arguments I don't need potentially and that could mess up my implementation.
The last thing that came to mind is that I could just put a variadic, and then let the implementation take care of the arguments
interface Api_Gateway_Create {
public function create_app( ...$arguments_list );
// other methods.
}
In the implementation I'd have
class Create_App_Implementation1 implements Api_Gateway_Create {
public function create_app( ...$arguments_list ) {
list( $organization, $developer_id, $body ) = $arguments;
// Some business logic.
}
}
or
class Create_App_Implementation2 implements Api_Gateway_Create {
public function create_app( ...$arguments_list ) {
list( $organization, $app_key, $body ) = $arguments;
// Some business logic.
}
}
That way I don't need to care if my provider offers these arguments, because I'll just implement the ones I need.
This however presents another problem. In the consuming code, say a class that will use create_app() method via dependency injection, I need to make extra care that the correct values are passed. And this is not future proof, as I'd need to change the code in the consuming class as well (which to me seems like the opposite intention of the interface).
With first one I will never have to change the consuming code, because I don't care what provider I'm using, if I'm expecting the same result (based on the same input arguments). But as I've mentioned, this seems a bit constricting. Two providers could have different way of handling this.
Did anybody have to face this kind of thing and what is the industry standard of handling this?
I'm writing in PHP, but I think Java could also be suited because of its object oriented nature.

Did anybody have to face this kind of thing and what is the industry standard of handling this?
I'm sure they have.
There is no "industry standard" way of doing this.
(You should probably remove phrases like "industry standard" and "best practice" from your vocabulary. They are harmful for communication, in my opinion. Read "No best practices" and think about what he is saying.)
I'm not familiar enough with PHP to say what is commonly done to address this in that language.
In Java, there are two common approaches:
Define lots of different method (or constructor) overloads for the common cases; e.g.
public interface CreateAppApi {
public String create_app(String organization, String developerId,
String body);
public String create_app(String organization, String developerId);
public String create_app(String developerId);
}
This doesn't work well if the parameters all have the same type: the different overload may not be distinguishable.
Use the fluent builder pattern; e.g. define the interface like this:
public interface CreateAppRequest {
public CreateAppRequest organization(String value);
public CreateAppRequest developer(String developerId);
public CreateAppRequest body(String body);
public String send();
}
and use it like this:
String result = new CreateAppRequestImpl().organization(myOrg)
.developer(myId).body(someBody).send();
This works nicely from the API user perspective, and it is easy to evolve. (Just add more methods for supplying new parameters to the API and implement them.) The downside is that there is more boilerplate code.
Java supports variadic parameter, but they are not suitable for the use-case you are describing. (That are applicable to cases where you have a variable number of values that essentially mean the same thing; e.g. an inline list of strings representing methods of our hypothetical "app".)
In Python, there is no method overloading ... because there is no need for it. Instead:
- you can use positional or keyword arguments, or a combination of them.
- you also have constructs like *args and **kwargs to pass through arbitrary parameters without explicitly declaring them.
Generally speaking, keyword parameters are better for APIs which require a variety of arguments with different meanings and (possibly) types.
So in this example you might write something like this:
class CreateAppRequest(SomeBaseClass):
def __init__(self, organization='defaultOrg', developer=None, body='',
**kwargs):
super(self, CreateAppRequest).__init__(**kwargs)
if developer is None:
raise Exception('developer is mandatory')
self.developer = developer
self.organization = organization
self.body = body
def send(self):
...
The builder / fluent approach can be used in Python too.

Related

Partly mutable API class with a generic variable holder for client use

I am building an API. One of its functions is to perform some resource analysis (imagine a document, URI, or DB, not important what) and return a List<Finding> where Finding is a POJO. I want the Finding to be immutable once returned from the API, with all the data returned by the API, however, I would like to have a single setUserNote(String) method for client convenience.
The reason for it is so that a client gets a listing of Findings, it can process them while using setUserNote to save its own data in the object itself, like a plain note. I think that would be a neat convenience preferable to the client having to extend Finding just to add that one variable or encapsulate it as an instance variable and then ExtendedFinding.someMethod() { return this.finding.someMethid(); } for every method in Finding. Furthermore, it would be messy, to say the least, for the client to construct ExtendedFinding out of the Finding he gets from the API. That's why I plan to just simply give them that one field they can use for convenience.
Questions:
Is this bad design and why? I have never done anything like this before nor have I seen API classes come with an arbitrary data holder variable for client convenience.
Let's say this is a bad design. What would be an applicable design pattern to easily propagate Finding to construct ExtendedFinding by the client? Surely, you could have something like public ExtendedFinding(Finding) { /* copy vars one by one */ } but that is far from elegant
First your third point, final in no way makes a class immutable - it signifies that the class cannot be inherited from. So you cannot extend a final class.
For your main problem, why don't you cast your POJO to an interface and return a list of that rather than the underlying POJO. You can then make your actual POJO class package private so that the client cannot cast it back:
public static interface Finding {
//all public getters
void setUserNote();
}
static final class FindingImpl implements Finding {
#Override
public void setUserNote() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
private final Collection<FindingImpl> findingImpls = new ArrayList<>();
public Collection<Finding> getFindings() {
final Collection<Finding> findings = new ArrayList<>();
for (final FindingImpl fi : findingImpls) {
findings.add(fi);
}
return findings;
}
This is not necessarily bad design. It sounds uncommon though. It is important to keep in mind the probable uses of an API when designing it, but I feel this goes a little too far:
It breaks the single-responsibility principle: the class now does both its job of representing Findings and of being a container for user specified data.
It limits the user to String notes instead of arbitrary objects. For example they wouldn't be able to use a Map or a custom POJO if they need to. (This could be easily fixed using generics, though.)
A better solution might be defining the equals and hashCode methods in the Finding class. This way these objects could be used as keys to a Map, and users would be able to store their notes outside of your API.
Another solution might defining a new class to represent the pair of a Finding and user notes. This has a cleaner "feel" than storing notes within the otherwise-immutable Finding class, but the added complexity might make it not worth the effort. Which solution is best really depends on the situation; there is no right or wrong answer.
(By the way, the final keyword doesn't make a class immutable. It just means you can't define subclasses for it. You can create mutable classes that are final - take for example StringBuilder)
I'm confused. If you return a Finding to me, that you consider immutable, how does it make a lick of sense for me to be able to inject a note, one time, into that object? The presumption would be that other people might be shown the same findings, no?
The correct answer here is that you should have another class: FindingComment with the commenter's id, the id of the Finding and a timestamp.
Your instinct that extending the class to glom a comment on is surely correct!

Design to emulate Visitor without its drawbacks

I'm looking for a clean design to emulate Visitor functionality without the many drawbacks it has.
In Java, the traditional implementations (as the described in GoF) resort to double dispatch to get rid of if-elses. To solve this, I've seen some implementations that use reflection to avoid modifications on the "Visitable" classes, but these rely on hardcoded strings when looking for method names. Although quite useful, I still think that they are not clean design.
Is it possible to emulate the same idea using data structures and/or good OO-design? It doesn't have to be a pattern, just I'm looking for examples where a similar problem is solved (e.g.: using a Map<Class<T>,SomeFunctionObject>).
UPDATE Something like this:
public abstract class BaseVisitor<T> {
private final TypesafeHeterogeneusMap map;
protected BaseVisitor(){
map = inflateFunctions();
}
public <E extends T> void process(E element){
if(element == null){
throw new NullPointerException();
}
boolean processed = false;
#SuppressWarnings("unchecked")
Class<? super T> sc = (Class<? super T>) element.getClass();
while(true){
if(sc != null){
FunctionObject<? super T> fo2 = map.get(sc);
if(fo2 != null){
fo2.process(element);
processed = true;
break;
}
sc = sc.getSuperclass();
} else {
break;
}
}
if(!processed) System.out.println("Unknown type: " + element.getClass().getName());
}
abstract TypesafeHeterogeneusMap inflateFunctions();
}
Actually is a mix of Template pattern and Command pattern, I think. Feel free to post your suggestions on how to enhance it.
You could just make all your Visitor implementations extend a base class, which provides a default implementation for every type of Visitable:
public interface AnimalVisitor {
void visitHorse(Horse horse);
void visitDog(Dog dog);
}
public class BaseAnimalVisitor implements AnimalVisitor {
public void visitHorse(Horse horse) {
// do nothing by default
}
public void visitDog(Dog dog) {
// do nothing by default
}
}
Then, when a new class Cat is introduced, you add the visitCat(Cat cat) method to the interface and the base class, and all the visitors are left unchanged and still compile. If they don't want to ignore cats, then you override the visitCat method.
Although it's not the answer you're looking for: Consider using a higher-level, less verbose language than Java. You will find that things like the Visitor pattern start to seem irrelevant. Of course, if you want to define logic for traversing a data structure in one place, and define what to do with the elements of the data structure (based on their types) somewhere else, and make it possible to mix-and-match traversal/processing strategies, you can do that. But you can do it using just a small amount of straightforward code, nothing that you would think of calling a "pattern".
I came from a C/Java programming background and started learning various dynamic languages a few years ago. It was mind-blowing to realize how much you can do in a few lines of code.
For example, if I was to emulate the Visitor pattern in Ruby:
module Enumerable
def accept_visitor(visitor)
each do |elem|
method = "visit#{elem.class}".to_sym
elem.send(method,elem) if elem.respond_to? method
end
end
end
To explain: in Ruby, an Enumerable represents anything which can be iterated over. In those 8 lines of code, I have made every kind of object which can be iterated over accept Visitors. Whether I plan to have 5, 10, or 100 different classes accept Visitors, those 8 lines are all that are needed.
Here's a sample Visitor:
class CatCounter
attr_reader :count
def initialize; #count = 0; end
def visitCat; #count += 1; end
end
Note that the Visitor doesn't have to define methods for all the different types of Visitables. Each Visitor just has to define methods for the types of Visitables it is interested in; it can ignore the rest. (Which means you don't have to modify a bunch of existing code if you add a new type of Visitable.) And any Visitor can interoperate with any object which accepts Visitors.
Just in those few lines of code, all the problems you mentioned with the Visitor pattern have been overcome.
Don't get me wrong; Java is a great language for some things. But you need to choose the right tool for the job. The fact that you are fighting so much to overcome the limitations of your tool might indicate that in this case, a different tool is called for.
#MisterSmith, since you have to use Java, and presumably you do have good reasons for using Visitor, I am going to propose another possible solution.
Let's separate our minds from the way Visitor is usually implemented and go back to the reason why people use Visitors in the first place. Although I mentioned it already in my other answer, the point of Visitor is to make it possible to mix-and-match traversal and processing logic.
"Traversal logic" could mean logic for traversing different types of data structures, or traversing the same data structure in a different order. Or it could even include traversal strategies which apply certain filters to the elements returned, etc.
Implicit in Visitor is the idea that the processing we apply to each element is going to depend on its class. If what we do to each element doesn't depend on its class, there is no reason to use Visitor. Unless we want to do a "switch" on element class, we need to use virtual method calls to do this (which is why the usual Java implementation uses double dispatch).
I propose that we can split the Visitor pattern into 3 rather than 2 parts:
An Iterator object which implements a certain traversal
An object which implements the strategy of "deciding what to do with an element based on its class" (the part which normally requires double dispatch). Using reflection, we can make a general-purpose class which does this. A simple implementation would use a Map, or you could make something which generates bytecode dynamically (I forget the platform method in Java which lets you load raw bytecodes as a new Class, but there is one). OR! OR, you could use a dynamic, JVM-hosted language like JRuby or Clojure to write #2, compile to bytecode, and use the resulting .class file. (This file would probably use the invokedynamic bytecode, which as far as I know, is not accessible from Java -- the Java compiler never emits it. If this has changed, please edit this post.)
The Visitors themselves. In this implementation, Visitors won't have to subclass from a common superclass, nor will they have to implement methods for elements they're not interested in.
Keeping the traversal in a general-purpose Iterator allows you to do other things with it (not just accepting Visitors).
There are a couple ways the 3 pieces could be tied together; I'm thinking #2 will wrap #3 (taking it as a constructor argument). #2 will provide a public method which takes an Iterator as an argument, and applies the Visitor to it.
The interesting part is #2. I may edit this post later to add a sample implementation; right now I have some other things to do. If someone else comes up with an implementation, please add it here.

Should my classes restrict developers from doing wrong things with them?

I am trying to understand where good contracts end and paranoia starts.
Really, I just have no idea what good developer should care about and what shall he leave out :)
Let's say I have a class that holds value(s), like java.lang.Integer. Its instances are aggregated by other objects (MappedObjects), (one-to-many or many-to-many), and often used inside MappedObjects' methods. For performance reasons, I also track these relationships in TreeMap (guava MultiMap, doesn't matter) in addition, to be able to get fast iterations over MappedObjects bound to some range of Integer keys.
So, to keep system in consistent state, I should modify MappedObject.bind(Integer integer) method to update my Map like:
class MappedObject {
public void bind (Integer integer) {
MegaMap.getInstance().remove(fInteger, this);
fInteger = integer;
MegaMap.getInstance().add(fInteger, this);
}
...
private Integer fInteger;
}
I could just make abstract MappedObject class with this final method, forcing other to inherit from it, but it is rude. If I will define MappedObject as interface with method bind() and provide skeletal implementation -- other developer might later just forget to include it in object and implement method by himself without Map updating.
Yes, you should force people to do the right thing with your code. A great example of letting people do the wrong thing is the servlet method init( ServletConfig config ) that expected you would store the servlet config yourself but, obviously, a lot of people forgot to store the config and when running their servlets just failed to work.
When defining APIs, you should always follow the open-closed principle, your class should be open for extension and closed for modification. If your class has to work like this, you should only open extension points where they make sense, all the other functionality should not be available for modification, as it could lead to implementation issues in the future.
Try to focus on functionality first and leave all unnecessary things behind. Btw you can't prohibit reflection so don't worry too much on misuse. On the other hand your API should be clear and straightforward so users will have clear idea, what they should and what they shouldn't do with it.
I'd say your classes should be designed for as simple use as possible.
If you allow a developer to override methods you definitely should document the contract as good as possible. In that case the developer opts to override some basic functionality and thus is responsible to provide an implementation that adheres to the contract.
In cases where you don't want the developer to override parts of the functionality - for security reasons, if there is no sensible alternative etc. - just make that part final. In your case, the bind method might look like this:
class MappedObject {
public final void bind (Integer integer) {
MegaMap.getInstance().remove(fInteger);
internalBind( integer );
MegaMap.getInstance().add(fInteger);
}
protected void internalBind( Integer integer ) {
fInteger = integer;
}
...
private Integer fInteger;
}
Here you'd allow the developer to override the internalBind() method but ensure that bind() will do the mapping.
To summarize: Make using and extending classes as easy as (sensibly) possible and don't have the developer to copy lots of boiler plate code (like the map updates in your case) in case he just wants to override some basic functionality (like the actual binding).
At least you should do really everything that prevents bugs but cost no effort.
For example: use primitive types (int) instead of wrappers (Integer) if the variable is not allowed to be null.
So in your bind method. If you not have intended to bind null, then use int instead of Integer as parameter type.
If you think your API users are stupid, you should prohibit wrong usage. Otherwise you should not stand in their way to do things they need to do.
Domumentation and good naming of classes and methods should indicate how to use your API.

Using an untyped wrapper class around objects stored in XML, is this bad?

class MyThing {
protected HashMap<String,Object> fields;
protected MyThing(HashMap<String,Object> newFields){
fields.putAll(newFields);
}
protected Object get(String key){
return fields.get(key);
}
}
Now a little background. I am using this class as a super class to a bunch of different classes which represent objects from an XML file. This is basically an implementation of an API wrapper and I am using this as an adapter between the parsed XML from an API and a database. Casting is delegated to the caller of the get method. If the subclasses need to do something when they are created or when they return a variable, they just call super and then manipulate what gets returned afterwards. eg.:
class Event extends MyThing {
public Event(HashMap<String,Object> newFields){
super(newFields);
// Removes anything after an # symbol in returned data
Pattern p = Pattern.compile("\\#.*$");
Matcher m = p.matcher((String)fields.get("id"));
boolean result = m.find();
if (result)
fields.put("id", m.replaceFirst(""));
}
}
public Object get(String key){
Object obj = super(key);
if (key.equals("name")){
return "Mr./Mrs. " + ((String)obj);
}
}
}
The reason I feel like I should do this is so I don't have to write getId, getName, getWhatever methods for every single subclass just because they have different attributes. It would save time and it is pretty self explanatory.
Now this is obviously "unJavalike" and more like a ducktyped language way of doing things, but is there a logical reason why I should absolutely not be doing this?
If you're going to this level of complexity and mucking up your object model just because you don't want to have getters and setters, do it in Groovy instead.
Groovy is a duck typed dynamic language on the JVM that accepts 98% of valid Java code, so you already know most of the language (you don't lose functionality)...there are "more idiomatic" ways of doing things, but you can pick those up with time. It also already has a built in XmlSlurper, which probably does most of what you're trying to do anyway.
As for the "reasons why you shouldn't", you're introducing all types of maintainability concerns.
New classes will always have to derive from the base class.
They will have to implement a constructor that always calls a base constructor
They will have to override get() [which you're basically using to encapsulate your getters and setters anyway, why not just add that method and delegate to those other methods] and write specific logic which is likely to degrade with time.
Why shouldn't you? It'll work, right? Sure. But it's poor engineering in that you're either creating a maintenance nightmare, or reinventing the wheel and likely to do it wrong.
Obviously, it's not type safe.
Future maintainers won't know what the types are supposed to be and will get generally confused as to why you're not using POJOs.
Instead of constant time, space complexity and performance you have the characteristics of a HashMap.
It become very difficult to write non-trivial getters/setters in future.
Most data binding systems are designed to work with POJOs/Beans (JAXB, JPA, Jackson, etc).
I'm sure there are more, but this will do. Try using some proper OXM libraries and you'll be much better off.

Nice name for `decorator' class?

I would like to separate the API I'm working on into two sections: 'bare-bones' and 'cushy'. The idea is that all method calls in the 'cushy' section could be expressed in terms of the ones in the 'bare-bones' section, that is, they would only serve as convenience methods for the quick-and-dirty. The reason I would like to do this is that very often when people are beginning to use an API for the first time, they are not interested in details and performance: they just want to get it working.
Anybody tried anything similar before? I'm particularly interested in naming conventions and organizing the code.
One way to provide a discrete separation of 'cushy' vs 'bare-bones' would be using separate interfaces that are implemented by the same class. When writing an API I like to keep it as simple as possible. If you need lots of parameters, consider using a fluent interface.
Yes, I've done something like this before, and I tend to pre-pend a word that indicates what the extra functionality is doing.
For example, a basic Vector class might only perform very basic vector operations (add, dot product), and a Vectors class might have a variety of static helper methods (cross products, projections, etc). Then, a FluentVector incorporates all those helper operations, while mutating the underlying Vector.
However, this isn't the decorator pattern - decorator produces different "decorated" results with the same interface. This is the facade pattern - different interface with the same underlying function.
Also, keep in mind that your extended API may have a variety of different ways of delivering the same function. Back to my Vector example, one might not want to mutate the underlying Vector with each chained-operation and instead introduce a new Vector - this might be an ImmutableFluentVector or some such. The API would be identical, except for the specification of side-effects. Just something to keep in mind.
Since you're asking for nice names, commonly used is simple or basic API and extended API. The simple API uses, as mentioned by Simon Nickerson, the extended API technically by providing an abstraction. See also Facade Pattern
Assuming Barebone provides basic functionality and Cushy provides additional functionality:
public class Skeleton
{
public virtual void Info()
{
}
}
public class Adorner:Skeleton
{
private Skeleton _skeleton;
public Adorner(Skeleton skeleton)
{
_skeleton = skeleton;
}
public override void Info()
{
//apply adorning work
}
}
Skeleton bareBones = new Skeleton();
Adorner cushy = new Adorner(bareBones);
Somebody at work suggested Foo and FooHelper. I like it.

Categories