Open Closed and Interface Segregation - java

I am writing a code which basically reads a text file (Tabular format) and check if the file contains expected data type or not. For that I have write following class.
The sample file would be something like this.
name age
abc 20
xyz vf
aaa 22
And I have JSON file which says, which conlumn should contains what?
{
filename:"test.txt",
cols:{
name:string,
age: int
}
}
A JSON file contains the DataType for each row, so I know what to expect?
Following code working without any issue. However, it seems that this code Violates the open closed and interface segregation principle.
public class DataValidation {
public boolean isInt(String value) {
try {
Integer.parseInt(value);
return true;
} catch (NumberFormatException ne) {
return false;
}
}
public boolean isFloat(String value) {
try {
Float.parseFloat(value);
return true;
} catch (NumberFormatException ne) {
return false;
}
}
}
And so I am thinking to Refector the code as mentioned below. However, would like to know what advantage I will get and is there any better approach?
public interface DataValidation {
boolean validate(String value);
}
public class IntValidator implements DataValidation {
public boolean validate(String value) {
try{
Integer.parseInt(value);
return true;
}catch (NumberFormatException ne){
return false;
}
}
}

Basic Definition of Open-Close Principle (OCP): (Meyer 1988)
the open/closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; that is, such an entity can allow its behavior to be extended without modifying its source code. see Reference
BUT: On the other hand Uncle Bob in this reference provide some clarifications about the meaning of OCP. (that I used them in the following)
First of all: In my idea, your class (DataValidation) did not conflict
Open-Close Principle.
Your class JUST check the primitive data types. (as you answered to my question in comment). There are just 8 primitive data types in Java. This number will not change in the future. So if you put all the 8 methods in one class, you don't have any extensions or modifications on data types in the future.
In the other hand, OCP is about adding new source codes without any changes in old codes. So event if Java adds new data type, you can add the method easily without modifications in other parts of code.
Therefore, I think that your class is not BIG enough to violate Open-Close Principle.
Secondly: To use Interface Segregation Principle (ISP)
To use ISP, we need some prerequisites. We should have some dependencies between part of our system (or class). we should need for Dependency Management to manage some parts of system and we consciously decide what each part of the system can depend on. please read this reference in-depth
I think that your class is just a Checker class and does not have any states (Attributes or Fields). So there is not any reason to use ISP.
To sum up: Using all Object Oriented principles and heuristics (like SOLID), should help us to reduce COMPLEXITY. In your project, there is no need to use them.
To offer a solution for your problem
You can use an enum DataTypes {boolean, char, _etc_} for Primitive Data Types and use only one method like DataType getDataType(String S) to get the type of given String as enum. But your approach (DataValidation class) is good enough too.

Gholamali-Irani provide great answer, but I want add some my own thinks about yours topic:
First of all, almost every best practice, paradigm, etc. trying to increase degree of maintainability, testability and extensibility. Do you really need them? How big probability of adding some custom and complex type? If its very low, than maybe your first variant is good enough for your task (not for general task of verification, just for yours).
Secondly, much depends on how you use it. You didn't show how exactly you use all this methods/classes/interfaces. "Servant" code might be very good, it can cleanest code in the world, but who cares if its used incorrectly or its very hard to use?

Related

How to compare Java function object to a specific method? [duplicate]

