Java Builder Pattern pass to session JSP servlet - java

I just started learning and implementing builder patterns from Wiki. And also CH2 of Effective Java.
This pertains to JSP servlets, this might be a little convoluted, but I just wanted to pass this by you guys to see how to do this correctly.
Lets start with a scenario, where you can't build the object completely there are certain information that is not given. So most likely you have to put the object in session and then add variables to the session object later. How would I accomplish this with Build pattern?
Here is a code example
public class Widget(){
public static class Builder(){
public Builder(String id) {...}
public Builder serialNumber (String val) {...}
public Builder area (String val) {...}
public Widget build() { return new Widget(this); }
}
private Widget(Builder builder){...}
}
JSP Servlet 1 // only have ID information
Widget w = new Widget().Builder(id).build();
HttpSession session = request.getSession();
session.setAttribute("widget", w);
JSP Servlet 2 // Now I have serial and area
Widget.Builder w = (Widget.Builder) session.getAttribute("widget");
//** This is as far as I go **
w.serialNumber("something") // Now this works
.area("sideArea") //
.build() // < I know if I do this I will be creating another Object. Is there a way to use build pattern without creating redundant obj?
Thank you all...

w.serialNumber("something") // Can not find symbol
because serialNumber is not a method of the w object. What you're probably looking for is method chaining:
public class Widget {
... //assuming you have all the right fields here
public Widget setSerialNumber(String id) {
this.id = id;
return this;
}
public Widget setArea(String area) {
this.area = area;
return this;
}
public static class Builder(){
public Builder(String id) {...}
public Builder serialNumber (String val) {...}
public Builder area (String val) {...}
public Widget build() { return new Widget(this); }
}
private Widget(Builder builder){...}
}
then you can do something like this:
w.setSerialNumber(id).setArea(area);
Use Widget.Builder when you want to construct a new Widget object, and method chaining when you want to change an existing Widget object.

Related

Pass new object with the use of setter in method parameters

I'm trying to pass new Object as method parameter and set it's variable at the same time.
This an okay solution but big and not nice...
EventBox evtbox = new EventBox();
evtbox.setFloorColor(floorColor);
scriptUtils.runScript("sc-cfrmd",evtbox);
and I need something like this to shorten it up a bit
scriptUtils.runScript("sc-cfrmd",new EventBox().setFloorColor(floorColor));
of course, logical way of doing this is just creating a constructor in EventBox class but I need to figure out way without use of constructors.
any tips are appreciated
You are looking for fluent interface
Usually, when you need to create a complex object you are implementing fluent interface with builder design pattern
For example:
import java.awt.Color;
public class EventBox {
private Color floorColor;
private EventBox() {
this.floorColor = null;
}
public Color getFloorColor() {
return floorColor;
}
private void setFloorColor(Color floorColor) {
this.floorColor = floorColor;
}
public static EventBoxBuilder builder() {
return new EventBoxBuilder();
}
public static class EventBoxBuilder {
private final EventBox box;
EventBoxBuilder() {
this.box = new EventBox();
}
public EventBoxBuilder setFloorColor(Color color) {
box.setFloorColor(color);
return this;
}
public EventBox build() {
return box;
}
}
}
....
scriptUtils.runScript("sc-cfrmd",EventBox.builder().setFloorColor(floorColor).build());
If you are able to use Lombok Framwork, such builder can be automatically generated on compile time by adding #Builder annotation to the EventBox class
You can use method chaining by adding methods as desired. Conventionally, leave the setters/getters as the standard practice to just do what their name says.
public EventBox withFloorColor(String floorColor) {
setFloorColor(floorColor);
return this;
}
scriptUtils.runScript("sc-cfrmd",new EventBox().withFloorColor(floorColor));
The most basic and simple solution is of course to create a method like
EventBox createFloorEventBox( String floorColor ) {
EventBox eb = new EventBox();
eb.setFloorColor( floorColor );
return eb;
}
and use it like
scriptUtils.runScript("sc-cfrmd", createEventBox( floorColor ) );
Besides the builder pattern/method chaining/fluent approach, you could also consider using lambdas in Java, like
void runScript(String something, Consumer<EventBox> boxInitializer) {
EventBox eb = new EventBox();
initializer.apply(eb);
...
}
and then call this like
runScript("something", eb -> eb.setFloorColor( floorColor ));

