In my project I need to create objects for each kind of Java Math Operator like "Add", "Substraction", "Multiplication", etc. And these operators should be singletons.
So here is what I am going to do. I define the Math Operator as an interface and I put those implementations inside it as I don't want to define singleton classes for each operator.
public interface MathOperator {
double operate(double a, double b);
MathOperator ADD = new MathOperator(){
#Override
public double operate(double a, double b) {
return a + b;
}
};
MathOperator SUBSTRACT = new MathOperator(){
#Override
public double operate(double a, double b) {
return a - b;
}
};
}
I don't see much of such usage when I Google this. So I wonder if this is a good practice and if there are better and more graceful approaches?
I would do smt like
1) Define interface
interface MathOperator {
double operate(double a, double b);
}
2) Than have some common implementation in enum (less code)
enum MathOperators implements MathOperator {
ADD {
#Override
public double operate(double a, double b) {
return a + b;
}
},
SUBTRACT {
#Override
public double operate(double a, double b) {
return a - b;
}
}
}
3) Or public static members (more clean solution).
class MathOperators {
public static MathOperator ADD = new MathOperator() {
#Override
public double operate(double a, double b) {
return a + b;
}
};
public static MathOperator SUBTRACT = new MathOperator() {
#Override
public double operate(double a, double b) {
return a - b;
}
};
}
can create new MathOperator without changing MathOperators
have nice API for common operations
shouldn't write singletons
have nice clean interface
One idiom that I've seen used in precisely these circumstances is the use of enum:
public enum MathOperator {
ADD {
#Override
public double operate(double a, double b) {
return a + b;
}
},
SUBTRACT {
#Override
public double operate(double a, double b) {
return a - b;
}
};
public abstract double operate(double a, double b);
}
I use this pattern often, especially for specific implementations of generic interfaces. I find it works really well for me.
I like the way it puts the implementations where you can find them. I do it slightly differently - I make them static (it's a style thing, so the interface impls look more like class impls):
public interface MathOperator {
double operate(double a, double b);
public static MathOperator ADD = new MathOperator() {
#Override
public double operate(double a, double b) {
return a + b;
}
};
public static MathOperator SUBSTRACT = new MathOperator() {
#Override
public double operate(double a, double b) {
return a - b;
}
};
}
I don't see any problem with it. Take java.lang.String.CASE_INSENSITIVE_ORDER for instance. It is almost the same, except that
String is not an interface but a final class
The Comparator is not declared using an anonymous class, but using a static inner class, which is essentially the same
Personally, I don't like putting implementations within interfaces. I would either:
make MathOperator an enum
keep the interface but have a factory or a static class (say MathOperators) with the implementations
Why don't you define each implementation in its own class/file? This would make it clearer and would leave the interface clean.
Related
How is the following program correct?
abstract class Calculate
{
abstract int multiply(int a, int b);
}
public class Main
{
public static void main(String[] args)
{
int result = new Calculate()
{
#Override
int multiply(int a, int b)
{
return a*b;
}
}.multiply(12,32);
System.out.println("result = "+result);
}
}
We are changing the scope of the overridden method here.It is not public anymore and it should of default scope.Is the scope change of overridden method allowed?
You are creating an anonymous subclass in your current code, but you are very close to having a functional interface. Let's change it to that, like
#FunctionalInterface
interface Calculate {
int multiply(int a, int b);
}
Now you have a single abstract method and can use fancy lambdas. Like,
public static void main(String[] args) {
Calculate calc = (a, b) -> a * b;
int result = calc.multiply(12, 32);
System.out.println("result = " + result);
}
Note this is exactly like your original example, just syntactic sugar added with Java 8.
From your code, it multiply is not public to begin with. If you change your mulyiply method your Calculate class to
public abstract int multiply(int a, int b);
then it will not work.
According to your code, the calculate method is not in public scope, so you are not changing the scope.
abstract class Calculate {
public abstract int multiply(int a, int b);
}
public class MyClass {
public static void main(String[] args) {
int result = new Calculate() {
#Override
public int multiply(int a, int b) {
return a * b;
}
}.multiply(11,11);
System.out.println("result = " + result);
}
}
The access level cannot be more restrictive than the overridden method's access level. For example: If the super class method is declared public then the overriding method in the subclass cannot be either private or protected.
Now there is a separate scope as default scope introduced in java , so you can call it as package private scope.
For rules of overriding in java you can follow the Link
Say you have an interface which has a sum method, with two implementing classes A and B. Class A wants to sum two integers and class B wants to sum two long. What will be the implementation of interface C ?
class A implements C{
sum(2,3);
}
class B implements C {
sum(2.0,3.0);
}
How C should be implemented?
You can achieve this using a generic interface. For Example
interface C<T extends Number> {
T sum(T a, T b);
}
class A implements C<Long> {
#Override
public Long sum(Long a, Long b) {
return a+b;
}
}
class B implements C<Float> {
#Override
public Float sum(Float a, Float b) {
return a+b;
}
}
A generic interface can help you here. You can extend the Number class using Generics in Java
Interface
public interface BaseInterface<T extends Number> {
T sum(T a, T b);
}
Integer Implementation
public class ImplementationOne implements BaseInterface<Integer> {
#Override
public Integer sum(Integer a, Integer b) {
return a + b;
}
}
Double Implementation
public class ImpelementationTwo implements BaseInterface<Double> {
#Override
public Double sum(Double a, Double b) {
return a + b;
}
}
I have a class that performs some sort of (potentially redundant) validation logic on some number of arguments in the functions it contains. To demonstrate, I have the following Controller and ValidationHelper classes:
class ValidationHelper {
void validateA(int a, String b) { /*...*/ }
void validateB(int c, double d, String e) { /*...*/ }
void validateC(int f) { /*...*/ }
}
class Controller {
private ValidationHelper helper;
void foo(int a, String b, int f) {
this.helper.validateA(a, b);
this.helper.validateC(f);
// .. Rest of foo
}
void bar(int a, String b, int c, double d, String e) {
this.helper.validateA(a, b);
this.helper.validateB(c, d, e);
// .. Rest of bar
}
}
I'm wondering if there is a way to improve this validation architecture so any addition in validation logic wouldn't be as intrusive as the current implementation, and have validation become much cleaner? If this isn't achievable, would you have any suggestions if all the functions had the exact same validation statements? (e.g. both foo() and bar() containing ONLY this.helper.validateA(a,b)):
class Controller {
void foo(int a, String b, int f) {
this.helper.validateA(a, b);
// .. Rest of foo
}
void bar(int a, String b, int c, double d, String e) {
this.helper.validateA(a, b);
// .. Rest of bar
}
}
ValidationHelper is a code smell. You should be skeptical of any class ending in -ER.
I would implement this using validating decorators. Your example is a bit vague with all of the random meaningless variables, so let me invent my own.
interface CoffeeMachine
{
Coffee brew(Volume water, Volume milk);
}
class DarkRoastCoffeeMachine implements CoffeeMachine
{
public Coffee brew(Volume water, Volume milk) {
return new Coffee(Roast.DARK, water, milk);
}
}
But what if we want to enforce some constraints? Let's say there must be at least some quantity of water - we can't make coffee without water.
class WaterEnforcingCoffeeMachine implements CoffeeMachine
{
private CoffeeMachine delegate;
public WaterEnforcingCoffeeMachine(CoffeeMachine delegate) {
this.delegate = delegate;
}
public Coffee brew(Volume water, Volume milk) {
if (water.millilitres() < 50) {
throw new IllegalArgumentException("Must use more than 50ml of water");
}
return delegate.brew(water, milk);
}
}
You can then compose these like so:
CoffeeMachine coffeeMachine = new WaterEnforcingCoffeeMachine(
new DarkRoastCoffeeMachine()
);
Need additional validation? Add another decorator.
I'm learning Generics.I have written the following code just for practice. In this code I've created a single generic method for addition of two number and concatenation of two Strings as per values provided by the method call, it should be add the Integer or concatenate Strings.
class Kaushal28{
public <T> void add(T a, T b){
//System.out.println(a+b);
}
}
public class NewClass59 {
public static void main(String args[]){
Kaushal28 k = new Kaushal28();
k.add(5, 8);
k.add("5","8");
}
}
I'm not sure whether this can be done in a single method or not. If not then what can be the solution of this problem? Can I achieve this by use of generic class?
You can't have this as a generic method, but you can have a generic strategy:
interface Adder<T> { T add(T a, T b); }
and then specialize it for String and Integer:
class StringAdder implements Adder<String> {
#Override public String add(String a, String b) {
return a + b;
}
}
class IntegerAdder implements Adder<Integer> {
#Override public Integer add(Integer a, Integer b) {
return a + b;
}
}
You could then use this in a "single generic method" like this:
<T> void something(Adder<T> adder, T a, T b) {
System.out.println(adder.add(a, b));
}
something(new StringAdder(), "Hello", "World");
something(new IntegerAdder(), 1, 2);
or, of course:
System.out.println(new StringAdder().add("Hello", "World"));
System.out.println(new IntegerAdder().add(1, 2));
No it is not possible to have a generic method that covers every types so you will need to overload the method to support the target types, but here is a potential start that covers all Numbers and CharSequence:
class Kaushal28 {
public Number add(Number a, Number b){
return a.doubleValue() + b.doubleValue();
}
public CharSequence add(CharSequence a, CharSequence b){
StringBuilder sb = new StringBuilder(a.length() + b.length());
return sb.append(a).append(b).toString();
}
}
public class Kaushal28<T> {
public T add(T a, T b){
dynamic a1 = a;
dynamic b1 = b;
return a1+b1;
}
}
public class NewClass59
{
public static void Main(string[] args)
{
Kaushal28<int> ob =new Kaushal28<int>();
Console.WriteLine(ob.add(5,2));
Kaushal28<string> obj =new Kaushal28<string>();
Console.WriteLine(obj.add("5","2"));
}
}
Basically im coding a differential equation solver class that will take equations from an "Equation" Class and solve it using the rK4 method.
The main problem Im running into, is that I can't find a way to send a method to another class without extending and gaining acess through inheritance, or making a specefic instance of that Equation methods in my ODE class.
for example, how would I make the code below work? (remember I am not allowed to make a specific instance of Equation methods within the ODE class):
public class Equations {
public double pressureDrp( double a, double b) {
return a+b; //this is just a dummy equation for the sake of the question
}
public double waffles( double a, double b) {
return a-b; //this is just a dummy equation for the sake of the question
}
}
public class ODE {
//x being a method being passed in of "Equations" type.
public double rK4( Equation method x ) {
return x(3, 4);
//this would return a value of 7 from the pressureDrp method in class Pressure
//if I had passed in the waffles method instead I would of gotten a value of -1.
}
}
I would use an interface to encapsulate the concept of a binary method and to allow call-backs, something like:
interface BinaryEquation {
double operate(double d1, double d2);
}
This could then be placed in your equations class like so:
class Equations {
public static class PressureDrop implements BinaryEquation {
#Override
public double operate(double d1, double d2) {
return d1 + d2;
}
}
public static class Waffles implements BinaryEquation {
#Override
public double operate(double d1, double d2) {
return d1 - d2;
}
}
}
And used like so:
class ODE {
public double rk4(BinaryEquation eq) {
return eq.operate(3, 4);
}
}
Or better like so:
public class BinaryTest {
public static void main(String[] args) {
System.out.println("PressureDrop(3, 4): " + new Equations.PressureDrop().operate(3, 4));
System.out.println("PressureDrop(3, 4): " + new Equations.Waffles().operate(3, 4));
}
}