If commons-pool2 can new object with parameter? - java

The create method of PooledObjectFactory has no parameter
https://commons.apache.org/proper/commons-pool/api-2.4.2/org/apache/commons/pool2/BasePooledObjectFactory.html#create--
If my Foo class definition is:
public class Foo {
private String name;
public Foo(String name) {
super();
this.name = name;
}
}
Can this Foo can be pooled by commons-pool ?
Thank you for any advice

Because objects cannot be created by abstract classes,
you need to extend BasePooledObjectFactory and implement its abstract methods.
By doing this, you can create your own class(for example, FooFactory) which contains a constructor with parameters.
After that, you can use your own class to instantiate objects(namely Foo).
Sample Code:
public class FooFactory extends BasePooledObjectFactory<Foo> {
private String name;
public FooFactory(String name) {
this.name = name;
}
#Override
public Foo create() throws Exception {
return new Foo(name);
}
}

Related

How do I minimize the amount of code for a hierarchy

This is for learning. I have an interface that is implemented by 2 classes, and I am supposed to reduce the amount of code I use in order to keep things more clean and less messy. Currently, the code looks like this:
public abstract class VClass implements IntFace {
protected String name;
public VClass(String name) {
this.name = name;
}
public int value (SClass sc) {//comes from a diff class
return sc.lookup(name);
}
public String getName() {
return name;
}
#Override
public String toString() {
return getName();
}
}
public abstract class NClass extends VClass implements IntFace {
public Number(String name) {
super(name);
this.name = name;
}
public int value (SClass sc) {
return sc.lookup(name);
}
public String getName() {
return name;
}
#Override
public String toString() {
return getName();
}
}
public interface IntFace {
public int value (SClass sc);
public String toString (int num);
}
can this code be more condensed?
You can remove the following things from your code:
implements IntFace from NClass declaration. Since NClass extends VClass, it implements IntFace as well.
this.name = name; from NClass constructor. name is initialized in a superclass constructor
value and getName methods from NClass. These methods are implemented in a superclass.
public modifier from interface methods declaration. Methods in interfaces are public by default.
Now you can also make name field private since it's no longer used in a NClass.

The best way for (no) argument constructor - ResponseBody - Spring

Let me introduce my code then I will ask a question.
This is just an example. I would like to learn something new if it is possbile.
BaseClass.java
public class BaseClass {
private String baseName;
BaseClass(String baseName){
this.baseName = baseName;
}
//getters and setters
}
MyClass.java
public class MyClass extends BaseClass {
private boolean isTest;
private String name;
MyClass(){
}
MyClass(String baseName){
super(baseName);
this.isTest = true;
}
//getters and setters
}
MyClassController.java
#Controller
public class MyClassController {
#GetMapping(value="/")
#ResponseBody
public String myClassController(#RequestBody MyClass myClass) {
return "index";
}
}
JSON request:
{
"name": "Name for BaseClass"
}
So, I send name e.g.: Name for BaseClass. I want to set this name for variable BaseName in BaseClass through constructor. #RequestBody needs no atribute constructor so I cannot use there this second constructor with arguments. I can handle this e.g. for using additional method:
Additional method in MyClass.java
public MyClass setValues(String baseName){
super(baseName);
this.isTest = true;
return this;
}
New MyController.java
#Controller
public class MyClassController {
#GetMapping(value="/")
#ResponseBody
public String myClassController(#RequestBody MyClass myClass) {
myClass.setValues(myClass.getName());
//more uses for myClass
return "index";
}
}
Is there any better way to do something like this in more "professional" way?
If you're married to the current inheritance structure, you can use HttpMessageConverter to customize the way Spring deserializes HTTP requests.
public class MyClassConverter extends AbstractHttpMessageConverter<MyClass> {
public MyClassConverter() {
super(new MediaType("text", "myClass"));
}
#Override
protected boolean supports(Class<?> clazz) {
return MyClass.class.isAssignableFrom(clazz);
}
#Override
protected MyClass readInternal(Class<? extends MyClass> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
// Deserialize JSON request
MyClass inputObject = new MyClass(name);
return inputObject;
}
#Override
protected void writeInternal(MyClass myClass, HttpOutputMessage outputMessage) {
// Serialize MyClass object
}
}
Detailed example
Although it's not clear I'm assuming name and baseName are meant to be the same value. In that case it might make sense for BaseClass to be an abstract class or interface.
abstract class:
public class MyClass extends BaseClass {
private String name;
// constructors
#Override
String getName() {
return name;
}
// setters
}
public abstract class BaseClass {
abstract String getName();
}
interface:
public class MyClass implements DtoWithName {
private String name;
// constructors
#Override
String getName() {
return name;
}
// setters
}
public interface DtoWithName {
String getName();
}
Also, I can't tell much about your use-case from the given example, but you should read into Composition over inheritance to make sure you're going about it the right way. With DTOs in particular usually simple is best.

