I am trying to wrap my mind around how I would go about implementing this specific problem. We have an external API that performs some logic and returns back the result of that logic. Unfortunately, the API returns a new object as the result as opposed to just the part that I am interested in. For example, the code would look something like this:
public class ComplexObject {
//lots of fields
}
public interface LogicApplier {
LogicResult applyLogic(ComplexObject obj);
}
public class LogicResult {
ComplexObject result;
public ComplexObject getResult();
}
public class FirstImplementation {
private LogicApplier _applier;
public Implementation(LogicApplier applier) {
_applier = applier;
}
public ComplexObject mainImplementation (ComplexObject apply) {
LogicResult logicResult = _applier.applyLogic(apply);
ComplexObject newComplexObject = logicResult.getResult();
//Do some other stuff with new ComplexObject
}
}
So question is: what would be the best way to put a limit on LogicApplier's "power" over FirstImplementation? For example, our motivation to call logic in the first place is to derive a missing field, let's say "name". This field could potentially be different in, say, SecondImplementation where that implementation is now looking to derive "street address" from LogicApplier API. However, there is nothing to stop LogicApplier from changing some other field, say "idNumber".
Is this best solved by a adding an interface for our specific implementations and manually mapping fields? Something like:
public interface SecondImplementationLogicApplier {
public String deriveAddress(ComplexObject o);
}
public class LimitedImplementationLogicApplier implements FirstImplementationLogicApplier, SecondImplementationLogicApplier {
LogicApplier _applier;
public LimitedImplementationLogicApplier(LogicApplier applier) {
_applier = applier;
}
public String deriveFirstName(ComplexObject o) {
LogicResult res = _applier.applyLogic(o);
return res.firstName;
}
public String deriveFirstName(ComplexObject o) {
LogicResult res = _applier.applyLogic(o);
return res.address;
}
}
I think you are on right track with your LimitedImplementationLogicApplier. You should guard objects in your domain from possible corruption from the outside. Only update fields that you need.
It looks like your ComplexObject is mutable. I'd consider hiding it behind the immutable interface (that don't have any setters or way to change the object exposed) and pass immutable interface into your LimitedImplementationLogicApplier so its got no chance of mutating ComplexObject.
If your API requires ComplexObject type and you can't change that, to prevent mutation you could:
Option 1
Create a clone of your base ComplexObject instance and pass it into the API. After you've got the result back, you update the needed fields on untouched base instance. This will work nicely if ComplexObject is "thing in itself" and changes in its state does not have side effects outside of the class instance, like changing databases or affecting other state.
If mutation of ComplexObject has side effects or may have them in future then its a real trouble.
Option 2
Inherit a ReadonlyComplexObject class from ComplexObject and pass that into the API. In ReadonlyComplexObject you will suppress all the behavior of the parent to prevent modification.
This is hacky in my opinion and will create more work later - if ComplexObject will be extended with new properties later you will need to make changes to ReadonlyComplexObject otherwise mutation will still occur.
Related
I have a class whith some complex logic, so I decide to use the use method object several times to refactoring it .
Suppose a class like next:
public class MapperClass {
Entity entity = new Entity();
private final Item item;
public MapperClass(Item item) {
this.item = item;
}
public Entity getEntity() {
entity.setPrice(extractPrice());
//more long and complicated implementation
//mapped from item values
//entity.set....
//...
return entity;
}
private double extractPrice() {
double priceExtracted = 0d;
//Long and complicated implementation
//extracted from item
//...
return priceExtracted ;
}
private List<SubItem> getSubItemsMapped() {
//Long and complicated implementation
//extracted from item
//...
}
}
I refactor it to:
public class MapperClass{
private Entity entity = new Entity();
private final Item item;
public MapperClass(Item item) {
this.item = item;
}
public Entity getEntity() {
entity.setPrice(extractPrice());
entity.setSubEntities(getSubItemsMapped());
//more long and complicated implementation
//mapped from item values
//entity.set....
//...
return entity;
}
private double extractPrice() {
new PriceCalculator(item).getPrice();
}
private List<SubItem> getSubItemsMapped() {
new SubItemsMapper(item).getSubItems();
}
//More similar cases
}
So then I have a class whith several method objects which is cleaner than the one complicated class.
Then when I go to do my tests, I've got the doubt how to test this class.
Which is the best way to test a class with a method object?
Test only the class with the method objects
Test all classes, method object classes independently and then the class with method objects, all in deep.
Test all classes, but the method objects classes in deep, and the class with method objects with a simple class to check it is at least mapped by this method objects.
It has a bad design so rethink how to design it, and then test it.
Other options.
What is usually done in these cases?
You do what you always do when thinking about unit-testing:
You look at the public interface that class X is exposing. Meaning: which methods will be called on objects of that class; what are the parameters; what is the contract of each method.
You write test cases that fully cover the contract of each method.
That tells you: your "method classes" (I would rather call them "service classes") are subject for intensive unit testing; to make sure that the "service" they deliver ... is actually delivered.
For your MapperClass, you could theoretically re-use those testcases; as the "really public" contract is probably with that MapperClass.
But of course: that would mean "code duplication"; and if you think about it: that MapperClass only "needs" some kind of "plumbing test". Meaning: you only need to test that those method classes are correctly called to provide the required result. You do not need to run all your tests against the MapperClass.
When avoiding those calls to new in your methods in MapperClass (for example by turning the method objects into fields, and using constructor telescoping and dependency injection), then you could even use a mocking framework to simply check: when I call the "outer" method; the correct method object is invoked.
One caveat though: when you don't have that full "contract checking" suites for MapperClass and you later decide to refactor again then you are "broken". Because all that contract checking test code is "attached" to the specific "method class". So you would then have to move all those test to "MapperClass scope". So you should make that decision consciously (but I still advocate to not duplicate test code; and go for the solution outlined above - but you should understand this important consequence of that decision).
I often find I want to do something like this:
class Foo{
public static abstract String getParam();
}
To force a subclasses of Foo to return a parameter.
I know you can't do it and I know why you can't do it but the common alternative of:
class Foo{
public abstract String getParam();
}
Is unsatisfactory because it requires you to have an instance which is not helpful if you just want to know the value of the parameter and instantiating the class is expensive.
I'd be very interested to know of how people get around this without getting into using the "Constant Interface" anti pattern.
EDIT: I'll add some more detail about my specific problem, but this is just the current time when I've wanted to do something like this there are several others from the past.
My subclasses are all data processors and the superclass defines the common code between them which allows them to get the data, parse it and put it where it needs to go.
The processors each require certain parameters which are held in an SQL database. Each processor should be able to provide a list of parameters that it requires and the default values so the configuration database can be validated or initialised to defaults by checking the required parameters for each processor type.
Having it performed in the constructor of the processor is not acceptable because it only needs to be done once per class not once per object instance and should be done at system startup when an instance of each type of class may not yet be needed.
The best you can do here in a static context is something like one of the following:
a. Have a method you specifically look for, but is not part of any contract (and therefore you can't enforce anyone to implement) and look for that at runtime:
public static String getParam() { ... };
try {
Method m = clazz.getDeclaredMethod("getParam");
String param = (String) m.invoke(null);
}
catch (NoSuchMethodException e) {
// handle this error
}
b. Use an annotation, which suffers from the same issue in that you can't force people to put it on their classes.
#Target({TYPE})
#Retention(RUNTIME)
public #interface Param {
String value() default "";
}
#Param("foo")
public class MyClass { ... }
public static String getParam(Class<?> clazz) {
if (clazz.isAnnotationPresent(Param.class)) {
return clazz.getAnnotation(Param.class).value();
}
else {
// what to do if there is no annotation
}
}
I agree - I feel that this is a limitation of Java. Sure, they have made their case about the advantages of not allowing inherited static methods, so I get it, but the fact is I have run into cases where this would be useful. Consider this case:
I have a parent Condition class, and for each of its sub-classes, I want a getName() method that states the class' name. The name of the sub-class will not be the Java's class name, but will be some lower-case text string used for JSON purposes on a web front end. The getName() method will not change per instance, so it is safe to make it static. However, some of the sub-classes of the Condition class will not be allowed to have no-argument constructors - some of them I will need to require that some parameters are defined at instantiation.
I use the Reflections library to get all classes in a package at runtime. Now, I want a list of all the names of each Condition class that is in this package, so I can return it to a web front end for JavaScript parsing. I would go through the effort of just instantiating each class, but as I said, they do not all have no-argument constructors. I have designed the constructors of the sub-classes to throw an IllegalArgumentException if some of the parameters are not correctly defined, so I cannot merely pass in null arguments. This is why I want the getName() method to be static, but required for all sub-classes.
My current workaround is to do the following: In the Condition class (which is abstract), I have defined a method:
public String getName () {
throw new IllegalArugmentException ("Child class did not declare an overridden getName() method using a static getConditionName() method. This must be done in order for the class to be registerred with Condition.getAllConditions()");
}
So in each sub-class, I simply define:
#Override
public String getName () {
return getConditionName ();
}
And then I define a static getConditionName() method for each. This is not quite "forcing" each sub-class to do so, but I do it in a way where if getName() is ever inadvertently called, the programmer is instructed how to fix the problem.
It seems to me you want to solve the wrong problem with the wrong tool. If all subclasses define (can't really say inherit) your static method, you will still be unable to call it painlessly (To call the static method on a class not known at compile time would be via reflection or byte code manipulation).
And if the idea is to have a set of behaviors, why not just use instances that all implement the same interface? An instance with no specific state is cheap in terms of memory and construction time, and if there is no state you can always share one instance (flyweight pattern) for all callers.
If you just need to couple metadata with classes, you can build/use any metadata facility you like, the most basic (by hand) implementation is to use a Map where the class object is the key. If that suits your problem depends on your problem, which you don't really describe in detail.
EDIT: (Structural) Metadata would associate data with classes (thats only one flavor, but probably the more common one). Annotations can be used as very simple metadata facility (annotate the class with a parameter). There are countless other ways (and goals to achieve) to do it, on the complex side are frameworks that provide basically every bit of information designed into an UML model for access at runtime.
But what you describe (processors and parameters in database) is what I christened "set of behaviors". And the argument "parameters need to be loaded once per class" is moot, it completely ignores the idioms that can be used to solve this without needing anything 'static'. Namely, the flyweight pattern (for having only once instance) and lazy initialization (for doing work only once). Combine with factory as needed.
I'm having the same problem over and over again and it's hard for me to understand why Java 8 preferred to implement lambda instead of that.
Anyway, if your subclasses only implement retrieving a few parameters and doing rather simple tasks, you can use enumerations as they are very powerful in Java: you can basically consider it a fixed set of instances of an interface. They can have members, methods, etc. They just can't be instanciated (as they are "pre-instanciated").
public enum Processor {
PROC_IMAGE {
#Override
public String getParam() {
return "image";
}
},
PROC_TEXT {
#Override
public String getParam() {
return "text";
}
}
;
public abstract String getParam();
public boolean doProcessing() {
System.out.println(getParam());
}
}
The nice thing is that you can get all "instances" by calling Processor.values():
for (Processor p : Processorvalues()) {
System.out.println(String.format("Param %s: %s", p.name(), p.getParam()));
p.doProcessing();
}
If the processing is more complex, you can do it in other classes that are instanciated in the enum methods:
#Override
public String getParam() {
return new LookForParam("text").getParam();
}
You can then enrich the enumeration with any new processor you can think of.
The down side is that you can't use it if other people want to create new processors, as it means modifying the source file.
You can use the factory pattern to allow the system to create 'data' instances first, and create 'functional' instances later. The 'data' instances will contain the 'mandatory' getters that you wanted to have static. The 'functional' instances do complex parameter validation and/or expensive construction. Of course the parameter setter in the factory can also so preliminary validation.
public abstract class Processor { /*...*/ }
public interface ProcessorFactory {
String getName(); // The mandatory getter in this example
void setParameter(String parameter, String value);
/** #throws IllegalStateException when parameter validation fails */
Processor construct();
}
public class ProcessorA implements ProcessorFactory {
#Override
public String getName() { return "processor-a"; }
#Override
public void setParameter(String parameter, String value) {
Objects.requireNonNull(parameter, "parameter");
Objects.requireNonNull(value, "value");
switch (parameter) {
case "source": setSource(value); break;
/*...*/
default: throw new IllegalArgumentException("Unknown parameter: " + parameter);
}
}
private void setSource(String value) { /*...*/ }
#Override
public Processor construct() {
return new ProcessorAImpl();
}
// Doesn't have to be an inner class. It's up to you.
private class ProcessorAImpl extends Processor { /*...*/ }
}
classes:
public abstract class BaseHolidayPackageVariant {
private Integer variantId;
private HolidayPackage holidayPackage;
private String holidayPackageType;
}
public class LandHolidayPackageVariant extends BaseHolidayPackageVariant{
}
public class FlightHolidayPackageVariant extends BaseHolidayPackageVariant{
private Destination originCity;
}
public class HolidayPackage{
ArrayList<BaseHolidayPackageVariant> variants;
BaseHolidayPackageVariant defaultVariant;
}
At runtime, how can I know if a given Object in variants[] is of Type LandPackageVariant or FlightPackageVariant without doing something of the sorts of:
if(holidayPackageType.equals("LandHolidayPackageVariant")
obj = (LandHolidayPackageVariant)variant[i];
else if(holidayPackageType.equals("FlightHolidayPackageVariant")
obj = (FlightHolidayPackageVariant)variant[i];
This question stems from a design question I asked here
In a good object-oriented design, you shouldn't ever need to know if the object is of a particular type. You just call methods on it, and the object does the right thing.
For example, FlightHolidayPackageVariant has a field originCity that isn't in the other HolidayPackageVariant classes, and you want to render that in the UI. The object-oriented way to solve this is to make the HolidayPackageVariant responsible, in some way, for controlling its own rendering. Let's say your UI is going to show a list of properties for each variant. You can let the variants supply those lists:
public abstract class BaseHolidayPackageVariant {
private int cost;
public Map<String, String> getDetails() {
HashMap<String, String> details = new HashMap<String, String>();
details.put("cost", String.format("%.2f", cost / 100.0));
return details;
}
}
public class FlightHolidayPackageVariant extends BaseHolidayPackageVariant {
private Destination originCity;
#Override
public Map<String, String> getDetails() {
Map<String, String> details = super.getDetails();
details.put("origin city", originCity.getName());
return details;
}
}
Now, your UI code can simply ask each variant object for its details, without having to know what kind of variant it is.
try this:
if (variant[i] instanceof LandHolidayPackageVariant) {
LandHolidayPackageVariant obj = (LandHolidayPackageVariant)variant[i];
// do stuff
}
else if (variant[i] instanceof FlightHolidayPackageVariant) {
FlightHolidayPackageVariant obj = (FlightHolidayPackageVariant)variant[i];
// do other stuff
}
Note that if you also have types derived from one of those types, you should check for those first, as the upper checks would return true for that case, too.
A better approach might be to let the derived classes implement the required specific logic via defining appropriate methods to be overridden on the base class. That way you don't need to check for the types and can take full advantage of polymorphism.
like this:
if(object instanceof LandPackageVariant) {
System.out.println("it's a LandPackageVariant");
}
if(holidayPackageType.equals("LandHolidayPackageVariant")
obj = (LandHolidayPackageVariant)variant[i];
else if(holidayPackageType.equals("FlightHolidayPackageVariant")
obj = (FlightHolidayPackageVariant)variant[i];
Well doing this obj has to be a BaseHolidayPackageVariant so you don't even need to cast nor to do the if thingy.
If you want an object with the specific class Land or Flight to call a specific method, then maybe you should review your Object model.
You can use the instanceof operator for this:
if (variant[i] instanceof LandHolidayPackageVariant)
obj = (LandHolidayPackageVariant) variant[i];
However, usually you shouldn't need it. There are few good reasons to use instanceof to differentiate between classes, but usually the subclasses themselves should provide the different functionality needed through their common super class' interface.
You can use instanceof.
For example:
{
enter code here
if (variant[i] instanceof LandHolidayPackageVariant) {
//do something
} else if(variant[i] instanceof FlightHolidayPackageVariant){
//do something
}
}
Take a look at:http://www.java2s.com/Tutorial/Java/0060__Operators/TheinstanceofKeyword.htm
A better option would be to design you program so that you don't need the instanceof Operator.
Yeah, both answers here are - paradoxically - right.
Tom's answer that your question is dubious is on the ball. There generally isn't a reason to determine an object's specific type from other's in its hierarchy. (I mean outside of fancy reflection-uses)
Botz3000's answer is (like all the others that just appeared as i type) technically correct.
At a guess, you're working out which method to call in the class? In which case, use the #Override annotation, re-define the method in the child classes, and provide an abstract method in the parent (or a concrete version that does base things?)
From your class names, I suspect you should have a quick squiz at the Abstract Factory pattern and the (extremely simple) strategy pattern.
PS If you want to get fancy and use reflection, you can just call getClass() and check that. But there is, and I want to underscore this, no reason to do this, and it is bad practice. But there you are.
I am using an interface called Predicate which is used for sifting through Collections. For example, I can define
public class BlackCatPredicate implements Predicate<Cat> {
public boolean evaluate( Cat c ) {
return c.isBlack();
}
}
and then use some utility findAll( Collection<T> coll, Predicate<T> pred) method to apply the predicate to a collection of Cats, and get just the black ones, etc.
My question is this: I'm finding black cats all over my code, so there is no need to keep instantiating the BlackCatPredicate over and over again. It should just have one instance. (A singleton?) But then, over the course of writing many predicates, I don't want to have to implement each one as a singleton. So -- what is the proper design here?
I'd use an anonymous class constant and put it with the class it operates on:
public class Cat{
public static final Predicate<Cat> BLACK_PREDICATE = new Predicate<Cat>(){
public boolean evaluate( Cat c ) {
return c.isBlack();
}
};
// Rest of the Cat class goes here
}
If the predicate has parameters, you can use a static factory method.
Edit: As was pointed out in the comments, depending on the usage patterns, it may result in clearer code to collect the predicate constants (and/or factory methods) in a separate class, either only those for Cat, or all of them. It depends mainly on their number, how much additional organization is helpful.
Something like this should work:
class Predicates
{
private static class BlackCatPredicate implements Predicate<Cat>
{
public boolean evaluate(final Cat c)
{
return c.isBlack();
}
}
private static final BlackCatPredicate = new BlackCatPredicate();
public static Predicate<Cat> getBlackCatPredicate()
{
return (blackCatPredicate);
}
}
You could make a generic factory that takes any predicate as a type arg - and then generates a single instance for a given predicate type.
Another more general approach would be to start using a dependency injection library - and do all of your object creation through it. Typically you can switch a type to be a singleton, if appropriate, with little change.
I wouldn't worry about creating extra BlackCatPredicate instances at all.
If you don't like writing new BlackCatPredicate() all over the place you can certainly add a static factory method so you can write BlackCatPredicate.getInstance() instead. Yet another option would be to create a separate class so you can write CatPredicates.getBlackCatPredicateInstance().
However this is only for abstracting the creation of the predicate from the client code, it has nothing to do with actual object creation. Dealing with short-lived objects is one of the things the JVM does best, so creating a bunch of extra BlackCatPredicate instances and discarding them immediately won't affect your performance in the slightest.
I have a class called DataSet with various constructors, each specifying a different type of variable. It might look a bit like this:
public class DataSet
{
private HashSet Data;
public DataSet( DataObject obj )
{
Data = new <DataObject>HashSet();
Data.add( obj );
}
public DataSet( ObjectRelationship rel )
{
Data = new <ObjectRelationship>HashSet();
Data.add( rel );
}
// etc.
Note: I haven't yet gotten to test that code due to incomplete parts (which I'm building right now).
In a function that I'm currently building, getDataObjects(), I need to return all DataObject objects that this set represents. In the case of constructors that initiate the class's HashSet, Data with types other than DataObject (such as the above ObjectRelationship), there obviously won't be any DataObjects stored within. In this case, I need to be able to detect the type that the HashSet 'Data' was initiated with (like, to tell if it's 'ObjectRelationship' or not, I mean). How do I do this?
tl;dr: How do I tell the type that a Collection (in this case, a HashSet) was initiated with in my code (like with an 'if' or 'switch' statement or something)?
Sounds like you want to make the entire class generic- add a template parameter to the declaration for the class and define your HashSet and retrieval functions using that template parameter for the types.
I'm a .Net guy at the moment, though, so I couldn't give you the Java syntax, but using C# syntax it would look something like this:
public class DataSet<T>
{
private Set<T> Data;
public DataSet( T obj )
{
Data = new HashSet<T>();
Data.add( obj );
}
public Iterator<T> getDataObjects()
{
return Data.iterator;
}
}
You could fetch an object from the set and verify its type.
Or you could have multiple sets to contain different types.
Or you could have an instance variable of type Class to act as a discriminator as an instance variable.
Or you could create a proxy object for HashSet using the last technique.
You could use a map to the set
HashMap <Class<?>, HashSet<Object>> data;
HashSet temp = data.get(DataObject.class);
if(temp == null)
{
temp = new HashSet();
data.put(DataObject.class, temp);
}
temp.add(obj);
Then you will get the best of both worlds.
Sounds like your design needs to be re-thought.
Also, to be clear on Generics; you cannot access the type at runtime. The type parameter is only for compile-time checking and is completely gone (type erasure) at runtime.
What does this class offer that CachedRowSet does not?
Sorry, I don't consider this to be a very good abstraction. If I were a member of your team, I wouldn't use it.
Your syntax doesn't look correct to me, either. IntelliJ agrees with me: it won't compile.
This does:
import java.util.HashSet;
import java.util.Set;
import java.util.Arrays;
public class DataSet
{
private Set<DataObject> data;
public DataSet(DataObject obj)
{
this.data = new HashSet<DataObject>();
data.add(obj);
}
public DataSet(DataObject[] objs)
{
data = new HashSet<DataObject>();
data.addAll(Arrays.asList(objs));
}
// etc.
}
Still a poor abstraction. Rethink it.
You could add an property to your dataset class (an enumerated value, boolean or type) that specifies which type was used to initialize the hashset.
Set the property in the appropriate constructor. This allows you to bypass getting an element out of the collection to check its type.
pseudo-code:
public class DataSet
{
private HashSet Data;
private Type _iw = null;
public Type InitializedWith { return _iw; }
public DataSet(DataObject)
{
...
_iw = typeof(DataObject);
}
public DataSet(ObjectRelationship)
{
...
_iw = typeof(ObjectRelationship)
}
I'm going to follow duffymo's advice and just use better abstraction. I'm going to make multiple classes for each specific type I plan to use (each implementing a common interface) so that I can just bypass this dumb problem.
It'll add a minuscule bit of overhead during the process of creating each DataSet object of correct type, but I suppose that's just how it goes.
I don't know what DataObject gives you over and above an Object.
I think an object-oriented approach to your problem would use classes that reflected your domain of interest (e.g., Invoice, Customer, etc.). The persistence layer would hide the persistence details.
A common way to accomplish this is to use the Data Access Object, which might look like this in Java:
public interface GenericDao<T>
{
T find(Serializable id);
List<T> find();
void save(T obj);
void update(T obj);
void delete(T obj);
}
Now you're dealing with objects instead of things that smack of relational databases. All the CRUD details are hidden behind the DAO interface.