Say I have a List of object which were defined using lambda expressions (closures). Is there a way to inspect them so they can be compared?
The code I am most interested in is
List<Strategy> strategies = getStrategies();
Strategy a = (Strategy) this::a;
if (strategies.contains(a)) { // ...
The full code is
import java.util.Arrays;
import java.util.List;
public class ClosureEqualsMain {
interface Strategy {
void invoke(/*args*/);
default boolean equals(Object o) { // doesn't compile
return Closures.equals(this, o);
}
}
public void a() { }
public void b() { }
public void c() { }
public List<Strategy> getStrategies() {
return Arrays.asList(this::a, this::b, this::c);
}
private void testStrategies() {
List<Strategy> strategies = getStrategies();
System.out.println(strategies);
Strategy a = (Strategy) this::a;
// prints false
System.out.println("strategies.contains(this::a) is " + strategies.contains(a));
}
public static void main(String... ignored) {
new ClosureEqualsMain().testStrategies();
}
enum Closures {;
public static <Closure> boolean equals(Closure c1, Closure c2) {
// This doesn't compare the contents
// like others immutables e.g. String
return c1.equals(c2);
}
public static <Closure> int hashCode(Closure c) {
return // a hashCode which can detect duplicates for a Set<Strategy>
}
public static <Closure> String asString(Closure c) {
return // something better than Object.toString();
}
}
public String toString() {
return "my-ClosureEqualsMain";
}
}
It would appear the only solution is to define each lambda as a field and only use those fields. If you want to print out the method called, you are better off using Method. Is there a better way with lambda expressions?
Also, is it possible to print a lambda and get something human readable? If you print this::a instead of
ClosureEqualsMain$$Lambda$1/821270929#3f99bd52
get something like
ClosureEqualsMain.a()
or even use this.toString and the method.
my-ClosureEqualsMain.a();
This question could be interpreted relative to the specification or the implementation. Obviously, implementations could change, but you might be willing to rewrite your code when that happens, so I'll answer at both.
It also depends on what you want to do. Are you looking to optimize, or are you looking for ironclad guarantees that two instances are (or are not) the same function? (If the latter, you're going to find yourself at odds with computational physics, in that even problems as simple as asking whether two functions compute the same thing are undecidable.)
From a specification perspective, the language spec promises only that the result of evaluating (not invoking) a lambda expression is an instance of a class implementing the target functional interface. It makes no promises about the identity, or degree of aliasing, of the result. This is by design, to give implementations maximal flexibility to offer better performance (this is how lambdas can be faster than inner classes; we're not tied to the "must create unique instance" constraint that inner classes are.)
So basically, the spec doesn't give you much, except obviously that two lambdas that are reference-equal (==) are going to compute the same function.
From an implementation perspective, you can conclude a little more. There is (currently, may change) a 1:1 relationship between the synthetic classes that implement lambdas, and the capture sites in the program. So two separate bits of code that capture "x -> x + 1" may well be mapped to different classes. But if you evaluate the same lambda at the same capture site, and that lambda is non-capturing, you get the same instance, which can be compared with reference equality.
If your lambdas are serializable, they'll give up their state more easily, in exchange for sacrificing some performance and security (no free lunch.)
One area where it might be practical to tweak the definition of equality is with method references because this would enable them to be used as listeners and be properly unregistered. This is under consideration.
I think what you're trying to get to is: if two lambdas are converted to the same functional interface, are represented by the same behavior function, and have identical captured args, they're the same
Unfortunately, this is both hard to do (for non-serializable lambdas, you can't get at all the components of that) and not enough (because two separately compiled files could convert the same lambda to the same functional interface type, and you wouldn't be able to tell.)
The EG discussed whether to expose enough information to be able to make these judgments, as well as discussing whether lambdas should implement more selective equals/hashCode or more descriptive toString. The conclusion was that we were not willing to pay anything in performance cost to make this information available to the caller (bad tradeoff, punishing 99.99% of users for something that benefits .01%).
A definitive conclusion on toString was not reached but left open to be revisited in the future. However, there were some good arguments made on both sides on this issue; this is not a slam-dunk.
To compare labmdas I usually let the interface extend Serializable and then compare the serialized bytes. Not very nice but works for the most cases.
I don't see a possibility, to get those informations from the closure itself.
The closures doesn't provide state.
But you can use Java-Reflection, if you want to inspect and compare the methods.
Of course that is not a very beautiful solution, because of the performance and the exceptions, which are to catch. But this way you get those meta-informations.

Builder pattern with error-checking: is it possible/advisable?

I am using the Builder pattern to make it easier to create objects. However, the standard builder pattern examples do not include error-checking, which are needed in my code. For example, the accessibility and demandMean arrays in the Simulator object should have the same length. A brief framework of the code is shown below:
public class Simulator {
double[] accessibility;
double[] demandMean;
// Constructor obmitted for brevity
public static class Builder {
private double[] _accessibility;
private double[] _demandMean;
public Builder accessibility(double[] accessibility) {
_accessibility = accessiblity.clone();
return this;
}
public Builder demandMean(double[] demandMean) {
_demandMean = demandMean.clone();
return this;
}
// build() method obmitted for brevity
}
}
As another example, in a promotion optimization problem, there are various promotional vehicles (e.g. flyers, displays) and promotion modes, which are a set of promotional vehicles (e.g. none, flyer only, display only, flyer and display). When I create the Problem, I have to define the set of vehicles available, and check that the promotion modes use a subset of these vehicles and not some other unavailable vehicles, as well as that the promotion modes are not identical (e.g. there aren't two promo modes that are both "flyer only"). A brief framework of the code is shown below:
public class Problem {
Set<Vehicle> vehicles;
Set<PromoMode> promoModes;
public static class Builder {
Set<Vehicle> _vehicles;
Set<PromoMode> _promoModes;
}
}
public class PromoMode {
Set<Vehicle> vehiclesUsed;
}
My questions are the following:
Is there a standard approach to address such a situation?
Should the error checking be done in the constructor or in the builder when the build() method is called?
Why is this the "right" approach?
When you need invariants to hold while creating an object then stop construction if any parameter violates the invariants. This is also a fail-fast approach.
The builder pattern helps creating an object when you have a large number of parameters.
That does not mean that you don't do error checking.
Just throw an appropriate RuntimeException as soon as a parameter violates the objects invariants
You should use the constructor, since that follows the Single Responsibility Principle better. It is not the responsibility of the Builder to check invariants. It's only real job is to collect the data needed to build the object.
Also, if you decide to change the class later to have public constructors, you don't have to move that code.
You definitely shouldn't check invariants in setter methods. This has several benefits:
* You only need to do checking ONCE
* In cases such as your code, you CAN'T check your invariants earlier, since you're adding your two arrays at different times. You don't know what order your users are going to add them, so you don't know which method should run the check.
Unless a setter in your builder does some intense calculations (which is rarely the case - generally, if there's some sort of calculation required, it should happen in the constructor anyway), it doesn't help very much to 'fail early' in, especially since fluent Builders like yours use only 1 line of code to build the object anyway, so any try block would surround that whole line either way.
The "right" approach really depends on the situation - if it is invalid to construct the arrays with different sizes, i'd say it's better to do the handling in the construction, the sooner an invalid state is caught the better.
Now, if you for instance can change the arrays and put in a different one - then it might be better to do it when calling them.

Application design for processing data prior to database

I have a large collection of data in an excel file (and csv files). The data needs to be placed into a database (mysql). However, before it goes into the database it needs to be processed..for example if columns 1 is less than column 3 add 4 to column 2. There are quite a few rules that must be followed before the information is persisted.
What would be a good design to follow to accomplish this task? (using java)
Additional notes
The process needs to be automated. In the sense that I don't have to manually go in and alter the data. We're talking about thousands of lines of data with 15 columns of information per line.
Currently, I have a sort of chain of responsibility design set up. One class(Java) for each rule. When one rule is done, it calls the following rule.
More Info
Typically there are about 5000 rows per data sheet. Speed isn't a huge concern because
this large input doesn't happen often.
I've considered drools, however I wasn't sure the task was complicated enough for drols.
Example rules:
All currency (data in specific columns) must not contain currency symbols.
Category names must be uniform (e.g. book case = bookcase)
Entry dates can not be future dates
Text input can only contain [A-Z 0-9 \s]
etc..
Additionally if any column of information is invalid it needs to be reported when
processing is complete
(or maybe stop processing).
My current solution works. However I think there is room for improvement so I'm looking
for ideals as to how it can be improved and or how other people have handled similar
situations.
I've considered (very briefly) using drools but I wasn't sure the work was complicated enough to take advantage of drools.
If I didn't care to do this in 1 step (as Oli mentions), I'd probably use a pipe and filters design. Since your rules are relatively simple, I'd probably do a couple delegate based classes. For instance (C# code, but Java should be pretty similar...perhaps someone could translate?):
interface IFilter {
public IEnumerable<string> Filter(IEnumerable<string> file) {
}
}
class PredicateFilter : IFilter {
public PredicateFilter(Predicate<string> predicate) { }
public IEnumerable<string> Filter(IEnumerable<string> file) {
foreach (string s in file) {
if (this.Predicate(s)) {
yield return s;
}
}
}
}
class ActionFilter : IFilter {
public ActionFilter(Action<string> action) { }
public IEnumerable<string> Filter(IEnumerable<string> file) {
foreach (string s in file) {
this.Action(s);
yield return s;
}
}
}
class ReplaceFilter : IFilter {
public ReplaceFilter(Func<string, string> replace) { }
public IEnumerable<string> Filter(IEnumerable<string> file) {
foreach (string s in file) {
yield return this.Replace(s);
}
}
}
From there, you could either use the delegate filters directly, or subclass them for the specifics. Then, register them with a Pipeline that will pass them through each filter.
I think your method is OK. Especially if you use the same interface on every processor.
You could also look to somethink called Drules, currently Jboss-rules. I used that some time ago for a rule-heavy part of my app and what I liked about it is that the business logic can be expressed in for instance a spreadsheet or DSL which then get's compiled to java (run-time and I think there's also a compile-time option). It makes rules a bit more succint and thus readable. It's also very easy to learn (2 days or so).
Here's a link to the opensource Jboss-rules. At jboss.com you can undoubtedly purchase an offically maintained version if that's more to your companies taste.
Just create a function to enforce each rule, and call every applicable function for each value. I don't see how this requires any exotic architecture.
A class for each rule? Really? Perhaps I'm not understanding the quantity or complexity of these rules, but I would (semi-pseudo-code):
public class ALine {
private int col1;
private int col2;
private int coln;
// ...
public ALine(string line) {
// read row into private variables
// ...
this.Process();
this.Insert();
}
public void Process() {
// do all your rules here working with the local variables
}
public void Insert() {
// write to DB
}
}
foreach line in csv
new ALine(line);
Your methodology of using classes for each rule does sound a bit heavy weight but it has the advantage of being easy to modify and expand should new rules come along.
As for loading the data bulk loading is the way to go. I have read some informaiton which suggests it may be as much as 3 orders of magnitude faster than loading using insert statements. You can find some information on it here
Bulk load the data into a temp table, then use sql to apply your rules.
use the temp table, as a basis for the insert into real table.
drop the temp table.
you can see that all the different answers are coming from their own experience and perspective.
Since we don't know much about the complexity and number of rows in your system, we tend to give advice based on what we have done earlier.
If you want to narrow down to a 1/2 solutions for your implementation, try giving more details.
Good luck
It may not be what you want to hear, it isn't the "fun way" by any means, but there is a much easier way to do this.
So long as your data is evaluated line by line... you can setup another worksheet in your excel file and use spreadsheet style functions to do the necessary transforms, referencing the data from the raw data sheet. For more complex functions you can use the vba embedded in excel to write out custom operations.
I've used this approach many times and it works really well; its just not very sexy.

Get Methods: One vs Many

getEmployeeNameByBatchId(int batchID)
getEmployeeNameBySSN(Object SSN)
getEmployeeNameByEmailId(String emailID)
getEmployeeNameBySalaryAccount(SalaryAccount salaryAccount)
or
getEmployeeName(int typeOfIdentifier, byte[] identifier) -> In this methods the typeOfIdentifier tells if identifier is batchID/SSN/emailID/salaryAccount
Which one of the above is better way implement a get method?
These methods would be in a Servlet and calls would be made from an API which would be provided to the customers.
Why not overload the getEmployeeName(??) method?
getEmployeeName(int BatchID)
getEmployeeName(object SSN)(bad idea)
getEmployeeName(String Email)
etc.
Seems a good 'many' approach to me.
You could use something like that:
interface Employee{
public String getName();
int getBatchId();
}
interface Filter{
boolean matches(Employee e);
}
public Filter byName(final String name){
return new Filter(){
public boolean matches(Employee e) {
return e.getName().equals(name);
}
};
}
public Filter byBatchId(final int id){
return new Filter(){
public boolean matches(Employee e) {
return e.getBatchId() == id;
}
};
}
public Employee findEmployee(Filter sel){
List<Employee> allEmployees = null;
for (Employee e:allEmployees)
if (sel.matches(e))
return e;
return null;
}
public void usage(){
findEmployee(byName("Gustav"));
findEmployee(byBatchId(5));
}
If you do the filtering by an SQL query you would use the Filter interface to compose a WHERE clause.
The good thing with this approach is that you can combine two filters easily with:
public Filter and(final Filter f1,final Filter f2){
return new Filter(){
public boolean matches(Employee e) {
return f1.matches(e) && f2.matches(e);
}
};
}
and use it like that:
findEmployee(and(byName("Gustav"),byBatchId(5)));
What you get is similar to the Criteria API in Hibernate.
I'd go with the "many" approach. It seems more intuitive to me and less prone to error.
I don't like getXByY() - that might be cool in PHP, but I just don't like it in Java (ymmv).
I'd go with overloading, unless you have properties of the same datatype. In that case, I'd do something similar to your second option, but instead of using ints, I'd use an Enum for type safety and clarity. And instead of byte[], I'd use Object (because of autoboxing, this also works for primitives).
The methods are perfect example for usage of overloading.
getEmployeeName(int batchID)
getEmployeeName(Object SSN)
getEmployeeName(String emailID)
getEmployeeName(SalaryAccount salaryAccount)
If the methods have common processing inside, just write one more getEmplyeeNameImpl(...) and extract there the common code to avoid duplication
First option, no question. Be explicit. It will greatly aid in maintainability and there's really no downside.
#Stephan: it is difficult to overload a case like this (in general) because the parameter types might not be discriminative, e.g.,
getEmployeeNameByBatchId(int batchId)
getEmployeeNameByRoomNumber(int roomNumber)
See also the two methods getEmployeeNameBySSN, getEmployeeNameByEmailId in the original posting.
I will use explicit method names. Everyone that maintains that code and me later will understand what that method is doing without having to write xml comments.
Sometimes it can be more conveniant to use the specification pattern.
Eg: GetEmployee(ISpecification<Employee> specification)
And then start defining your specifications...
NameSpecification : ISpecification<Employee>
{
private string name;
public NameSpecification(string name) { this.name = name; }
public bool IsSatisFiedBy(Employee employee) { return employee.Name == this.name; }
}
NameSpecification spec = new NameSpecification("Tim");
Employee tim = MyService.GetEmployee(spec);
I would use the first option, or overload it in this case, seeing as you have 4 different parameter signatures. However, being specific helps with understanding the code 3 months from now.
Is the logic inside each of those methods largely the same?
If so, the single method with identifier parameter may make more sense (simple and reducing repeated code).
If the logic/procedures vary greatly between types, a method per type may be preferred.
As others suggested the first option seems to be the good one. The second might make sense when you're writing a code, but when someone else comes along later on, it's harder to figure out how to use code. ( I know, you have comments and you can always dig deep into the code, but GetemployeeNameById is more self-explanatory)
Note: Btw, usage of Enums might be something to consider in some cases.
In a trivial case like this, I would go with overloading. That is:
getEmployeeName( int batchID );
getEmployeeName( Object SSN );
etc.
Only in special cases would I specify the argument type in the method name, i.e. if the type of argument is difficult to determine, if there are several types of arguments tha has the same data type (batchId and employeeId, both int), or if the methods for retrieving the employee is radically different for each argument type.
I can't see why I'd ever use this
getEmployeeName(int typeOfIdentifier, byte[] identifier)
as it requires both callee and caller to cast the value based on typeOfIdentifier. Bad design.
If you rewrite the question you can end up asking:
"SELECT name FROM ... "
"SELECT SSN FROM ... "
"SELECT email FROM ... "
vs.
"SELECT * FROM ..."
And I guess the answer to this is easy and everyone knows it.
What happens if you change the Employee class? E.g.: You have to remove the email and add a new filter like department. With the second solution you have a huge risk of not noticing any errors if you just change the order of the int identifier "constants".
With the first solution you will always notice if you are using the method in some long forgotten classes you would otherwise forget to modify to the new identifier.
I personally prefer to have the explicit naming "...ByRoomNumber" because if you end up with many "overloads" you will eventually introduce unwanted errors. Being explicit is imho the best way.
I agree with Stephan: One task, one method name, even if you can do it multiple ways.
Method overloading feature was provided exactly for your case.
getEmployeeName(int BatchID)
getEmployeeName(String Email)
etc.
And avoid your second solution at all cost. It smells like "thy olde void * of C". Likewise, passing a Java "Object" is almost as poor style as a C "void *".
If you have a good design you should be able to determine if you can use the overloading approach or if you're going to run into a problem where if you overload you're going to end up having two methods with the same parameter type.
Overloading seems like the best way initially, but if you end up not being able to add a method in future and messing things up with naming it's going to be a hassle.
Personally I'd for for the approach of a unique name per method, that way you don't run into problems later with trying to overload the same parameter Object methods. Also, if someone extended your class in the future and implemented another void getEmployeeName(String name) it wouldn't override yours.
To summarise, go with a unique method name for each method, overloading can only cause problems in the long run.
The decoupling between the search process and the search criteria jrudolf proposes in his example is excellent. I wonder why isnt it the most voted solution. Do i miss something?
I'd go with Query Objects. They work well for accessing tables directly. If you are confined to stored procedures, they lose some of their power, but you can still make it work.
The first is probably the best in Java, considering it is typesafe (unlike the other). Additionally, for "normal" types, the second solution seems to only provide cumbersome usage for the user. However, since you are using Object as the type for SSN (which has a semantic meaning beyond Object), you probably won't get away with that type of API.
All-in-all, in this particular case I would have used the approach with many getters. If all identifiers have their own class type, I might have gone the second route, but switching internally on the class instead of a provided/application-defined type identifier.
stick all your options in an enum, the have something like the following
GetEmployeeName(Enum identifier)
{
switch (identifier)
case eBatchID:
{
// Do stuff
}
case eSSN:
{
}
case eEmailId:
{
}
case eSalary:
{
}
default:
{
// No match
return 0;
}
}
enum Identifier
{
eBatchID,
eSSN,
eEmailID,
eSalary
}
You are thinking C/C++.
Use objects instead of an identifier byte (or int).
My Bad, the overload approach is better and using the SSN as a primary key is not so good
public ??? getEmployeeName(Object obj){
if (obj instanceof Integer){
...
} else if (obj instanceof String){
...
} else if .... // and so on
} else throw SomeMeaningFullRuntimeException()
return employeeName
}
I think it is better to use Unchecked Exceptions to signaling incorrect input.
Document it so the customer knows what objects to expect. Or create your own wrappers. I prefer the first option.

Best way to return status flag and message from a method in Java

I have a deceptively simple scenario, and I want a simple solution, but it's not obvious which is "most correct" or "most Java".
Let's say I have a small authenticate(Client client) method in some class. The authentication could fail for a number of reasons, and I want to return a simple boolean for control flow, but also return a String message for the user. These are the possibilities I can think of:
Return a boolean, and pass in a StringBuilder to collect the message. This is the closest to a C-style way of doing it.
Throw an exception instead of returning false, and include the message. I don't like this since failure is not exceptional.
Create a new class called AuthenticationStatus with the boolean and the String. This seems like overkill for one small method.
Store the message in a member variable. This would introduce a potential race condition, and I don't like that it implies some state that isn't really there.
Any other suggestions?
Edit Missed this option off
Return null for success - Is this unsafe?
Edit Solution:
I went for the most OO solution and created a small AuthenticationResult class. I wouldn't do this in any other language, but I like it in Java. I also liked the suggestion
of returning an String[] since it's like the null return but safer. One advantage of the Result class is that you can have a success message with further details if required.
Returning a small object with both the boolean flag and the String inside is probably the most OO-like way of doing it, although I agree that it seems overkill for a simple case like this.
Another alternative is to always return a String, and have null (or an empty String - you choose which) indicate success. As long as the return values are clearly explained in the javadocs there shouldn't be any confusion.
You could use exceptions....
try {
AuthenticateMethod();
} catch (AuthenticateError ae) {
// Display ae.getMessage() to user..
System.out.println(ae.getMessage());
//ae.printStackTrace();
}
and then if an error occurs in your AuthenticateMethod you send a new AuthenticateError (extends Exception)
Avoid returning a "sentinel value", especially null. You will end up with a codebase where methods cannot be understood by the caller without reading the implementation. In the case of null, callers may end up with NullPointerExceptions if they forget (or don't know) that your method may return null.
The tuple suggestion from Bas Leijdekkers is a good one that I use all the time if I want to return more than one value from a method. The one we use is P2<A, B> from the Functional Java library. This kind of type is a joint union of two other types (it contains one value of each type).
Throwing Exceptions for control flow is a bit of a code smell, but checked exceptions are one way of getting more than one type of value from a method. Other, cleaner possibilities exist though.
You can have an Option<T> abstract class with two subclasses Some<T> and None<T>. This is a bit like a type-safe alternative to null, and a good way to implement partial functions (functions whose return value isn't defined for some arguments). The Functional Java library has a full-featured Option class that implements Iterable<T>, so you can do something like this:
public Option<String> authenticate(String arg) {
if (success(arg))
return Option.some("Just an example");
else
return Option.none();
}
...
for(String s : authenticate(secret)) {
privilegedMethod();
}
Alternatively, you can use a disjoint union of two types, as an Either<L, R> class. It contains one value which is either of type L or R. This class implements Iterable<T> for both L and R, so you can do something like this:
public Either<Fail, String> authenticate(String arg) {
if (success(arg))
return Either.right("Just an example");
else
return Either.left(Fail.authenticationFailure());
}
...
Either<Fail, String> auth = authenticate(secret);
for(String s : auth.rightProjection()) {
privilegedMethod();
}
for(Fail f : auth.leftProjection()) {
System.out.println("FAIL");
}
All of these classes, P2, Option, and Either are useful in a wide variety of situations.
Some more options:
Return an separate enum value for each type of failure. The enum object could contain the message
Return an int and have a separate method that looks up the appropriate message from an array
create a generic utility tuple class that can contains two values. Such a class can be useful in many more places.
simple tuple example, actual implementation may need more:
class Tuple<L, R> {
public final L left;
public final R right;
public Tuple( L left, R right) {
this.left = left;
this.right = right;
}
}
You could return a Collection of error messages, empty indicating that there were no problems. This is a refinement of your third suggestion.
I personally think creating a new class called AuthenticationStatus with the boolean and the String is the most Java like way. And while it seems like overkill (which it may well be) it seems cleaner to me and easier to understand.
Just because failed authentication is commonplace doesn't mean it isn't exceptional.
In my opinion, authentication failures are the poster-child use case for checked exceptions. (Well... maybe file non-existence is the canonical use case, but authentication failure is a close #2.)
I use the "tiny class" myself, usually with an inner class. I don't like using arguments to collect messages.
Also, if the method that might fail is "low level" - like coming from an app server or the database layer, I'd prefer to return an Enum with the return status, and then translate that into a string at the GUI level. Don't pass around user strings at the low level if you're ever going to internationalize your code, because then your app server can only respond in one language at a time, rather than having different clients working in different languages.
Is this the only method where you have such a requirement? If not, just generate a general Response class with an isSuccessful flag and a message string, and use that everywhere.
Or you could just have the method return null to show success (not pretty, and does not allow returning a success AND a message).
I would most probably go for something like :
class SomeClass {
public int authenticate (Client client) {
//returns 0 if success otherwise one value per possible failure
}
public String getAuthenticationResultMessage (int authenticateResult) {}
//returns message associated to authenticateResult
}
With this "design", you can ask for a message only when authentication fails (which I hope is the scenario that occurs 99,99% of time ;))
It may also be of good practice to delegate message resolution to another Class. But it depends of your application needs (mostly, does it need i18n ?)
This seems like a common idiom in other programming languages, but I cannot figure out which one ( C I guess as I read in the question ) .
Almost the same question is posted here and here
Attempting to return two values from a single function, may be misleading. But as it has been proved by the attempts of doing so, it may be very useful too.
Definitely creating and small class with the results should be the correct way to proceed if that is a common flow in the app as posted before.
Here's a quote about returning two values from a function:
As a matter of programming style, this idea is not
appealing in a object oriented programming language.
Returning objects to represent computation results
is the idiom for returning multiple values. Some
suggest that you should not have to declare classes
for unrelated values, but neither should unrelated
values be returned from a single method.
I've found it in a feature request for java to allow multiple return values
look at the "evaluation" section dated: 2005-05-06 09:40:08
Successful authentication should be the "normal" case, so an authentication failure is the exceptional case.
What are the different status strings for the user anyway. I can see only two, success or failure. Any further information is a potential security issue.
Another advantage of the solution with exceptions is that it cannot be called in the wrong way and the failure case is more obvious. Without exceptions, you write:
if (authenticate()) {
// normal behaviour...
}
else {
// error case...
}
You can accidently call the method ignoring the return value. The "normal behaviour" code is then executed without successful authentication:
authenticate();
// normal behaviour...
If you use exceptions, that cannot happen. If you decide to not use exceptions, at least name the method so that it is clear that it returns a state, e. g.:
if (isAuthenticated()) {
//...
}
There are a lot of good answers here so I will keep it short.
I think failure of a user to authenticate can be considered a valid case for a checked exception. If your style of programming favoured handling exceptions then there would be no reason not to do this. It also removes the "How to return multiple values from a method, my method does one thing It authenticates a user"
If you are going to return multiple values then spend 10 minutes creating a generic PairTuple (can also be more than a pair TripleTuple, I won't repeat the example listed above) and return your values that way.
I hate having small dto style objects to return various multiple values they just clutter the place.
How about returning a string. Empty or Null for success. Error Message in case of failure.
Simplest that would work. However not sure if it reads well.
Return the Object. It allows you to put additional functionality into the Class if you need it. Short lived objects in Java are quick to create and collect.
I would choose the Exception option in first place.
But, in second place, I would prefer the C-style technique:
public boolean authenticate(Client client, final StringBuilder sb) {
if (sb == null)
throw new IllegalArgumentException();
if (isOK()) {
sb.append("info message");
return true;
} else {
sb.append("error message");
return false;
}
}
This is not so strange and it's done in many places in the framework.
Instead of creating a special object for return type, I usually just return an array where all the returned information is stored. The benefit is that you can extend this array with new elements without creating new types and mess. The downside you have to know exactly what elements should present when array is returned from particular method to parse it correctly. Usually I agree on certain structure, like first element is always Boolean indication success, second is String with description, the rest is optional.
Example:
public static void main(String[] args)
{
Object[] result = methodReturningStatus();
if(!(Boolean)result[0])
System.out.println("Method return: "+ result[1]);
}
static Object[] methodReturningStatus()
{
Object[] result = new Object[2];
result[0] = false;
result[1] = "Error happened";
return result;
}

Categories

Resources