POJO multiple-hierarchy Builder

I'm trying to achieve a hierarchy of builder with more than 3 levels.
Something like:
public abstract class ElementBuilder {
protected String name;
public ElementBuilder setName(String name) {
this.name = name;
return this;
}
}
public abstract class OperationBuilder extends ElementBuilder {
protected String attribute;
public OperationBuilder setName(String attribute) {
this.attribute = attribute;
return this;
}
}
public abstract class FilterBuilder extends OperationBuilder {
....
}
The problem is that when I call an operation of the super class it's returning a builder of the that class. I don't want to duplicate the setter method in each child, cause it maybe contain some logic.
I tried using generics but I could not achieve it in a clean way.

How can I add a protected method to a class implementing an interface in java?

I have a class called Property which has nothing but get-methods. All the fields will be set when a new instance of Propertyis created. Property implements an interface called IProperty.
Due to some bug in a library I use, I have to set the name of an instance of Property anew after its creation. Therefore it was suggested to create a WrapperPropertyclass that will provide a public setName-method which itself calls a therefore created setName()-method in Property, which will be protected/package view.
The problem is that I cannot make this method protected in Property, because Eclipse tells me to add it to the interface IProperty and make it public.
Is there some work-around to it?
WrapperIProperty:
public class WrapperIProperty {
private IProperty prop;
WrapperIProperty(Property prop) {
this.prop = prop;
}
public void setName(String name) {
prop.setName(name);
}
}
Property:
public class Property implements IProperty {
String name;
protected void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getFoobar() {
return 123;
}
public int getWhatever() {
return 987;
}
}
IProperty:
public interface IProperty {
public int getWhatever();
public int getFoobar();
public String getName();
}
This is how it looks at the moment. Obviously it won't work, since I cannot let the method be protected in the Property class. Therefore I best get rid of the interfacee entry somehow. But how?
What you probably want to do is to leave the IProperty interface alone (don't add the setName method to it) and create a delegating wrapper class which provides the method you want (wraps an implementation of the interface).
This way you can feed wrapped properties and regular properties to whatever needs them.
public class WrappedProperty implements IProperty {
private String name;
private Property prop;
WrappedProperty (Property prop) {
this.prop = prop;
}
protected void setName(String name) {
this.name = name;
}
public int getWhatever() {
return prop.getWhatever();
}
public int getFoobar() {
return prop.getFoobar();
}
public String getName() {
if (this.name == null) {
return prop.getName():
} else {
return this.name;
}
}
}
public class Property implements IProperty {
public String getName() {
return "blah";
}
public int getFoobar() {
return 123;
}
public int getWhatever() {
return 987;
}
}
public interface IProperty {
public int getWhatever();
public int getFoobar();
public String getName();
}
Methods in an Interface are public in scope so implementing class cannot override methods by reducing their accessibility. Make them public
You cannot have a public methodName in an Interface and a private or protected methodName in a Class implementing this Interface.
So you can have the methodName public in your Class :
this method do nothing
this method call [another]methodNameProtected (you give another name to a new protected method)
UPDATE
If you want it only in Interface you have to change your Interface in an AbstractClass and put in it the method
public final returnCode methodName if the method is common for all inherited classes
Found the solution to that problem:
WrapperIProperty :
public class WrapperIProperty {
private Property prop;
public WrapperIProperty(IProperty prop) {
this.prop = (Property) prop;
}
public void setName(String name) {
prop.setName(name);
}
}
Property:
public class Property implements IProperty {
private String name = null;
[...]
void setName(String name) {
this.name = name;
}
}
IProperty:
public interface IProperty {
[...]
}
This will do the job

Factory class design issue in java

I have two classes
public class PrepaidPackage {
private String name;
private String serviceClassID;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getServiceClassID() {
return serviceClassID;
}
public void setServiceClassID(String serviceClassID) {
this.serviceClassID = serviceClassID;
}
}
other class is
public class PostpaidPackage {
private String name;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I want to create a factory class which on base of package type create relevant class. But if you look at above clasess they dont have same type of methods and variables. So please guide how create interface or abstract class for above class?
Now factory will return class name Package. Would i able to call methods which are not present in other class.
Updates
Please suggest if i break my package into two classes like
public abstract class MyPackage {
public abstract PackageSpec getSpec();
public abstract PackagePrepaidDetails getDetail();
}
Now common attributes will be in PackageSpec and prepaid stuff in packageDetails.
Its kind of abstract factory pattern.
public class PrepaidPackage extends MyPackage{
PackageSpec spec;
public Spec getSpec() {
spec = new PackageSpec();
spec.setTranferable(true)
spec.setName("abc");
return spec;
}
public PackagePrepaidDetails getDetails() {
details = new PackagePrepaidDetails ();
details.setServiceClassID(123)
return details;
}
}
public class PostpaidPackage extends MyPackage{
PackageSpec spec;
public Spec getSpec() {
spec = new PackageSpec();
spec.setTranferable(true)
spec.setName("abc");
return spec;
}
}
I recomment you to have an interface if you don't have already. You do not neccessarily need it, but it is a good practice if they are so similar:
public interface Package {
public boolean isTranferable();
public void setTranferable(boolean isTranferable);
public String getName();
public void setName(String name);
}
Then in your calling code, you have a Package from your factory and:
Package p = myFactory.nextPackage(); // or something
if (p instanceof PrepaidPackage) {
PrepaidPackage prepaid = (PrefpaidPackage)p;
// and do the thing you want
} else if (p instanceof PostpaidPackage) {
PostpaidPackage postpaid = (PostpaidPackage)p;
// amd do the other things
}
Thing you are recommended to llok into is the instanceof operator and type casting.
A quick fix, not an ideal one is to have an interface that represents all the methods in the Prepaid class and leave them unimplemented in the Postpaid. That will solve the problem in the short term. I would suggest that you have a relook of the classes and the usages to avoid unimplemented methods in the code.
Well for an abstract super class you have to group everything common to both :
public abstract class MyPackage { // not sure you can call a class just "Package"
private String name;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
then both inherits from it (the first adds serviceClassID and the second nothing)
your factory function will return a MyPackage (or AbstractPackage, whatever), but to access the specific function you'll have to cast after an instanceof test.
Two possible design choices you can make:
Have the prepaid package extend
postpaid package and your factory
then returns objects of type
postpaid package, the code which
calls the factory is then
responsible for inspecting the type.
Have a package interface which
defines all of the methods and have
postpaid package define the methods
to throw an
UnsupportedOperationException (ala
the way collections defines some
operations as optional.) or return
some kind of sentinel value (i.e. null)
For either of the above you could add another method getType() which returns an enum of the various package types you wish to implement, and this could then be used in the code that accesses the factory objects to determine which methods are available.

Categories

Resources