dcsimg
Help on Factory Pattern
4 posts in topic
Flat View  Flat View
TOPIC ACTIONS:
 

Posted By:   Vikram_Vollu
Posted On:   Monday, June 3, 2002 09:37 AM

Hi,



In my project I have three different types of users. My class design is like this: User - abstract class (first name, last name and user id are attributes). I derived three classes from this class. Each derived class adds its own attributes apart from the above three.



I am using the factory method pattern to instatiate the derived clases. But how can I access its own attributes.


Thanks for the help.

Re: Help on Factory Pattern

Posted By:   Eric_Lindauer  
Posted On:   Wednesday, August 14, 2002 09:17 PM

Hi there,



As no one else has mentioned this, I'll point out that your factory does not necessarily ever need to know the type of the object being constructed. By combining the interface suggestion made above with reflection, your factory can become completely open to extension, without any changes to your factory's source code ( much better than the switch statement suggestion, IMO ). At that point, anyone can come along and plugin their own User implementation, using your factory as the instantiation point.






All you have to do to implement this is to write your instantiation logic to check a more dynamic location to determine the name of the class to instantiate ( for example, a Properties created from a known file location, or some other user pref mechanism ). Require that all plugins have a no-args constructor, for example, and then do something like:




public User getUser () {

if ( it's a Thursday ) {
Class result = Class.forName ( MyPrefs.getThursdayClassName () );
return (User) result.newInstance ();
} else {
return (User) Class.forName ( MyPrefs.getNormalUser () ).newInstance ();
}
}





Of course, Class.forName isn't the best, and you'll have to deal with ClassNotFoundExceptions... hopefully this is enough to give you the idea. The point is that, you want details about the exact type to instantiate to be changable outside of you code. This makes it open to extension, but closed to modification, which makes it much more reusable and powerful.




Hope this helps.

Eric





ps... another way to accomplish the effect is to make your factory a singleton ( a good idea anyways ) and make the process of instantiating the factory itself involve the dynamic lookup process described above. This also makes your code open to extension, as third-parties can plugin their own factory extension, override the method, and return their own stuff to handle special cases as they see fit. With this change, you could go with the switch statement in the actual ( now non-static ) method, if this logic was required.

Re: Help on Factory Pattern

Posted By:   Joy_Bagchi  
Posted On:   Saturday, July 13, 2002 03:49 PM

Usually the best solution in such cases is that at runtime you check for what subclass your actual object is.
for eg



public abstract class User {



//abstract method list here

}

public class UserA extends User{

//your UserA specific attr



//Abstract methods implentation

}

.... //other 2 user classes goes here





//code snippet showing runtime use of user classes

.....

User usr = UserFactory.getUser();

if(usr instanceof (UserA)){

...../UserA specific code

}

.....//other Cases for other User Classes

//end code snippet






Also there could be another solution if your Usertype specific Attributes have any kind of commonality.



In that case you can Abstract the UserAttributes in a base class and then in the User specific class have a subclass of abstract Attribute class.





But this approach will only work if your actual runtime can work with certain abstraction of attributes. If you need to know specific details about the attributes then its best to do a runtime check like I metioned above



Joy

Re: Help on Factory Pattern

Posted By:   Stu_Pedasso  
Posted On:   Tuesday, July 9, 2002 10:29 AM

Hi there,

It sounds like you have a structure like this:



public abstract class User {...}
public class UserA extends User {...}
public class UserB extends User {...}
public class UserC extends User {...}


At runtime you want to instantiate one of User[A|B|C] through your factory and then access the specific attributes/methods of that concrete class. So, based on that, you might want to consider using an

if
block or
switch
block to determine which to instantiate. For example, in your factory class:



public User getInstance(String buildMe) {
//...stuff...
if (buildMe.equals("UserA")) {
return new UserA();
} else if (buildMe.equals("UserB")) {
return new UserB();
} else if (buildMe.equals("UserC")) {
return new UserC();
}
//...stuff...
return null;
}


Note the return type. Now through the magic of polymorphism the correct attributes/methods should be called. For example, if User has the following method:



public void helloFrom() {
System.out.println("Hello from User!");
}


and UserB has the following method:



public void helloFrom() {
System.out.println("Hello from UserB!");
}


and the following was done:



User u = Factory.getInstance("UserB");
u.helloFrom();


the output would be:



Hello from UserB!


So, I think the only thing you would really have to figure out is how you want to implement the logic to determine which concrete class to instantiate. Which would involve some hardcoding or property files.


enjoy.

Re: Help on Factory Pattern

Posted By:   Anonymous  
Posted On:   Monday, June 3, 2002 10:01 AM

You will need to cast the user class to a specific type of user to access specific attributes.
About | Sitemap | Contact