Factory methods and downcasting
I am having a class hierarchy and a factory method that creates the classes from this hierarchy. The factory method returns the root class of this hierarchy and every time I want to use a class specific method of one of the sub classes I will have to check the type of this class and cast to this class type. My question is now if there is a possibility to avoid the type checking and casting or if this is one of the few situations where type checking and casting is approriate. To illustrate the problem here is some code:
class Factory {
public static A create() {
if (//someCondition)
return new B();
else
return new C();
abstract class A {
public void commonMethod() {
// do stuff
public void polymorphicMethod();
class B extends A {
public void polymorphicMethod() {
// do something
public void specificBMethod() {
// do stuff that only B can do
class C extends A {
public void polymorphicMethod() {
// do some other thing
public void specificCMethod() {
// do stuff that only C can do
}Now I run into a situation where I have to downcast to the correct type.
class Worker {
public void work() {
A a = Factory.create();
if (a instanceof B) {
( (B) a).specificBMethod();
} else if (a instanceof C) {
( (C) a).specificCMethod();
} else {
// Error
}I think this problem always arises if you have a factory method that returns a class at the top of the hierarchy or a interface but you can not put all the methods that a client wants to call in this common class or interface. Is there a better a way to do this or is this already a good solution?
In my particular case I have an XML parser that
parses messages. I implemented each different message
type as a different class and the parser uses the
factory to create new message objects. The parser
then uses methods that are defined in the topmost
Message class and in an interface to set the
attributes of the object. Each message class
overrides a "handleXMLElement" method defining how to
deal with the message specific XML elements. So this
is fine the parser is the client of the factory and
he uses only methods that are defined in a common
class and an interface.
After a message has been read the message object is
forwarded to a hierarchy of message handlers. Of
course the message handlers know of the message class
hierarchy and want to access all methods of each
message object. But since the parser only knows about
the interface and the common class, the message
handlers will have to cast the message objects to the
concrete types.If the message type that's passed in has its behavior in the common interface, why is there a need to cast?
So the parser-factory relationship works well but the
(nasty) casting arises due to the later message
handling. Maybe your message handling needs redesign. Or perhaps a hierarchy of callback objects that let you customize that part that changes for each message.
I also remembered why I implemented it this
way. In the Desing Patterns book of Gamma et. al.
the Chain of Responsibility pattern can be
implemented this way using casts. So the solution
can't be that bad at all, I guess.Don't take that as gospel. GoF isn't perfection. Patterns can be misapplied.
@stefan: I can't pull all my methods from the
subclasses in one upper class, because the methods
are different and specialised for each sub class. I
don't think that it is good when one sub class knows
all the methods of all other sub classes.Maybe a callback object can help sort this out. I think you need a redesign to eliminate the casts. More thinking is required.
%
Similar Messages
-
What is a Factory method and when to use this concept?
Could any one please describe what a factory method is and explain how I can use it by giving a simple example
A Factory Method (sometimes called a "virtual constructor") is a way to avoid hard coding what class is instantiated. Consider:
DataSource myDataSource = new DataSource();Now, if you want to use some other DataSource in your app, say, an XMLDataSource, then you get to change this code and all subsequent lines that use this, which can be a lot. If, however, you specified and interface for your DataSources, say, IDataSource, and you gave the DataSource class a static "create" method that would take some indication of what sort of DataSource to actually use, then you could write code like:
IDataSource myDataSource = DataSource.create(dataSourceString);And be able to pass in a dataSourceString describing what DataSource you wanted to use - and not have to recompile. Check out the Java Design Patterns site ( http://www.patterndepot.com/put/8/JavaPatterns.htm )
Make sense?
Lee -
Spring factory-method and factory-bean
I have a singleton class which returns a Connection object by getDbConnection() method. I have created the bean of this class and declared getDbConnection() as a factory method. How do i access this factory method from other classes. No doubt I have created a second bean which uses the factory method of the first bean. How do i get the connection in my second class namely DbConnectionSingletonTest
package ioc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class DbConnectionSingleton{
public static Connection con = null;
private DbConnectionSingleton(){
public static Connection getDbConnection(){
if(con == null){
con = createConnection();
return con;
// public static void main(String[] args) {
// createConnection();
public static Connection createConnection() {
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("springfile.xml"));
DbConnection dbConnection = (DbConnection) factory.getBean("dbConnection");
HashMap dbProperties = dbConnection.getDbProperties();
try {
// con = DriverManager.getConnection ("jdbc:oracle:thin:@localhost:1521:bob", "scott", "tiger");
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
String host = (String) dbProperties.get("host");
String port = (String) dbProperties.get("port");
String dsn = (String) dbProperties.get("dsn");
String username = (String) dbProperties.get("username");
String password = (String) dbProperties.get("password");
Connection con = DriverManager.getConnection ("jdbc:oracle:thin:@"+host
+":"+port+":" +dsn, username, password);
if(con != null){
System.out.println("Connection established Successfully at port : "+port);
}else{
System.out.println("Could not establish Connection");
} catch (SQLException e) {
e.printStackTrace();
return con;
My springfile.xml code
[CODE]<?xml version="1.0"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework..org/dtd/spring-beans.dtd">
<beans>
<bean id = "point" class="ioc.Point">
<property name="x" value="10" />
<property name="y" value="-23" />
</bean>
<bean id = "dbConnectionSingleton" class="ioc.DbConnectionSingleton" factory-method="getDbConnection">
<property name="dbProperties">
<map>
<entry key = "username" value="scott" />
<entry key = "password" value="tiger" />
<entry key = "host" value="localhost" />
<entry key = "port" value="1521" />
<entry key = "dsn" value="bob" />
</map>
</property>
</bean>
<bean id = "dbConnectionSingletonTest" class="ioc.DbConnectionSingleton" factory-bean="dbConnectionSingleton" factory-method="getDbConnection">
</bean>
</beans>Message was edited by:
hemanthjava
Message was edited by:
hemanthjava
Message was edited by:
hemanthjavaOne of the goals of Spring is to help you eliminate the use of singletons. You might want to try looking for help on the Spring forums (http://forum.springframework.org) since there is no JSF-related content to your post.
-
Generics, factory methods and compiler warnings
Hi all,
I have a parametrized class where new objects are created via a factory. The problem is that I'm getting some compiler warnings. Am I missing something or there's no way to avoid them?
public interface Schedulable {
// methods here
public class Scheduler<T extends Schedulable> {
// should this be parameterized? If yes, how?
// (it's not possible to use T while <? extends Schedulable> gives problems)
private static Scheduler scheduler;
private NodeManager nodes;
private DefaultServiceManager<T> services;
private Timer timer;
private LifecycleManager lifecycle;
public static synchronized <E extends Schedulable> QueueScheduler<E> newInstance() {
if (scheduler == null) {
scheduler = new Scheduler();
scheduler.nodes = DefaultNodeManager.newInstance(scheduler);
scheduler.services = new DefaultServiceManager<E>(scheduler.nodes);
scheduler.timer = new Timer(scheduler);
scheduler.lifecycle = new LifecycleManager(scheduler,
scheduler.timer);
// these fields are initialized here and not into the constructor in order to avoid
// the 'this' reference to escape (see //http://www-128.ibm.com/developerworks/java/library/j-jtp07265/index.html
// for example)
// all the fields initialized above generate a warning
return scheduler;
protected Scheduler() {
// initialization of some fields here
// methods here
// methods here
}Thanks,
MicheleOops, sorry, didn't see the variable actually is a static, raw one. Here you will have a problem, as for once you cannot use the E for the static variable and second you could not guarantee that a previously created Scheduler would have the same type parameter as the one you are going to create:FirstSchedulable a = Scheduler.newInstance();
SecondSchedulable b = Scheduler.newInstance(); // would fail!The second call would fail, as the first would have created an instance of Scheduler<FirstSchedulable>, which is stored in the static variable scheduler and not compatible to a Scheduler<SecondSchedulable>.
You should rethink you design. -
Hey all, I am tying to learn factory method and working on an example from the Oreilly AS3 Design patterns book. I am attempting figure out how all the classes work together in this design pattern and I have a question I am hoping someone might be able clearify for me.
In the document class "Main" I have the following code in the constructor
// instantiate concrete shape creators
var unfilledShapeCreator:ShapeCreator = new UnfilledShapeCreator( );
// draw unfilled shapes NOTE: draw() is a method of the ShapeCreator class
unfilledShapeCreator.draw(UnfilledShapeCreator.CIRCLE, this.stage, 50, 75);
I get what is going on there, so I open up the 'UnfilledShapeCreator" class and it has the following:
package shapecreators
/* Concrete Creator class */
public class UnfilledShapeCreator extends ShapeCreator
public static const CIRCLE :uint = 0;
public static const SQUARE :uint = 1;
//implement the createShape factory method from the ShapeCreator Class.
override protected function createShape(cType:uint):ShapeWidget
if (cType == CIRCLE)
trace("Creating new circle shape");
return new CircleWidget( ); //Instantiates circleWidge Product Class
} else if (cType == SQUARE) {
trace("Creating new square shape");
return new SquareWidget( ); //Instantiates square Widge Product Class
} else {
throw new Error("Invalid kind of shape specified");
return null;
and the ShapeCreator class is as follows
package shapecreators
/* Defines the abstract interface for the creator classes */
import flash.display.DisplayObjectContainer;
import flash.errors.IllegalOperationError;
// ABSTRACT Class (should be subclassed and not instantiated)
public class ShapeCreator
public function draw(cType:uint, target:DisplayObjectContainer, xLoc:int, yLoc:int):void
var shape = this.createShape(cType);
shape.drawWidget( );
shape.setLoc(xLoc, yLoc); // set the x and y location
target.addChild(shape); // add the sprite to the display list
// ABSTRACT Method (must be overridden in a subclass)
protected function createShape(cType:uint):ShapeWidget
throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
return null;
My question is: how does the cType parameter get passed into the createShape method? This method does not seem to get called from anywhere or any other class. I see how FilledShapeCreator.CIRCLE gets passed to the draw method in the ShapeCreator class, but the createShape method is never called like the draw method is.
Is it because createShape is called within the draw function?
I am quite sure it is a simple answer, but it has me completely lost.
Thanks,Yes, it is called by super class in line:
var shape = this.createShape(cType);
By the way, I don't know where you got code but it is a pretty bad practice not type variables. Good compiler should not even allow you to compile. The line above should be:
var shape:ShapeWidget = this.createShape(cType); -
Design Patterns: 'Program to an interface, not an impl.' and Factory Method
Design Patterns: 'Program to an interface, not an implementation' and Factory Method.
Hi All,
I've 4 questions. And 1M thanks for your precious input.
1. OOAD steps:
Requirement-->Use Cases-->Analysis Classes-->Sequence Diagrams-->CRC-->other UML diagrams if needed--> Domain/Business Classes.
If we follow the rule 'Program to an interface, not an implementation',
would that imply NECESSARILY we should have another set of Interface Classes for our Domain Classes? i.e Interface_ClassX for ClassX_Impl.
2. If the point 1 is a MUST because of the rule 'Program to an interface, not an implementation',
ie we should have an Interface classe for every one Domain classe,
would that NECESSARILY imply we should have as many Factory Methods as they are Domain Classes to abstract the creation process?
Interface_ClassX X= Factory.GetClassX() ( return new ClassX_Impl)
Interface_ClassY Y= Factory.GetClassY() ( return new ClassY_Impl)
Interface_ClassZ Z= Factory.GetClassZ() ( return new ClassZ_Impl)
3. On the point 2, the underlying principle used is Factory Methods.
Now on the surface, what are other possible business and/or technical naming for such Factory Methods? I mean should we call it a kind of Business Facade?
4. Is the point 1 and point 2 considered to be the best practices?So the question here is whether we can predict having
more than one possible implementations which required
option c. Is this a dilema? I guess it's hard to
predict the future.Right. Hopefully it's fairly obvious while designing things and
deciding what objects are needed.
Now, if the Presentation Tier, says JSP, needs that
ClassNormal object. Would we still keep that line of
code a.
OR would we introduce an intermediate object to free
JSP from the direct creational aspect using new
keyword like the choice b. that you reject.
The point here is to reduce the direct coupling aspect
between the Presentation Tier and Business Tier. So
what would that intermediate object be?In that case, you have to ask yourself if there is a valid
need for reducing the coupling. If you simply make an intermediate
object, what keeps you from making an intermediate object to your
new intermediate object, ad infinitum.
That intermediate object could be a Facade pattern, or simply
an abstraction. We actually did that here, we began a massive
java project, and we abstracted away from Swing J-classes and created
our own "wrappers" that simply extended all the J-classes and we had
all our programmers develop using our wrappers instead of the Swing
classes. That allowed us to add some custom code, some temporary bug fixes, etc. Some of our classes were nothing more than "EPPasswordField extends JPasswordField" with nothing overridden. It does allow us a place to hook in and adjust or fix things if needed though. -
How to add a new button in an ALV using factory method
im using factory method to creat an ALV
The reason why I'm doing this is because I want the ALV and the selection screen in the same screen like exemplified here http://help-abap.blogspot.com/2008/10/dispaly-alv-report-output-in-same.html
CALL METHOD cl_salv_table=>factory
EXPORTING
list_display = if_salv_c_bool_sap=>false
r_container = lo_cont
container_name = 'DOCK_CONT'
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = me->t_data.
The above code already uses every parameter that method as to offer.
Is it possible to add extra buttons to an ALV using that method?Hi Ann,
The reason you are not able to see any of the new columns as a option to select in your web service block is because when you have published that block, they were not present. Add these two new objects in your block and publish it again. You will be prompted for duplication content. Select the highlighted block for duplicate and now you can see the new added objects in the filter option. Update and this will overwrite your published block. Please note, web services do appear to behave weirdly when used with dashboards so I request you to please try it in a separate test report first.
Hope that helps.
Regards,
Tanisha -
Problem in factory method, how to pass arguments ?
Hello it's me again :)
here's the code :
package print;
import java.util.*;
import static print.Print.*;
interface Fact<T> {
T create(String n);;
T create ();
class PetColl {
public String toString() {
return getClass().getSimpleName();
static List<Fact<? extends Pet>> petSpecies=
new ArrayList<Fact<? extends Pet>>();
static {
// Collections.addAll() gives an "unchecked generic
// array creation ... for varargs parameter" warning.
petSpecies.add(new Cymric.Factory());
petSpecies.add(new EgyptianMau.Factory());
petSpecies.add(new Hamster.Factory());
petSpecies.add(new Manx.Factory());
petSpecies.add(new Mouse.Factory());
petSpecies.add(new Pug.Factory());
petSpecies.add(new Mutt.Factory());
petSpecies.add(new Rat.Factory());
private static Random rand = new Random(47);
public static Pet createRandom() {
int n = rand.nextInt(petSpecies.size());
return petSpecies.get(n).create();
public Pet[] createArray(int size) {
Pet[] result = new Pet[size];
for(int i = 0; i < size; i++)
result[i] = createRandom();
return result;
public ArrayList<Pet> arrayList(int size) {
ArrayList<Pet> result = new ArrayList<Pet>();
Collections.addAll(result, createArray(size));
return result;
class Individual implements Comparable<Individual> {
private static long counter = 0;
private final long id = counter++;
private String name;
public Individual(String name) { this.name = name; }
// ?name? is optional:
public Individual() {}
public String toString() {
return getClass().getSimpleName() +
(name == null ? "" : " " + name);
public long id() { return id; }
public boolean equals(Object o) {
return o instanceof Individual &&
id == ((Individual)o).id;
public int hashCode() {
int result = 17;
if(name != null)
result = 37 * result + name.hashCode();
result = 37 * result + (int)id;
return result;
public int compareTo(Individual arg) {
// Compare by class name first:
String first = getClass().getSimpleName();
String argFirst = arg.getClass().getSimpleName();
int firstCompare = first.compareTo(argFirst);
if(firstCompare != 0)
return firstCompare;
//second compare by name
if(name != null && arg.name != null) {
int secondCompare = name.compareTo(arg.name);
if(secondCompare != 0)
return secondCompare;
}//third compare by id
return (arg.id < id ? -1 : (arg.id == id ? 0 : 1));
class Pets {
public static final PetColl creator =
//new LiteralPetCreator();
new PetColl();
public static Pet randomPet() {
return creator.createRandom();
public static Pet[] createArray(int size) {
return creator.createArray(size);
public static ArrayList<Pet> arrayList(int size) {
return creator.arrayList(size);
class Person extends Individual {
String name;
public static class Factory implements Fact<Person>{
public Person create(String name){
Person.name=name;
return new Person(); }
public Person create(){return new Person();}
class Pet extends Individual {
class Dog extends Pet {
class Mutt extends Dog {
public static class Factory implements Fact<Mutt> {
public Mutt create(String name){return new Mutt(name);}
public Mutt create () {return new Mutt();}
class Pug extends Dog {
public static class Factory implements Fact<Pug> {
public Pug create(String name){return new Pug(name);}
public Pug create () {return new Pug();}
class Cat extends Pet {
class EgyptianMau extends Cat {
public static class Factory implements Fact<EgyptianMau> {
public EgyptianMau create(String name){return new EgyptianMau(name);}
public EgyptianMau create () {return new EgyptianMau();}
class Manx extends Cat {
public static class Factory implements Fact<Manx> {
public Manx create(String name){return new Manx(name);}
public Manx create () {return new Manx();}
class Cymric extends Manx {
public static class Factory implements Fact<Cymric> {
public Cymric create(String name){return new Cymric(name);}
public Cymric create () {return new Cymric();}
class Rodent extends Pet {
class Rat extends Rodent {
public static class Factory implements Fact<Rat> {
public Rat create(String name){return new Rat(name);}
public Rat create () {return new Rat();}
class Mouse extends Rodent {
public static class Factory implements Fact<Mouse> {
public Mouse create(String name){return new Mouse(name);}
public Mouse create () {return new Mouse();}
class Hamster extends Rodent {
public static class Factory implements Fact<Hamster> {
public Hamster create(String name){return new Hamster(name);}
public Hamster create () {return new Hamster();}
public class Test {
public static void main(String[] args) {
for(Pet p:Pets.creator.arrayList(25)){
PetCount.petC.count(p.getClass().getSimpleName());
print(p.getClass().getSimpleName());}
class PetCount {
static class PetCounter extends HashMap<String,Integer> {
public void count(String type) {
Integer quantity = get(type);
if(quantity == null)
put(type, 1);
else
put(type, quantity + 1);
public static PetCounter petC= new PetCounter();
}and here's my problem:
I'm trying to fill up list using factory method but in a fact that I want to have two constructors, I have a problem to set field name of objects of those classes. Is there any possibility to use in that way some factory method to create that list ?
In Person class I've tried to set it in factory method before creating an object, but as you know that option is only alvailable for static fields which i don't want to be static.I for one have no idea what you're asking, and what you seem to be saying doesn't make sense.
I'm trying to fill up list using factory method but in a fact that I want to have two constructors,Two constructors for what? The factory class? The classes that the factory instantiates?
I have a problem
to set field name of objects of those classes. Is there any possibility to use in that way some factory method to
create that list ?What?
In Person class I've tried to set it in factory method before creating an object, but as you know that option is only alvailable for static fields which i don't want to be static.That doesn't make any sense. A Factory can easily set fields in the objects it creates on the fly (not static). -
Meaning of factory method in abap objects
Hi,
Can anybody help me in understanding the meaning of factory method in abap object? what is the importance of this?
Regards
SudhansuHi Krish and Sudhansu,
Design patterns are solutions which are already verified and known by many developers. That is why it is worth to use them. There is no need to reinvent the wheel in many cases.
I would recommend book which is placed in the ABAP world:
http://www.sap-press.com/products/Design-Patterns-in-Object%252dOriented-ABAP-(2nd-Edition).html
Although Java language has intuitive syntax, there are some special things in ABAP development so it is better to check solutions adjusted for ABAP editor.
The most common usage of factory pattern is to simplify object creation.
- By one method call you provide required parameters and do all initializations, including dependent objects.
- Class can have many factory methods, if you want to provide more ways of initialization.
- Factory method is usually static in the class and they return initialized instance of object for this class.
- There is naming convention to start factory method name with "create" - easy to recognize pattern.
- If you set property of class to "private instantiation" then you force to use factory method for object creation. In this way it is really simple to find all places where object are created with given set of input parameters - find references of factory method.
Factory pattern becomes even more powerful if we add inheritance. Factory method returns basic object (like ZCL_VEHICLE) but its implementation can return different subclass instance, depending on input parameter (ZCL_CAR, ZCL_TRAIN etc). Each instance can implement differently behavior (methods implementation), but these are object oriented techniques.
Regards,
Adam -
Trying to understand Objective C warning related to factory method
All,
I'm just beginning learning objective C (I am a C++ programmer by day), and I have a question about a warning I am seeing in my code. I found some really simple example code on the web that used the 'new' factory method to create an instance of an object. Here are the three files:
List.h
#import <objc/Object.h>
@interface List : Object // List is a subclass of the superclass Object
int list[100]; // These are instance variables.
int size;
/* Public methods */
- free;
- (int) addEntry: (int) num;
- print;
/* Private methods */
/* Other programs should not use these methods. */
- resetSize;
@end
List.m
#import "List.h"
@implementation List
+ new // factory method
self = [super new];
printf("inside new\n");
[self resetSize];
return self;
- free
return [super free];
- (int) addEntry: (int) num
list[size++] = num;
return size;
- print
int i;
printf("\n");
for (i = 0; i < size; ++i)
printf ("%i ", list);
return self; // Always return self
// if nothing else makes sense.
- resetSize
printf("Inside resetSize\n");
size = 0;
return self;
@end
main.m
#import <objc/Object.h>
#import "List.h" // Note the new commenting style.
main()
id list; // id is a new data type for objects.
list = [List new]; // create an instance of class List.
[list resetSize];
[list addEntry: 5]; // send a message to the object list
[list print];
[list addEntry: 6];
[list addEntry: 3];
[list print];
printf("\n");
[list free]; // get rid of object
Now, I know that the 'best' way to allocate and initialize an object is through [[List alloc] init], but I'm seeing a strange warning when I compile List.m, and I just want to understand why it's showing up. Here's the warning.
List.m: In function ‘+[List new]’:
List.m:9: warning: ‘List’ may not respond to ‘+resetSize’
List.m:9: warning: (Messages without a matching method signature
List.m:9: warning: will be assumed to return ‘id’ and accept
List.m:9: warning: ‘...’ as arguments.)
It looks like something is assuming that resetSize is a factory method rather than an instance method. The strange thing, though, is that the program works exactly like expected. resetSize is actually called from within the new method correctly.
Any ideas why I'm seeing the error, and how I should get rid of it?
Thanks,
EricThanks for clearing that up for me - it makes sense now. And sorry about the formatting problems - I guess forgetting the {code} tags make a pretty big difference
It's taking a little bit for my mind to switch from C++ syntax to Objective C, but I'm able to visualize the problem and the reason the code I found produced the error.
Thanks again,
Eric -
ALV GRID DISPLAY USING FACTORY METHODS
Hi all
I am using factory methods for my alv grid display.
I have a list of functionalities, for which i am not able to find a correct method..
1) Header of alv(with all the values of the selection-screen)
2)How to give text to a subtotal(ed) column, i.e. if i subtotal a qty field against a sorted field, i want to display ==> Nett Wt. = 123.00 (for first header entry) and so on for each header entry.
3)how to remove the zeroes from a quantity field?
4) Displaying the cells as blanks where data is 0( for quantity fields if i have a cell with zero value, it should be blank.)
5) double click on a cell to open a transaction with the cell's value.
Any help on this would be appreciated.
Points will be rewarded for sure...
Thanks & Regards
Ravish GargHello Ravish
Regarding the display of zero values as empty cells have a look at my <i>modified </i>sample report <b>ZUS_SDN_CL_SALV_TABLE_INTERACT</b>.
*& Report ZUS_SDN_CL_SALV_TABLE_INTERACT
REPORT zus_sdn_cl_salv_table_interact.
TYPE-POOLS: abap.
DATA:
gt_knb1 TYPE STANDARD TABLE OF knb1.
DATA:
go_table TYPE REF TO cl_salv_table,
go_events TYPE REF TO cl_salv_events_table.
* CLASS lcl_eventhandler DEFINITION
CLASS lcl_eventhandler DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
handle_double_click FOR EVENT
if_salv_events_actions_table~double_click
OF cl_salv_events_table
IMPORTING
row
column.
ENDCLASS. "lcl_eventhandler DEFINITION
* CLASS lcl_eventhandler IMPLEMENTATION
CLASS lcl_eventhandler IMPLEMENTATION.
METHOD handle_double_click.
* define local data
DATA:
lo_table TYPE REF TO cl_salv_table,
lt_orders TYPE STANDARD TABLE OF bapiorders,
ls_knb1 TYPE knb1.
READ TABLE gt_knb1 INTO ls_knb1 INDEX row.
IF ( syst-subrc = 0 ).
CALL FUNCTION 'BAPI_SALESORDER_GETLIST'
EXPORTING
customer_number = ls_knb1-kunnr
sales_organization = '1000'
* MATERIAL =
* DOCUMENT_DATE =
* DOCUMENT_DATE_TO =
* PURCHASE_ORDER =
* TRANSACTION_GROUP = 0
* PURCHASE_ORDER_NUMBER =
* IMPORTING
* RETURN =
TABLES
sales_orders = lt_orders.
* Create ALV grid instance
TRY.
CALL METHOD cl_salv_table=>factory
* EXPORTING
* LIST_DISPLAY = IF_SALV_C_BOOL_SAP=>FALSE
* R_CONTAINER =
* CONTAINER_NAME =
IMPORTING
r_salv_table = lo_table
CHANGING
t_table = lt_orders.
CATCH cx_salv_msg .
ENDTRY.
lo_table->display( ).
** SET PARAMETER ID 'BUK' FIELD ls_knb1-bukrs.
** SET PARAMETER ID 'KUN' FIELD ls_knb1-kunnr.
** CALL TRANSACTION 'XD03' AND SKIP FIRST SCREEN.
ENDIF.
ENDMETHOD. "handle_double_click
ENDCLASS. "lcl_eventhandler IMPLEMENTATION
START-OF-SELECTION.
SELECT * FROM knb1 INTO TABLE gt_knb1
WHERE bukrs = '1000'.
* Create ALV grid instance
TRY.
CALL METHOD cl_salv_table=>factory
* EXPORTING
* LIST_DISPLAY = IF_SALV_C_BOOL_SAP=>FALSE
* R_CONTAINER =
* CONTAINER_NAME =
IMPORTING
r_salv_table = go_table
CHANGING
t_table = gt_knb1.
CATCH cx_salv_msg .
ENDTRY.
* Create event instance
go_events = go_table->get_event( ).
* Set event handler
SET HANDLER:
lcl_eventhandler=>handle_double_click FOR go_events.
PERFORM modify_columns.
go_table->display( ).
END-OF-SELECTION.
*& Form MODIFY_COLUMNS
* text
* --> p1 text
* <-- p2 text
FORM modify_columns .
* define local data
DATA:
lt_dfies TYPE ddfields,
ls_dfies TYPE dfies,
lo_typedescr TYPE REF TO cl_abap_typedescr,
lo_strucdescr TYPE REF TO cl_abap_structdescr,
lo_tabledescr TYPE REF TO cl_abap_tabledescr,
lo_columns TYPE REF TO cl_salv_columns_table,
lo_column TYPE REF TO cl_salv_column.
lo_columns = go_table->get_columns( ).
lo_typedescr = cl_abap_typedescr=>describe_by_data( gt_knb1 ).
lo_tabledescr ?= lo_typedescr.
lo_strucdescr ?= lo_tabledescr->get_table_line_type( ).
lt_dfies = lo_strucdescr->get_ddic_field_list( ).
LOOP AT lt_dfies INTO ls_dfies.
lo_column = lo_columns->get_column( ls_dfies-fieldname ).
IF ( ls_dfies-keyflag = abap_true ).
CONTINUE.
ELSEIF ( ls_dfies-fieldname = 'WEBTR' ). " Bill of ex. limit
lo_column->set_zero( if_salv_c_bool_sap=>true ). " display zero
lo_column->set_zero( if_salv_c_bool_sap=>false ). " hide zero
ELSE.
lo_column->set_technical( if_salv_c_bool_sap=>true ). " hide col
ENDIF.
ENDLOOP.
ENDFORM. " MODIFY_COLUMNS
Regards
Uwe -
Factory method usage, creating the correct Image subclass
Hi, I created a factory method
public enum ImgType {
SINGLE, STRIP, SPRITE_SHEET
public static Image createImage(ImgType imgType) {
switch (imgType) {
case SINGLE:
return new MyImage1(0, 0);
case SPRITE_SHEET:
return new MyImage2("", 0, 0);
case STRIP:
return new MyImage3("", 0, 0);
default:
throw new IllegalArgumentException("The image type " + imgType + " is not recognized.");
}that creates different images based on the enum type provided.
and heres is a usage of that function
public BufferedImage loadAwtImage(ImageInputStream in, String imgName, ImageTypeFactory.ImgType imgType) throws IOException {
BufferedImage img = imgLoader.loadImage(in);
BufferedImage imgsubType = ImageTypeFactory.createImage(imgType); // Convert to real Image type
addAwtImg(imgName, imgsubType);
return imgsubType;
}In a test:
imgLib.loadAwtImage(imageStream, "cursor", ImageTypeFactory.ImgType.SPRITE_SHEET);Is it 'good' that in the test I can say(using the imgType enum) what sort of Image should be returned?
doesn't this expose the working of the class to the outside, on the other hand I don't know howto create the correct sub image based on an image loaded.
I use subImages to allow selection within the image, like the 3th 'tile' within an imageStrip returns just that cropped image.
Before I had List<Image> and List<List<Image>> and now I can just return Images in 1 method instead of 2,3 by using lists.
Edited by: stef569 on Dec 12, 2008 11:05 AMcreates specifications... :p
* load the BufferedImage from the ImageInputStream
* add it to the cache keyed by the imgName
* @return a BufferedImage, or a custom subclass based on the imgType
* @throws IOException when the img could not be loaded
public BufferedImage loadAwtImage(ImageInputStream in, String imgName, ImageTypeFactory.ImgType imgType) throws IOException I can test it, but the ImageTypeFactory.ImgType imgType parameter looks wrong to me.
if you see this in a class method would you change it/find a better way. -
Factory method generateRandomCircle: "cannot resolve symbol"
I have written 2 classes: Point and Circle, which uses Point objects in order to create a Circle object. I have created a factory method for Point, which creates random Point objects and a for Circle, which does the same. "newRandomInstance" works fine for Point, but "generateRandomCircle" throws a "cannot resolve symbol" error. "main" is inside Point class. What's the problem?
Thanks
================================================
import java.io.*;
import java.lang.*;
import java.util.*;
public class Circle implements Cloneable
public static Circle generateRandomCircle()
int a= (int) (Math.random()* Short.MAX_VALUE);
int b= (int) (Math.random()* Short.MAX_VALUE);
Point p=new Point(a,b);
int r= (int) (Math.random()* Short.MAX_VALUE);
Circle c= new Circle(p,r);
return c;
===============================================
import java.io.*;
import java.lang.*;
import java.util.*;
public class Point implements Cloneable, Comparable
public static Point newRandomInstance()
int x = (int) (Math.random() * Short.MAX_VALUE);
int y = (int) (Math.random() * Short.MAX_VALUE);
return new Point(x,y);
public static void main (String[] args)
Circle cRandom= generateRandomCircle(); //doesn't work
System.out.println(cRandom.getCenter()+" "+ cRandom.getRadius());
Point randomP= newRandomInstance(); //works OK
randomP.printPoint();
}I tried "Circle cRandom=
Circle.generateRandomCircle(); " instead of "Circle
cRandom= generateRandomCircle();" and it worked. Why
did this happen?Because generateRandomCircle() exists in class Circle and not in class Point where your are trying to use it.
>
Function "newRandomInstance()" works either as
"Point.newRandomInstance()" or as
"newRandomInstance()", however. Why does this
controversy exist?No controversy! Your main() is contained within class Point and as such knows about everything that is declared in class Point() but nothing about what is in class Circle unless you tell it to look in class Circle. -
Back button issue in ALV Grid(Factory method)
Hi All,
I have displayed a report using factory method(CL_SALV_TABLE).In that i have added buttons in application bar too.So when clicking on refresh button ALV should display again with latest number of records,that is working fine but when clicking on back button it should go to selection screen instead of that it is going a step back and displaying previous list of grid and then back and then selection screen.
Can any one help me how to directly go to input selection screen instead of going step back...
Regards,
RamHI,
Use this syntax (CALL SELECTION-SCREEN 1000)...Try this one
regards,
balaji -
Academic Question about Classes Method and Constructor
Given the similarity between the Constructor class and the Method class, why don't they have a common super class for the methods they have in common that are unique to them?
sledged wrote:
jschell wrote:
sledged wrote:
I've found that the most common reason for invoking a constructor or method through reflection is because you don't know what you need until runtime, commonly because what you want can vary based on context, or is otherwise being specified external to the bit of code that uses reflection. Not true. The fact that I don't need it until runtime never means I don't know what I need.Never? Then your experiences with the reflection API have been different than mine. Either that or I wasn't very clear. Let's take Apache Commons BeanUtils;
It doesn't matter how you access a class. You can't use it unless
1. You have a goal in mind
2. That object in some way fulfills that goal.
3. You know how that object fulfills that goal.
And as I already pointed out you can't use a JFrame for a JDBC driver. Simple as that. Nor can I create a new class that implements, for example, ProC (Oracle method to embed access into C code) using my own idiom despite that it provide database access. It MUST match what jdbc expects.
Sometimes it's not even clear before runtime whether a constructor's needed or a method.
I disagree. That isn't true in any OO language.Perhaps not out the box, but it can be true when using certain tools built from the OO language. Let me continue using the Spring framework as an example. It does not know whether to use a method or a constructor to instantiate any bean defined in the XML configuration metadata until that XML file is read and it determines whether or not a given bean definition has the "factory-method" attribute. The XML file in not read until runtime, therefore with any given bean defined therein, Spring does not know until runtime whether to use a constructor or method.Not apt at all.
As I already said those are two different idioms. Spring supports them because they are used to solve different problems not because they wish constructors didn't exist.
>
The basis of OO is the "object". You can't have a method without the object in the conceptual OO model. (And in Smalltalk that is always true.)
True, but one may not always care how the "object" is provided. When the method [Properties.load(InputStream)|http://java.sun.com/javase/6/docs/api/java/util/Properties.html#load%28java.io.InputStream%29] is called, it isn't going to care whether the InputStream argument was instantiated by one of the FileInputStream constructors, or if it came from a [URL.openStream()|http://java.sun.com/javase/6/docs/api/java/net/URL.html#openStream%28%29] method call. It'll work with either regardless of their respective origins.
That of course has nothing to do with anything. Unless you are suggesting that construction in any form should not exist.
A factory is not a constructor.I'm not saying it is. I'm just pointing out a number of the similarities between the two.
So? There are many similarities between RMI and JDBC but that doesn't mean that they should be the same.
With your argument you can claim that construction doesn't exist because any method, regardless of intent, that uses 'new' would eliminate the need for construction. And that isn't what happens in OO languages.I wouldn't claim that construction doesn't exist in any OO language. But I do know that in ECMAScript construction exists on the basis of whether or not a method is called with the 'new' operator. So in ECMAScript a single method can also be a constructor.
And in C++ I can entirely circumvent the object construction process. Actually I can do that in JNI as well.
I would still be a bad idea.
>
They are not interchangable.Normally, no, but with a high enough level of abstraction, they can become interchangeable. Again, the Spring framework is a great example. It doesn't care if a method or a constructor is used, and it won't know which one has been chosen until runtime. I don't even think Spring checks the return type of a method, so you could use a void return type method. (Although I don't know what that would buy you because the bean would always be set to null, but still...)
No.
Based on that argument every possible programming problem could be solved by simply stating that one must implement the "doit()" method. One just need to generalize it enough.
Different APIs exist because there are in fact differences not because there are similarities.
Over generalization WILL lead to code that is hard to maintain. Actually generalization itself, even when done correctly, can lead to code that is actually more complex.
Because construction is substantially different than calling a method. In all OO languages.Yes, construction is different, but the actual call to a constructor and a method is only syntactically different with the presence of the 'new' operator. With reflection the difference is between calling Method.invoke() and Constructor.newInstance(), and, as I mentioned earlier, there's enough similarity between the two methods that they could be called by a single method specified by a common super class.Which does not alter the fact that the process of achieving the result is fundamentally different.
Maybe you are looking for
-
Hi Friends, I have got two ODS with diffrent data. ODS1: Sales Doc, Fiscal Year Period, Key Fig1 ODS2: Sales Doc, Key Fig2 I have created a multiprovider with these two ODS by maiing - Sales Doc from bothe ODS1 and ODS2 - Fisc Yr Per from ODS1 (I don
-
Just receive an unlocked 3gs iphone from a family member and can't unlock the screen. Can't restore iphone because of error message.Now what do I do?
-
Error while posting in accounts: Condition type does not exist in COPA
Hi, I'm trying to post an invoice into accounts but I'm constantly encountering a Error message as : Assign condition type in COPA. This error is appearing whenever I'm assigning the pricing procedure and KOFK account entries to a new sales organizat
-
Pdf files as attachments, inconsistent, some open some as file?
WHen i attach multiple pdf files, sometimes they just show up at the attachment and sometimes they are open in the email. I prefer the former. How can I make them all the same? They can be created from the same application the same way, no rhyme or r
-
I create a Production order for a material When we create a Production order for 30 numbers and execute cop2 the transaction code is working fine , Handling units are created , confirmations and goods receipt also happening When we create a productio