Restrict access to only necessary data-class accessors / getters

I have a data class that is created in one class, and can be passed to one of several Android UI Activities that implement a specific Interface.
Each UI uses the same data, however, not all the UIs need all of the data. I was wondering if there was a simple solution that allows each UI to only use a specific part of the data (only use specific accessors / getters)
ClickListener Handler Class
// ICalculatorAbstraction is what all my UI's implement. It has method... void updateResult(ExpressionState expression)
public final View.OnClickListener listenerOn(final ICalculatorAbstraction UI) {
return listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Calculations
ExpressionState expression = new ExpressionState.Builder()
.setFirstNumber(num1)
.setSecondNumber(num2)
.setTotal(total)
.setOperator(operator.getSign())
.build();
UI.updateResult(expression);
}
};
}
ICalculatorAbstraction Interface
Again, all of my Android Activities (UIs) implement this interface
public interface ICalculatorAbstraction {
...
void updateResult(ExpressionState result);
}
Needs All Accessors UI
#Override
public void updateResult(ExpressionState result) {
String results = String.format( // NOTE: this one needs ALL the accessors / getters!!
"%s %s %s = %s",
result.getFirstNumber(),
result.getOperator(),
result.getSecondNumber(),
result.getTotal()
);
this.txtResult.setText(results);
Needs One Accessor UI
#Override
public void updateResult(ExpressionState result) {
String results = String.format( // NOTE: this one needs ONE accessor / getter!!
"Wow. Such Calcuation. %s",
result.getTotal()
// NOTE: These should not be allowed in this instance because this UI does not use them
// result.getFirstNumber()
// result.getOperator()
// result.getSecondNumber()
);
this.txtResult.setText(results);
How can I change updateResult(...) (both in the interface and in the UI) so that the specific UI's updateResult(...) will only let me use the needed assessors / getters?
I have tried to create a blank interface, and then created 2 abstract classes that implement that blank interface. The abstract classes had only the accessors / getters I needed, but when I tried to modify the above code, nothing worked.
Is this possible?
Update
Here is what I would like to see - "my best possible solution" you can say.
Needs All Accessors UI
#Override
public void updateResult(IAllAccessors result) {
String results = String.format(
"%s %s %s = %s",
result.getFirstNumber(),
result.getOperator(),
result.getSecondNumber(),
result.getTotal()
);
this.txtResult.setText(results);
Needs One Accessor UI
#Override
public void updateResult(IOneAccessorOnly result) {
String results = String.format(
"Wow. Such Calcuation. %s",
result.getTotal() // I should not be able to do result.getFirstNumber(); for example
);
this.txtResult.setText(results);
ExpressionState / Builder Class
public class ExpressionState implements IOneAccessorOnly, IAllAccessors {
private ExpressionState(Builder builder) { ... }
public double getFirstNumber() { ... } // IAllAccessors
public double getSecondNumber() { ... } // IAllAccessors
public String getOperator() { ... } // IAllAccessors
public double getTotal() { ... } // IAllAccessors, IOneAccessorOnly
public static class Builder { ... }
}
The problem with this solution, is that I cannot figure out what to do with my interface that I have above! I cannot have a parameter that will make the compiler happy with both UIs.
Update 2
I cannot have...
In my ClickListener class when creating ExpressionState with the builder
IOneAccessorOnly var = new ExperssionState.Builder()...
This is because in my ClickListener class, I don't know which one to create. It has to be very generic. In my UI's I want to simplify what I can use. I cannot do that with this approach
Because it does not know what to be, it has to be "everything"
ExpressionState var = new ExpressionState.Builder()...
It really cannot be anything other than that. The solution will have to deal with the UIs (Activities) specifically to narrow down what is allowed!!
If Expression state is your own class I'd make it implement two different interfaces like so.
public class ExpressionState implements InterfaceOne, InterfaceTwo {
public void interfaceOneGetterMethod()
public void interfaceTwoGetterMethod()
}
in another file:
public interface InterfaceOne {
public void interfaceOneGetterMethod();
and final file:
public interface InterfaceTwo {
public void interfaceTwoGetterMethod();
Now when you create the ExpressionState objects assign them to objects defined as:
InterfaceTwo var = new ExperssionState(blah);
Or modify your builder to just return interfaces( even better )

Possibility to call nonstatic gwt java method from javascript

General Aim: call some nonstatic java method from javascript
Description:
To find gwt's widget on DOM in Java Applet code and call it's java method(non static)
JSObject win = JSObject.getWindow(this);
JSObject doc = (JSObject) win.getMember("document");
JSObject gwtWidget = (JSObject) doc.call("getElementsByName", widgetName);
//todo: have possibility to call `exported` java method over here, smth like:
//Object[] params = new Object[1];
//params[0] = widgetName;
//Object result = gwtWidget.call("exportedJavaMethod", params);
//todo: or just call global ($wnd) static JSNI bridge method:
//Object result = win.call("exportedJavaMethod", params);
//
The problem is: I can find by widget's id not the widget, but it's DivElement which does not have any exported instanced methods.
My widget class is Exportable (gwt-export):
#Export(value="somewidget")
public class SomeWidget extends SimplePanel implements ..., Exportable {
private final String id = "id_some_widget_" + count++;
private static int count = 0;
public SomeWidget () {
getElement().setAttribute("name", id);
getElement().setId(id);
}
...
public static Element getInstanceById(String elementId) {
Element someWidget= DOM.getElementById(elementId);
return someWidget;
}
public String getSomeInstancedData() {
return "useful_inner_data" + this.id;
}
So, for example I'd like to find the concrete widget added to DOM and call nonstatic method getSomeInstancedData() in javascript. Is it possible at all?
Suppose smth like:
var someWidget = document.getElementById(widgetId);
alert(someWidget.getSomeInstancedData());
//or:
var someWidgetExported = com.mypackage.widgets.somewidget.getInstanceById(listenerId);
alert(someWidgetExported.getSomeInstancedData());
In Base module I write:
ExporterUtil.exportAll();
There is a View(ViewWithSomeWidget.ui.xml) that contains this widget:
...
base:Form
base:SomeWidget ui:field="someWidget" ...
...
/base:SomeWidget
...
When SomeWidget does not implement Exportable, project runs well, but I couldn't call nonstatic methods of found widget's DIV element.
By the time, to solve the problem SomeWidget implements Exportable, but progect doesn't show View with the SomeWidget well because of ClassCastException using deferred binding:
ClassCastException: com.mypackage.widgets.SomeWidgetExporterImpl cannot be cast to com.mypackage.widgets.SomeWidget
So, probably there are any other methods to find widget's javascript object and call it's exported java method? In any ways, any idea is much appreciated.
You can declare a javascript function, which will fire the non-static method.
For example:
package com.example;
public class Layout extends VLayout() {
private String nonStaticVar = "nonStaticVar";
public Layout() {
declareMethod(this);
}
//Method which declares non-static method in javascript
public native void declareMethod(Layout layout) /*-{
var layout = layout;
$wnd.doSomething = function(someString) {
layout.#com.example.Layout::doSomething(Ljava/lang/String;)(someString);
}
}-*/;
//Non static method which is being called
public String doSomething(String someString) {
//Do something, e.g. set var in this instantiated class, or output stuff
this.nonStaticVar = someString;
Window.alert(someString);
}
}
Now, calling
doSomething("bla");
from javascript will call your non-static method.
you can define an own jsmethod on the div element, that can call a widget-method
#Export(value="somewidget")
public class SomeWidget extends SimplePanel implements ..., Exportable {
private final String id = "id_some_widget_" + count++;
private static int count = 0;
public SomeWidget () {
getElement().setAttribute("name", id);
getElement().setId(id);
attachInstanceHook(getElement());
}
...
public String getSomeInstancedData() {
return "useful_inner_data" + this.id;
}
private native void attachInstanceHook(Element element) /*-{
var elem = element;
var widget = this;
elem.getWidgetData = function () {
widget.#your.package.name.SomeWidget::getSomeInstancedData()();
};
}-*/;
and your js-code should look like this:
var someWidget = document.getElementById(widgetId); //the id of the div element
alert(someWidget.getWidgetData());
instead of trying to fetch the widget through its DOM element, inject its Java instance first to the global scope and refer to it:
public class SomeWidget extends SimplePanel implements ..., Exportable {
//...
public SomeWidget () {
getElement().setAttribute("name", id);
getElement().setId(id);
attachToGlobalScope(id, this);
}
private native void attachToGlobalScope(String id, SomeWidget instance) /*-{
$wnd.shared[id] = instance;
}-*/;
//...
}
than later, update the corresponding fetch in the Applet API layer:
JSObject win = JSObject.getWindow(this);
JSObject shared = (JSObject) win.getMember("shared");
Widget widgetRef = (Widget) shared.getMember(widgetId);
disclaimer: this somewhat crooked solution relays on JavaScript global scope variables, which is considered bad practice in general, but here acts as the only common scope, thus abused for objects storage.

How to have a method have different input types java

I have a program on my computer that simulates a server on the internet and the fake server needs to be able to send multiple data types to some classes. Like for instance at one point of the program the server needs to send an int to a class then convert that int to a string and send it to another.
Basically what I am asking is if a method can have multiple data types for an input(Does this make sense? if not ill try to explain better). Is there any way to do this without creating many different methods?
Edit: Also is there a way to tell the difference between the types passed in (to prevent errors)
You can have a method which takes Object which is any type. In Java 5.0 and later primitives will be auto-boxed and passed as an object as well.
void method(Object o);
can be called using
method(1);
method("hello world");
method(new MyClass());
method(null);
If I understand correctly, you're asking if a method foo() can have multiple different inputs for its parameters
That way foo(Integer i) and foo(String s) are encased in the same method.
The answer: yes, but it's not pretty
foo(Object o)
Is your method declaration
Now you need to sort out the different types of possibilities
if(o instanceof Integer){
stuff();
} else if (o instanceof String){
moreStuff();
}
Just chain those else/if statements for the desired result.
What you want are Generic methods or classes.
to check what type an object is you'll have to use the 'instanceof' method
you can either make an entire class generic or just a single method, an example of a generic class:
package javahowto;
public class Member<T> {
private T id;
public Member(T id) {
this.id = id;
}
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
public static void main(String[] args) {
Member<String> mString = new Member<String>("id1");
mString.setId("id2");
System.out.printf("id after setting id: %s%n", mString.getId());
//output: id after setting id: id2
Member<Integer> mInteger = new Member<Integer>(1);
mInteger.setId(2);
System.out.printf("id after setting id: %d%n", mInteger.getId());
//output: id after setting id: 2
}
Now you now what to look for I'm sure you'll find the best solution to your problem.
check out:
http://download.oracle.com/javase/tutorial/java/generics/index.html
http://en.wikipedia.org/wiki/Generics_in_Java
...
Well I have also wondered and wrote below block. I think instanceof better but I tried getclass.
public static void main(String[] args){
System.out.println(method("This is a test"));
}
private static String method(Object o){
System.out.println(o.toString());
String status = "";
String className;
String[] oList = {"Double","Integer","String","Double","Float","Byte","Short","Long","Character","Boolean" };
for(int i = 0;i<oList.length;i++){
className = "java.lang." + oList[i];
Class testClass;
try {
testClass = Class.forName(className);
if(o.getClass().equals(testClass)){
status = "Your object is " + oList[i];
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return status;
}
You could use the "hashed adapter" pattern.
Public interface Adapter {
Public void handle(object o);
}
Public class StringAdapter implements Adapter {
Public void handle(String st) { // stuff ...
}
Public class IntegerAdapter implements Adapter {
Public void handle(Integer intgr) { // stuff ...
}
Private static final Map adapters = new HashMap();
Adapters.put(string.class, new stringAdapter());
Adapters.put(Integer.class, new IntegerAdapter());
Public void handleMe(Object o) {
Adapters.get(o.getClass()).handle(o);
}
Ive always liked this more than the ol' cascade of ifs and else's.
On my iPad so sorry about formatting and terseness and speellling.

remove duplication

I have a class contains 10 methods which are doing almost the same things apart from one key event. Two examples are given below:
Public String ATypeOperation(String pin, String amount){
doSomething();
doMoreStuff();
requestBuilder.buildATypeRequest(pin, amount);
doAfterStuff();
}
Public String BTypeOperation(String name, String sex, String age){
doSomething();
doMoreStuff();
requestBuilder.buildBTypeRequest(name, sex, age);
doAfterStuff();
}
As you can see from the above methods, they are similar apart from calling different methods provided by requestBuilder. The rest 8 are similar too. There is a lot duplicated code here. I feel there is a better way to implement this, but don’t know how. Any ideas and suggestions are appreciated.
Thanks,
Sarah
Use something like RequestBuilder, that accepts all these kinds of parameters:
public RequestBuilder {
// setters and getters for all properties
public Request build() {
doStuff();
Request request = new Request(this);
doAfterStuff();
return request;
}
}
and then
new RequestBuilder().setAge(age).setName(name).build();
What’s the nearest substitute for a function pointer in Java?
Function Pointers in Java
interface RequestBuilder {
void doStuff(params);
}
public RequestBuilder getARequestBuilder() {
return new RequestBuilder() {
void doStuff(params) {
// impl.details
}
}
}
public RequestBuilder getBRequestBuilder() {
return new RequestBuilder() {
void doStuff(params) {
// impl.details
}
}
}
public String buildRequest(yourParams, RequestBuilder builder){
doBefore();
builder.doStuff(yourParams);
doAfter();
}
I think this is called the Strategy pattern. It looks a lot like the Command pattern but because you encapsulate an algorithm it seems to be Strategy :)
What Bozho suggest is the Builder pattern.
I recommend you browse through a list of patterns some time, or buy Head First Patterns. Really fun reading.
You could pass the builder object to a generic buildRequest method. Since not only the algorithm but also the arguments vary, i put them into the builder. I dont think thats a nice solution but i wanted to show a command pattern here :D (Extraneon showed how to decouple params and command)
// call somewhere in the code:
Builder b = new BTypeBuilder();
b.age = "20"; b.sex = "female"; b.name = "eve";
String res = buildRequest(b);
Public String buildRequest(Builder builder)
{
doSomething();
doMoreStuff();
builder.build();
doAfterStuff();
}
// Command pattern
class BTypeBuilder implements Builder
{
String name, age, sex;
// Constructor here
void build()
{
// Do your stuff here
}
}
class ATypeBuilder implements Builder
{
String pin, amount;
// Constructor here
void build()
{
// Do your stuff here
}
}
public interface Builder
{
void build();
}
In addition to other answers, this might also be useful for you (If you want to just plugin your method, not using your parameters for 'before' and 'after' methods)
interface Function0<R> {
R apply();
}
public void performOperation(Function0<Void> operation) {
doSomething();
doBeforeStuff();
operation.apply();
doAfterStuff();
}
then you could use it like this,
final RequestBuilder builder = new RequestBuilder();
performOperation(new Function0<Void>() {
public Void apply() {
builder.buildATypeRequest("1234", "2445");
return null;
}
});
performOperation(new Function0<Void>() {
public Void apply() {
builder.buildBTypeRequest("1234", "2445", "1234");
return null;
}
});
Instead of sending a long parameter list just push all the parameters in a map and send that map as argument.

Categories