I have an interface with a few methods
public interface Turret {
void firePrimary();
void fireSecondary();
void reloadPrimary();
.......
}
I have implementation of it which has protected fields. In my implementation of the above methods I change the values of the protected fields.
#Override
public void firePrimary() {
if(shootablePriAmmo > 0) {
shootablePriAmmo--; //Shootable ammo is a protected field inside the implementation
}else{
reloadPrimary();
}
}
Now I am trying to test the fire primary method and check whether the shootablePriAmmo value was changed or not but since this is an interface implementation I cannot access the fields with interface methods and I don't want to write methods in interface for giving access to these fields as those methods won't be used anywhere else except for testing. If I write unit tests only on the implementation classes then I have to create public getters for these fields which I don't see is the correct way of doing it. What exactly should I do to overcome this? Am I violating any OOP principle?
EDIT
Here is the constructor of the implementation
public BasicTurret(int maxPriAmmo, int maxSecAmmo, int priAmmoCap, int secAmmoCap) {
this.maxPriAmmo = maxPriAmmo;
this.maxSecAmmo = maxSecAmmo;
this.curPriAmmo = priAmmoCap;
this.curSecAmmo = secAmmoCap;
this.priAmmoCap = priAmmoCap;
this.secAmmoCap = secAmmoCap;
this.shootablePriAmmo = priAmmoCap;
this.shootableSecAmmo = secAmmoCap;
}
Introduce ammo holder interface to encapsulate ammo manipulations and simplify testing
interface AmmoHolder {
getMax();
get/setCur(); // consume or reload
getShootable();
getCap();
}
class BasicTurret(AmmoHolder primary, AmmoHolder secondary) {
this.primaryAmmo = primary;
this.secondaryAmmo = secondary;
}
You could create an object that holds the state for your values that change from these methods. Then pass a mock in through a constructor.
Unit-tests are normally created for an implementation, not for an interface, so in your unit-test you need to instantiate a class you want to test as a reference to an implementation, not an interface (in your case - BasicTurret). Also unit-tests are usually placed to the same package as the original class, so they have access to protected fields/methods if necessary.
BasicTurret turret = new BasicTurret(.., .., 5, ..);
turret.firePrimary();
assertEquals(4, turret.shootablePriAmmo);
Related
In an abstract class I have a Predicate field, that is meant to be a combination of an unknown number of other Predicates. Joining the predicates works just fine but I am trying to have some way to know when the predicate has been initialized (or rather, just a way to know if it has or hasn't been initted).
Here is a short example of what I'm talking about:
public abstract class LimitedSystem implements Moveable {
private Predicate<Double> limits;
private final boolean initialized;
public void setLimits(SingleLimit... limits) {
List<Predicate<Double>> limitsList = Arrays.asList(limits);
this.limits = limitsList.stream().reduce(Predicate::and).orElse(x -> true);
}
public void setLimits(TwoLimits limits) {
this.limits = limits;
}
...
I am looking for ways to set initialized to true once (and once only, hence the final. I think I used it right) any of the setLimits have been called (they're overloaded).
I have other setLimits methods, but for the sake of generic code, I don't want to put a initialized at the end of each of the overloaded methods.
So my question is how can I, in a generic way, set the value of initialized after any of the setLimits methods has been called.
My first idea was to try to wrap the setLimits in some generic method which would call the correct overload by the parameter it gets, and then change initialized in that method. But I am not sure if that's a good idea.
Some other idea I got from another question1 was to put the setLimits in some interface or something similar. But I'm not sure how useful that might prove.
So how might this be accomplished?
(Also, if you happen to notice any design problems in this, please tell me because I'm trying to improve in that matter)
There's no need for separate fields:
private Predicate<Double> limits;
private final boolean initialized;
is basically
private Optional<Predicate<Double>> limits = Optional.empty();
if you want initialized to be set to true once limits is set,
provided you can guarantee that none of the setLimits methods can set it to Optional.empty() again. initialized == limits.isPresent().
You can't guarantee that a method is called in the body of an overridden method; in any case, this is a variant of the Call super antipattern.
You can do it like this:
abstract class Base {
final void setFoo(Object param) { // final, so can't be overridden.
setFooImpl(param);
thingThatMustBeCalled();
}
protected abstract void setFooImpl(Object param);
final void thingThatMustBeCalled() { ... }
}
class Derived extends Base {
#Override protected void setFooImpl(Object param) { ... }
}
But it's pretty ugly.
Here's the scenario:
public class A {
public A {}
void doSomething() {
// do something here...
}
}
Right now, the class is setup where you can create multiple instances. But I also see a need where I might want to restrict the class to only one instance, i.e. Singleton class.
The problem is I'm not sure how to go about the design of accomplishing both goals: Multiple instances and one instance. It doesn't sound possible to do in just one class. I imagine I'll need to use a derived class, an abstract class, interface, something else, or some combination.
Should I create class A as a base class and create a derived class which functions as the singleton class?
Of course, the first thing should always be to question the necessity to use singletons. But sometimes, they are simply a pragmatic way to solve certain problems.
If so, the first thing to understand is: there is no solution that can "enforce" your requirements and prevent mis-use, but here is a "pattern" that helps a lot by turning "intentions" into "meaningful" code:
First, I have an interface that denotes the functionality:
interface WhateverService { void foo() }
Then, I have some impl for that:
class WhateverServiceImpl implements WhateverService {
#Override
void foo() { .... }
Now, if I need that thing to exist as singleton, I do
enum WhateverServiceProvider implements WhateverService {
INSTANCE;
private final WhateverService impl = new WhateverServiceImpl();
#Override
void foo() { impl.foo() }
and finally, some client code can do:
WhateverService service = WhateverServiceProvider.INSTANCE;
service.foo()
(but of course, you might not want to directly assign a service object, but you could use dependency injection here)
Such architectures give you:
A clear separation between the core functionality, its implementation and the singleton concept
Guaranteed singleton semantics (if there is one thing that Java enums are really good for ... then it is that: providing fool-proof singletons!)
Full "testability" (you see - when you just use the enum, without making it available as interface ... then you have a hard time mocking that object in client code - as you can't mock enums directly).
Update - regarding thread safety:
I am not sure what exactly you mean with "singleton concept".
But lets say this: it is guaranteed that there is exactly one INSTANCE object instantiated when you use enums like that, the Java language guarantees that. But: if several threads are turning to the enum, and calling foo() in parallel ... you are still dealing with all the potential problems around such scenarios. So, yes, enum "creation" is thread-safe; but what your code is doing ... is up to you. So is then locking or whatever else makes sense.
I think you should take a look at this question:
Can a constructor in Java be private?
The Builder pattern described there could be a somewhat interesting solution:
// This is the class that will be produced by the builder
public class NameOfClassBeingCreated {
// ...
// This is the builder object
public static class Builder {
// ...
// Each builder has at least one "setter" function for choosing the
// various different configuration options. These setters are used
// to choose each of the various pieces of configuration independently.
// It is pretty typical for these setter functions to return the builder
// object, itself, so that the invocations can be chained together as in:
//
// return NameOfClassBeingCreated
// .newBuilder()
// .setOption1(option1)
// .setOption3(option3)
// .build();
//
// Note that any subset (or none) of these setters may actually be invoked
// when code uses the builer to construct the object in question.
public Builder setOption1(Option1Type option1) {
// ...
return this;
}
public Builder setOption2(Option2Type option2) {
// ...
return this;
}
// ...
public Builder setOptionN(OptionNType optionN) {
// ...
return this;
}
// ...
// Every builder must have a method that builds the object.
public NameOfClassBeingCreated build() {
// ...
}
// The Builder is typically not constructible directly
// in order to force construction through "newBuilder".
// See the documentation of "newBuilder" for an explanation.
private Builder() {}
}
// Constructs an instance of the builder object. This could
// take parameters if a subset of the parameters are required.
// This method is used instead of using "new Builder()" to make
// the interface for using this less awkward in the presence
// of method chaining. E.g., doing "(new Foo.Builder()).build()"
// is a little more awkward than "Foo.newBuilder().build()".
public static Builder newBuilder() {
return new Builder();
}
// ...
// There is typically just one constructor for the class being
// constructed that is private so that it may only be invoked
// by the Builder's "build()" function. The use of the builder
// allows for the class's actual constructor to be simplified.
private NameOfClassBeingCreated(
Option1Type option1,
Option2Type option2,
// ...
OptionNType optionN) {
// ...
}
}
Link for reference:
https://www.michaelsafyan.com/tech/design/patterns/builder
I am not sure that this is what you are looking for, but you can use Factory pattern. Create 2 factories, one will always return the same singleton, while the other one will create a new A object each time.
Factory singletonFactory = new SingetonFactory();
Factory prototypeFactory = new PrototypeFactory();
A a = singletonFactory.createA();
A b = singletonFactory.createA();
System.out.println(a == b); // true
A c = prototypeFactory.createA();
A d = prototypeFactory.createA();
System.out.println(c == d); // false
class A {
private A() {}
void doSomething() { /* do something here... */}
}
interface Factory {
A createA();
}
class SingetonFactory implements Factory {
private final A singleton = new A();
public A createA() {
return singleton;
}
}
class PrototypeFactory implements Factory {
public A createA() {
return new A();
}
}
i have my DTO class that is :
public class EmailResponse {
// Make public to avoid getters and setters
public Email email;
public RequestData reqData;
public EmailResponse() {
super();
}
}
and i want to implement to it this interface:
public interface IAssertionErrorDo {
public void onErrorDo();
}
but i want to do it during execution, i don't want to touch "EmailResponse" because it would not be ok to make it implements that interface due they don't belong to the same layer, i mean, EmailResponse would belong to service layer and IAssertionError would belong to test layer. I am using TestNG.
Do you know how i could do this? Regards
EDIT:
My implementation is this:
EmailResponse emailResponse = emailService.getUserEmail(userId);
And the reason i want to do this "injection" is because i have
public class LoggingAssert
extends Assertion {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingAssert.class);
private IAssertionErrorDo dataE;
#Override
public void onAssertFailure(IAssert a, AssertionError ex) {
LOGGER.info("[ERROR] " + a.getMessage());
if (this.dataE != null) {
this.dataE.onErrorDo();
}
}
public LoggingAssert setOnErrorDo(IAssertionErrorDo object) {
this.object = object;
return this;
}
}
loggingAssert.setOnErrorDo(emailResponse).assertNotNull(emailResponse.getEmail().getId(),
"Checking created email doesn't exists");
So i want to if assert fails execute method onErrorDo() from emailResponse
You could do
public class MyEmailResponse extends EmailResponse implements IAssertionErrorDo {
...
}
implementation calls in interfaces, you can call more than 1 interface if you want by adding commas to separate them..
to call interface methods you simply just use the method's name.
like this:
public class MyEmailResponse implements IAssertionErrorDo
{
public void onErrorDo() {//define it's behavior}
}
if you extend a class you use:
super.MyMethod()
to call the a method inside the extended class, but if you already have an extended class and want a method from another class you have to create an object for that class first then call it, thus:
MyClass mc = new MyClass();
if it is in a different package then
myPackage.MyClass mc = new myPackage.MyClass();
then you call your method from that class using the object you created, which is in this case mc.. so:
mc.MyMethod();
if you want it to return a variable then you will need to add a return statement in that method with the variable you want it to return.
interfaces are usually used for global an changing environments (dynamics), for example if you developed a program and it needs a driver to connect to databases then you will make an interface and send it to the database developers, and each one will fill the codes in that interface and send it back... this guarantees consistency.
when you implement an interface you have to define every method inside it (even if you leave it empty) and you cannot change the interface's methods names nor add... it is used in other areas as well, i don't think you need to use it in your case.
Can somebody help a novice programmer to understand if his solution is correct?
My question is similar to the the following two:
What's wrong with overridable method calls in constructors?
Factory pattern in C#: How to ensure an object instance can only be created by a factory class?
Problem: I want to have subclasses which will differ only in their initialisation method. However, I also want to prevent instantiating these classes without initialization. In other words, I want to ensure, that some "initialize()" method will always be called after instantiation of a subclass:
public abstract class Data {
protected Parameter dataSource;
Data(parameter1){
this.dataSource = parameter1;
loadData(); // should be called to initialise class fields and ensure correct work of other class methods
}
protected abstract loadData(){
... //uses dataSource
}
}
So I decided to perform initialization on a constructor. It worked (now I know that it's a very bad practice) until I created a subclass where the initialize method used some additional parameters:
public class DataFromSpecificSources extends Data {
private Parameter dataSource2;
public DataFromSpecificSources(parameter1, parameter2){
this.dataSource2 = parameter2; // I can't put it here because the constructor is not called yet
super(parameter1); // this, of course, will not work
}
#Override
private void loadData(){
... // uses both dataSource 1 and 2
// or just dataSource2
}
}
This, of course, is not going to work. And I started searching for a right pattern... After I read the answers on questions posted before, I decided to use the factory and limit visibility of the subclass constructor to the package:
My solution:
// factory ensures that loadData() method will be called
public class MyDataFactory(){
public Data createSubClass(parameter1,parameter2){
Data subClass;
if (parameter2 != null){
subClass = new DataFromSpecificSources(parameter1, parameter2);
subClass.loadData();
} else {
subClass = new AnotherSubClass(parameter1);
subClass.loadData()
}
return subClass;
}
}
public abstract class Data {
protected Parameter dataSource;
Data(parameter1){
this.dataSource = parameter1;
}
// I don't call it in constructor anymore - instead it's controlled within the factory
protected abstract loadData(){
... //uses dataSource
}
}
public class DataFromSpecificSources {
private Parameter dataSource2;
protected DataFromSpecificSources(){}
// now this constructor is only visible within package (only for the factory in the same package)
DataFromSpecificSources(parameter1, parameter2){
super(parameter1); // it does not initialise data anymore
this.dataSource2 = parameter2;
}
#Override
protected void loadData(){
... // uses dataSources 1 and 2
}
}
Now factory ensures that subclasses will be initialized (data will be loaded) and instantiation of subclasses is not allowed in other packages. Other classes have no access to constructor of subclasses and are forced to use factory to get an instance of a subclass.
I just wanted to ask if my solution is correct (logically) and Factory method with subclass constructor visibility limited to the package is right choice here?! Or there is any other more effective pattern solving the problem?!
Using a factory is definitely a step in the right direction. The issue I see is that what happens when you want to add a third class that takes a third parameter. Now your Factory is either going to have to have a second overloaded createSubClass method taking the third parameter, or all your code is going to have to be rewritten to provide the third parameter. Additionally you are forcing anyone using the Factory to specify null for the second parameter even if they only want the single parameter class.... when you get to the class that takes 15 parameters how are you going to remember which parameter is which
The solution to this is to use the Builder pattern instead.
public class MyDataBuilder(){
private parameter1 = null;
private parameter2 = null;
public MyDataBuilder withParameter1(parameter1) {
this.parameter1 = parameter1;
return this;
}
public MyDataBuilder withParameter2(parameter2) {
this.parameter2 = parameter2;
return this;
}
public Data createSubClass(){
Data subClass;
if (parameter2 != null){
subClass = new DataFromSpecificSources(parameter1, parameter2);
} else {
subClass = new AnotherSubClass(parameter1);
}
subClass.loadData();
return subClass;
}
}
Now the code creating the Data instances can work like so:
Data data = new MyDataBuilder().withParameter1(param1).withParameter2(param2).create();
or
Data data = new MyDataBuilder().withParameter1(param1).create();
And that code is future-proofed for when you add parameter3... and you can even have the builder with a non-null default for parameter3 if you so need that.
The next thing you notice is that you now have this nice Builder object that contains all the required parameters... so now you can add getters to the Builder and just pass the Builder as the constructor parameter, e.g.
public class DataFromSpecificSources {
...
DataFromSpecificSources(MyDataBuilder builder){
...
}
...
}
So that you now almost have a standard constructor signature
Now for some Java specific improvements. We can make the builder not need to know about the sub-classes at all!
Using a DI framework we can inject the classes that implement the Data interface / abstract class into the Builder and then just iterate through each class until we find a class that supports the configuration of the Builder instance.
The poor-man's DI framework is the /META-INF/services contract and the ServiceLoader class available since JRE 1.6 (though the core logic has been in Java since 1.2)
Your builder's create method will then look a little something like
public Data create() {
for (DataFactory factory: ServiceLoader.load(DataFactory.class)) {
if (factory.canCreate(this)) {
Data result = factory.newInstance(this);
result.loadData();
return result;
}
}
throw new IllegalStateException("not even the default instance supports this config");
}
Whether you want to go to that extreme is questionable... but since you might come across it at some point in time when looking at other people's code, it is probably a good time to point it out to you now.
Oh, the reason why we have to add a Factory class to be looked up by the ServiceLoader is because ServiceLoader expects to call the default constructor, and we have hidden the default constructor so we use a Factory class to do the work for us and allow us to keep the constructor hidden.
There is nothing preventing the Factory classes from being static inner classes in the Data classes (which gives them great visibility on the class they are creating), e.g.
public class UberData extends Data {
private UberData(MyDataBuilder config) {
...
}
public static class Factory extends DataFactory {
protected Data create(MyDataBuilder config) {
return new UberData(config);
}
protected boolean canCreate(MyDataBuilder config) {
return config.hasFlanges() and config.getWidgetCount() < 7;
}
}
}
As we can then list in META-INF/services/com.mypackage.DataFactory
com.mypackage.UberData.Factory
com.mypackage.DataFromSpecificSources.Factory
com.some.otherpackage.AnotherSubClass.Factory
The best bit about this type of solution is it allows adding additional implementations just by adding those implementations to the classpath at run-time... i.e. very loose coupling
So let's say I have a custom object in java:
public class TestObject {
private int value = 0;
public TestObject(int value) {
this.value = value;
}
public void increaseValue() {
value++;
}
}
Now I want to know when this object is modified. Or more specifically, I want to know when any of it's fields have changed (in this case value). Furthermore, if I extend TestObject, I still want to be able to listen to any field changes that might happen to that object, including if that change is to a new field new fields.
I've done some research and found of variety of listeners that come with java, but they all seem to fail in the area that they require you to put calls to the listeners at the end of you're methods. For example, increaseValue() would also have to notify all of the listeners to the TestObject that value had changed. Obviously this doesn't work for me because extensibility is a must have and I do not know that if people who inherit from that object will adhere to the requirement that they must notify listeners. Not to mention, it seems like a pain to have to program that for each mutator method
If any light could be shed on this subject it would be greatly appreciated.
You can use approach that Hibernate uses i.e. instrument/proxy your classes to add additional (listener) logic around your POJOs' getters and setters. But then you need to ensure that all use only proxied classes.
Not to mention, it seems like a pain to have to program that for each
mutator method
Take a look at The AspectJ Project. You could achieve this very easily with production aspect using a pointcut for field assignment.
public privileged aspect TestObjectObserver {
before(Object o) : set(* TestObject.*) && args(o) {
// notify listeners
}
}
// runs before field assignment to any field of TestObject. The value to be
// assigned is converted to an object type (int to Integer, for
// example) and named o in the body
// the aspect needs to be declared privileged so access private fields
Obviously this doesn't work for me because extensibility is a must
have and I do not know that if people who inherit from that object
will adhere to the requirement that they must notify listeners
Your approach is not in the correct path.
You can not enforce a derived class to keep the base's class invariants since inheritance can allow descendant classes to alter implementation in a way that makes them invalid from the viewpoint of the parent class.
In your case the derived class MAY or MAY not call the notification upon modification.
In cases like this you should model arround Composition and not Inheritence
Composition vs Inheritence
For your example:
class Value{
private int value;
public void increaseValue() {
value++;
}
}
Value knows how to increment itself.
class ValueHolder extends Observable {
private Value theValue;
public ValueHolder(Value v){
theValue = v;
}
public void modifyValue(String methodName)(){
Method method = theValue.getClass().getMethod(methodName, null);
method.invoke(theValue,null);//Since it has no args
setChanged();
notifyObservers();
}
}
So all the code will be as follows:
ValueHolder vh = new ValueHolder(new Value(10));
//registration of listeners
vh.modifyValue("increaseValue");
//So if you extend the Value
class DerivedValue extends Value{
private int y;
public void increaseY() {
y++;
}
}
ValueHolder vh = new ValueHolder(new DerivedValue());
//registration of listeners
vh.modifyValue("increaseY);
So the catch now is that the usage of the objects are via the holder.
Then the notification will happen.