Badges implementation issue - java

I am designing a website using JSF + EJBS + JPA, etc. JAVA EE 6 to sum up.
You can create an article, and over time if it meets certain conditions (say 1000 views) it's awarded a "1000 views badge."
The problem arises when I want to create new badges dynamically. I have a badge entity class, and all badges are fetched from a database. How can I dynamically establish conditions for a badge to be awarded to an article, since the behavior depends on each instance rather than its type?
For instance the business logic for evaluating the meeting requirements for a '1000 views badge' is very different from the one used in a 'best rated article of the week' etc. Also, what if the number of badges grows?
I can't just extend a class because it doesnt make sense, so I figured I'm not looking at this the right way.
Any thoughts on how would you implement it?

Implement a #Singleton, which has a method running once in a period(once per hour or per 24 hours). It will have a collection of classes to check the posts for some conditions. If you want a new badge, just add a class.
#Singleton
public class Watchdog implements Serializable {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The em. */
#PersistenceContext
private EntityManager em;
private List<PostChecker> checkers = new ArrayList<PostChecker>();
#PostConstruct
public void init() {
checkers.add(new ThousandViewChecker());
checkers.add(new PopularPostChecker());
....
}
#Schedule(...)
public void monitor() {
for (PostChecker checker : checkers) {
checker.check(em);
}
}
}
If you don't want to add a class each time, create some xml file with the rules of badge awarding and create a factory of checkers, which will construct their badge rules using those xml files. Then to add a badge you will need just to add an xml.

Related

Design Pattern for dealing with a complex conditional evaluation

I am designed to maintain a system that takes in account the value of three variables to determine which action it will take.
I want to refactor it to use a design pattern, but could not find one suitable for it needs.
To explain the situation, I will use as an example a gym system.
Every gym user has a TYPE_OF_CONTRACT, that could be:
PLATINUM_MEMBERSHIP
GOLD_MEMBERSHIP
SILVER_MEMBERSHIP
The gym has some GYM_CLASSES:
WEIGHT_LIFTING
BODY_BALANCE
STEP
SPINNING
ZUMBA
PERSONAL_TRAINING
Every gym user has a PHYSICAL_CONDITION
NO_RESTRICTIONS
OVER_65
LIMITED_MOBILITY
MEDICAL_CONDITION
BELOW_18
For each combination of these three characteristics, a arbitrary set of actions should be executed. For example:
if PLATINUM_MEMBERSHIP + PERSONAL_TRAINING + OVER_65:
medical approval needed
signed form
if GOLD_MEMBERSHIP + PERSONAL_TRAINING + OVER_65:
medical approval needed
signed form
extra monthly fee
if SILVER_MEMBERSHIP + PERSONAL_TRAINING + OVER_65:
refuse subscription
if (any membership) + STEP + MEDICAL_CONDITION:
medical approval needed
signed form
if PLATINUM_MEMBERSHIP + WEIGHT_LIFTING + LIMITED_MOBILITY:
medical approval needed
signed form
dedicated staff member assist
And so on.
The combination of characteristics can have a set of actions, that are not exclusive and not all of the combinations are ensured.
The legacy code uses nested switches as implementation. Example:
switch (contractType):
case PLATINUM_MEMBERSHIP:
switch (gymClass):
case (PERSONAL_TRAINING):
switch (physicalCondition):
case (OVER_65):
requiresMedicalApproval();
requiresSignedForm();
...
My problem is:
there are 3 conditions that combines to define a set of rules;
these rules are not necessarily unique;
not every combination defines a set;
I refactored a little using extract method technique and cleaning the code a little, but could not get rid of the 3 switches.
I wish to use design patterns to improve the design but so far I was unsuccessful.
I thought about polymorphism and Strategy, but could not figure a way to use any of them.
I also researched in google but haven't found anything that I could use.
What do you suggest?
Thank you.
EDIT:
A solution I reached, while researching #Paul's decision tree approach. After testing with a decision tree, I tried a three dimensional array, to define the conditions of the rules. I also used the Command pattern to define the actions that needed to be performed if the rule is activated.
In brief:
1) Enums to define the variables:
public enum TypeOfContract { ... }
public enum GymClasses { ... }
public enum PhysicalCondition { ... }
Every possible condition would be put in the enums.
2) The Command interface to define the actions
public interface Command {
public void execute(Map<String, Object> parametersMap);
}
Every action would be an implementation of Command. The Map parameter will be used to pass runtime context to the methods.
3) A Procedures class to hold the actions needed for each condition.
public class Procedures {
private List<Command> actionsToExecute = new LinkedList<Command>();
public static final Procedures NO_ACTIONS_TO_EXECUTE = new Procedures();
private Procedures() {}
public Procedures(Command... commandsToExecute) {
if (commandsToExecute == null || commandsToExecute.length == 0) {
throw new IllegalArgumentException("Procedures must have at least a command for execution.");
}
for (Command command : commandsToExecute) {
actionsToExecute.add(command);
}
}
public List<Command> getActionsToExecute() {
return Collections.unmodifiableList(this.actionsToExecute);
}
}
The Procedures class represent the Commands that needed to be executed. It has a LinkedList of Command, to ensure that the Commands are executed in the desired order.
It has the NO_ACTIONS_TO_EXECUTE to be sent instead of a null, in case a combination of the three variables does not exist.
4) A RulesEngine class, to register the rules and its commands
public class RulesEngine {
private static final int NUMBER_OF_FIRST_LEVEL_RULES = TypeOfContract.values().length;
private static final int NUMBER_OF_SECOND_LEVEL_RULES = GymClasses.values().length;
private static final int NUMBER_OF_THIRD_LEVEL_RULES = PhysicalCondition.values().length;
private static final Procedures[][][] RULES =
new Procedures[NUMBER_OF_FIRST_LEVEL_RULES]
[NUMBER_OF_SECOND_LEVEL_RULES]
[NUMBER_OF_THIRD_LEVEL_RULES];
{ //static block
RULES
[TypeOfContract.PLATINUM_MEMBERSHIP.ordinal()]
[GymClasses.PERSONAL_TRAINING.ordinal()]
[PhysicalCondition.OVER_65.ordinal()] =
new Procedures(new RequireMedicalApproval(),
new RequireSignedForm() );
RULES
[TypeOfContract.GOLD_MEMBERSHIP.ordinal()]
[GymClasses.PERSONAL_TRAINING.ordinal()]
[PhysicalCondition.OVER_65.ordinal()] =
new Procedures(new RequireMedicalApproval(),
new RequireSignedForm(),
new AddExtraMonthlyFee() );
...
}
private RulesEngine() {}
public static Procedures loadProcedures(TypeOfContract TypeOfContract,
GymClasses GymClasses, PhysicalCondition PhysicalCondition) {
Procedures procedures = RULES
[TypeOfContract.ordinal()]
[GymClasses.ordinal()]
[PhysicalCondition.ordinal()];
if (procedures == null) {
return Procedures.NO_ACTIONS_TO_EXECUTE;
}
return procedures;
}
}
(Unusual code formatting done for the sake of visualization in this site)
Here the meaningful associations of variables are defined in the RULES three dimensional array.
The rules are defined by employing the corresponding enums.
For the first example I gave, PLATINUM_MEMBERSHIP + PERSONAL_TRAINING + OVER_65, the following would apply:
RULES
[TypeOfContract.PLATINUM_MEMBERSHIP.ordinal()]
[GymClasses.PERSONAL_TRAINING.ordinal()]
[PhysicalCondition.OVER_65.ordinal()]
(the ordinal() is needed to return the int corresponding to the position of the enum)
To represent the actions needed to perform, a Procedures class is associated, wrapping the actions that are to be executed:
new Procedures(new RequireMedicalApproval(), new RequireSignedForm() );
Both RequireMedicalApproval and RequireSignedForm implement the Command interface.
The whole line for defining this combination of variables would be:
RULES
[TypeOfContract.PLATINUM_MEMBERSHIP.ordinal()]
[GymClasses.PERSONAL_TRAINING.ordinal()]
[PhysicalCondition.OVER_65.ordinal()] =
new Procedures(new RequireMedicalApproval(),
new RequireSignedForm() );
To check if a particular combination has actions associated to them, the loadProcedures is called, passing the enums representing that particular combination.
5) Usage
Map<String, Object> context = new HashMap<String, Object>();
context.put("userId", 123);
context.put("contractId", "C45354");
context.put("userDetails", userDetails);
context.put("typeOfContract", TypeOfContract.PLATINUM_MEMBERSHIP);
context.put("GymClasses", GymClasses.PERSONAL_TRAINING);
context.put("PhysicalCondition", PhysicalCondition.OVER_65);
...
Procedures loadedProcedures = RulesEngine.loadProcedures(
TypeOfContract.PLATINUM_MEMBERSHIP,
GymClasses.PERSONAL_TRAINING,
PhysicalCondition.OVER_65);
for (Command action : loadedProcedures.getActionsToExecute()) {
action.equals(context);
}
All information the actions need to execute are now inside a Map.
The conditions, represented by the three enums, are passed to the RulesEngine.
The RulesEngine will evaluate if the combination has associated actions and it will return a Procedures object with the list of these actions that needs to be executed.
If not (the combination has no action associated to it), the RulesEngine will return a valid Procedures object with an empty list.
6) Pros
The usage code is much cleaner
The duplication of code in the switches of the legacy code are now gone
The actions are now standardized and well defined (each one in its own class)
The rules used are now much easier to discern (a developer just needs to look at the RULES array to know which rules are set and what will happen in each one of them)
New rules and actions can be easily added
7) Cons
Easy to make mistakes in the definition of the rules, as the declaration of them is verbose and not semantically analysed - it will accepted repetitions, for example, possibly overwriting previous definitions.
Instead of 3 switches nested inside each other, now I have several classes. The maintenance of the system is a little more complex than before, the learning curve a little steeper.
procedures and rules are not good names - still looking for better ones ;-)
Map as parameter can promote bad coding, cluttering it with a lot of content.
How many options will you have? Let's say you have 8 per category, perhaps you can represent a particular combination as a 24-bit number, with 8 bits per category. When you receive a set of options, convert it over to a bit-pattern than then AND against bit-masks to figure out if a certain action needs to be done.
This still requires you to perform tests, but at least they are not nested, and you simply need to add a new test if/when you add a new feature.
You could use a decision-tree and build it from tuples of values.
This would be a lot simpler and if properly implemented even faster than hard-coded conditions and in addition provides higher maintainability.
In terms of design patterns, if you would like to decrease the complexity, you can use the abstract factory.
You can create three hierarchy of classes.
TYPE_OF_CONTRACT (AbstractProductA)
PLATINUM_MEMBERSHIP (ProductA1)
GOLD_MEMBERSHIP (ProductA2)
SILVER_MEMBERSHIP (ProductA3)
GYM_CLASSES (AbstractProductB)
WEIGHT_LIFTING (ProductB1)
BODY_BALANCE (ProductB2)
STEP (ProductB3)
SPINNING (ProductB4)
ZUMBA (ProductB5)
PERSONAL_TRAINING (ProductB6)
PHYSICAL_CONDITION (AbstractProductC)
NO_RESTRICTIONS (ProductC1)
OVER_65 (ProductC2)
LIMITED_MOBILITY (ProductC3)
MEDICAL_CONDITION (ProductC4)
BELOW_18 (ProductC5)

How to put DAO and GUI together with MVC

I'm creating a Java Application that represents a school. My aim is to keep the application open for new features, so I'm trying to apply some Design Patterns to it.
What I have so far is a HSQLDB connected to my program.
In the database one can store
pupils
courses
years
exams
grades
The current structure is as follows:
there are classes for each of the objects that contain the attributes + setters and getters
for each object there is a DAO that manages the CRUD operations on the DB
each DAO implements a GenericDAO interface
If i want to create a new pupil i can call:
PupilDao pupil = new PupilDao();
pupil.connectToDB();
pupil.add(new Pupil(name, age,...));
pupil.disconnectDB();
Every DAOs connectToDB() and disconnectDB() methods point to a DBuser-Classes connect() and disconnect() methods. So if I want to change the connection, there's only one place to do so.
So far, those operations work.
My questions are the:
1.) Is the current design a proper use of DAOs? I'm asking because i would rather have one
Dao for all objects because right now there's a lot of repetitive code in the DAOs. (e.g. get, update, delete...)
Now that the DB-Access works, I want to create a GUI using Swing. I have some experience doing this although not with the MVC-Pattern.
2.) As far as I understand, the DAOs + my object classes would be the Model here. Is that correct?
3.) My understanding of MVC is that in my View-Class (i.e. the GUI) I set listeners for my actions which point to different Controller-Classes implementing the ActionListener interface and in my Controller-Classes I would for example have a actionPerformed() that creates a new Pupil (using the DAO / Model - Classes). Am I on the right track here?
4.) Is it favourable to have one big Controller managing all actions over having different Controllers?
I'm asking those questions because I read/watched a lot about patterns/OO-Design and want to make sure my understanding is correct.
Furthermore I highly appreciate your thoughts on my design! What could be done more flexible or better to maintain later?
Thanks in advance for every suggestion and sorry for the somewhat long explanation!
Felix
While I still can't answer my questions for sure, I think I found a suitable way
for me and want to share the design (suggestions/answers are still appreciated!).
1) The applications entry-point is the main-application class (MVC.class). This class creates the
view using a main-controller. Here's the code:
public static void main(String[] args) {
// view is declared as class-variable
view = new View();
MainController mcontroll = new MainController(view);
view.getFrame().setVisible(true);
}
The main-controller only takes the view as parameter as its only purpose is to display the view.
As stated in my post above my aim was to display different database tables from a HSQLDB and modify them.
2) In the menubar there are entries for managing years, courses, etc. If one entry is clicked, the controller for the clicked category (e.g. years) takes control. Here is, how the controller is changed:
public void addManageYearsListener(ActionListener listener) {
mntmYears.addActionListener(listener);
}
The above method is located in the view class (i.e. the GUI class) but the main-controller implements the actionPerformed()-method. To do that, the main-controller calls the method defined in the view in his constructor like that:
public MainController(View view) {
this.view = view;
this.view.addManageCoursesListener(new ManageCourses());
this.view.addManageYearsListener(new ManageYears());
}
The corresponding class "ManageYears" is then defined as inner class:
class ManageYears implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
MVC mvc = new MVC("years");
}
}
What happens here is that when the menuitem is clicked, the main-controller "hears" the click (cause he is listening to it) and calls the main class again, although this time with a string as parameter. The constructor of the main class checks the string and sets the model and the controller that is needed. See here:
if (controller.equals("year")) {
YearDaoImpl yearDao = new YearDaoImpl();
YearController ycontroller = new YearController(view, yearDao);
}
"controller" is the string that is passed with the constructor and "yearDao" is the Data Access Object that handles the CRUD-operations which have to do with the object "year" (which is a class itself).
So now it's possible to switch controllers at runtime.
3) The year controller sets the ActionListeners for a add and remove button in his constructor (just like the main controller did for the menu item), get's the data from the database (via the yearDao) and sets the table model in the view (view has a setTableModel()-method for that) passing the returned ResultSet as parameter of the table Model class:
public void showYears() {
try {
con = yearDao.connectToDB();
stmt = con.createStatement();
rs = stmt.executeQuery("SELECT * FROM YEARS;");
view.setTableModel(new YearTableModel(rs));
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
As you can see, the yearDao has a connectToDB()-method that returns a connection (the connection is actually gotten from a c3p0 connection pool) which is then used to get a ResulSet of years from the database. The setTableModel()-method is then called setting the YearTableModel - a custom class extending AbstractTableModel and passing the ResulSet as parameter.
With the explained design it is now possible to:
1.) only have one table in the GUI that is populated with different database outputs.
2.) seperate the view from the data (which is what this whole fuss is about ;-)).
3.) add new controllers or models when needed without changing a lot of code.
As mentioned at the beginning I still appreciate every suggestion or improvement!
If you made it till the end of this post, I hope you found something to use in your own program!
regards,
Felix

How will I create a new music player screen on run time using reflection?

This is a interview question I was asked a week back, The problem was that
You have to develop a music player which gives the user the ability to create a new theme and use it.
I said that let's say there is a theme class like this
Class theme{
par1;
par2;
par3;
getter,setter
}
When the user tells our player to create a new theme, we will ask for these parameters and by using setter, we can have a theme object with parameters than can be used for rendering.
However he told me that this a java reflection question, he said you are supposed use reflection to get the class name etc.
Does anybody have any idea how reflection can be used here? or Have they ever been asked a question similar to this? Did they use reflection for solving?
I think it might have something to do with Factory design pattern but I can't find similarities between the question given and the design pattern?
What could be meant is class loading - to dynamically load the theme which also includes class loading - you get the needed class by calling Class.forName("org.package.YourTheme") and then create new instance by using reflection. And this instance or a plugin could customize your app.
EDIT:
This is how usually plugins are done in Java application. The developer creates a JAR containing it's implementation. In the simple case scenario he extends an interface in the app:
interface Theme{
void initialize();
void handleEvent(AppEvent e);
}
class MyTheme implements Theme{
public void initialize(){
// init logic
}
public void handleEvent(AppEvent e){
// handles the event
}
}
These two classes are packed by the developer into my-theme-0.1.jar.
A user downloads them on the web and copies them into the themes folder of his app.
When the app starts (or this could also be done during runtime) it scans the themes folder and loads all plugins by using URLClassLoader.
Then you load your theme:
final Class<?> settingsClass = classLoader.loadClass("MyTheme");
Theme theme = (Theme) settingsClass.newInstance();
theme.initialize();
I think one possible the solution could be as follows:
We'll use reflection to get all the attributes, these attributes would then be used to bring the customizable parameters up to the user.
Let's assume this is our theme class:
Class Theme{
//Customizable Theme related attributes
private Color background;
private Color baseColor;
//Business Domain related attributes
private User user;
}
We can use reflection to get the list of attributes Theme::getDeclaredFields, then we can get their names and inform the user about these attributes and "ask" him for what values he wants to customize.
The problem here is our class have attributes that aren't relevant to the theme 'look & feel' fields. For example the theme user field (owner?) shouldn't be brought to the user. This problem can be solved by using annotations (>= JDK 1.5)
Our class would then look like this :
Class Theme{
//Customizable Theme related attributes
#LookAndFeel(alias="Background", description="The background color of the player")
private Color background;
#LookAndFeel(alias="Base Color", description="The base color of the player")
private Color baseColor;
//Business Domain related attributes
private User user;
}
Now using reflection again we can bring up only the Look and feel related attributes (by inspecting the annotations), and we have as a bonus a user-friendly information about the fields : Ex. we will be able to tell the user that there is some "Base Color" parameter (better than using our attribute name "baseColor") that he can adjust.

Best design pattern to implement upload feature

I am working on a web application which is based on spring MVC. We have various screens for adding different domain components(eg. Account details, Employee details etc). I need to implement an upload feature for each of these domain components i.e. to upload Account, upload employee details etc which will be provided in a csv file (open the file, parse its contents, validate and then persist).
My question is, which design pattern should i consider to implement such a requirement so that upload (open the file, parse its contents, validate and then persist) feature becomes generic. I was thinking about using the template design pattern. Template Pattern
Any suggestions,pointers,links would be highly appreciated.
I am not going to answer your question. That said, let me answer your question! ;-)
I think that design patterns should not be a concern in this stage of development. In spite of their greatness (and I use them all the time), they should not be your primary concern.
My suggestion is for you to implement the first upload feature, then the second and then watching them for what they have that is equal and create a "mother" class. Whenever you come to a third class, repeat the process of generalization. The generic class will come naturally in this process.
Sometimes, I believe that people tend to over engineer and over plan. I am in good company: http://www.joelonsoftware.com/items/2009/09/23.html. Obviouslly, I am not advocating for no design software - that never works well. Nevertheless, looking for similarities after some stuff has been implemented and refactoring them may achieve better results (have you already read http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=sr_1_1?ie=UTF8&qid=1337348138&sr=8-1? It is old but stiil great!).
A strategy pattern my be useful here for the uploader. The Uploader class would be a sort of container/manager class that would simply contain a parsing attribute and a persistance attribute. Both of these attributes would be defined as an abstract base class and would have multiple implementations. Even though you say it will always be csv and oracle, this approach would be future-proof and would also separate the parsing/verifying from the persistence code.
Here's an example:
class Uploader
{
private:
Parser parser_;
Persistence persistence_;
void upload() {
parser_.read();
parser_.parse();
parser_.validate();
persistence_.persist(parser_.getData());
}
public:
void setParser(Parser parser) {parser_ = parser;}
void setPersister(Persistence persistence) {persistence_ = persistence;}
};
Class Parser
{
abstract void read();
abstract void parse();
abstract void validate();
abstract String getData();
};
class Persistence
{
abstract persist(String data);
};
class CsvParser : public Parser
{
// implement everything here
};
// more Parser implementations as needed
class DbPersistence : public Persistence
{
// implement everything here
};
class NwPersistence : public Persistence
{
// implement everything here
};
// more Persistence implementations as needed
You could use an Abstract Factory pattern.
Have an upload interface and then implement it for each of the domain objects and construct it in the factory based on the class passed in.
E.g.
Uploader uploader = UploadFactory.getInstance(Employee.class);

Places where JavaBeans are used?

What is a JavaBean and why do I need it? Since I can create all apps with the class and interface structure? Why do I need beans? And can you give me some examples where beans are essential instead of classes and interfaces?
Please explain the essentiality of a bean in the below context:
Wep apps
Standalone apps
They often just represent real world data. Here's a simple example of a Javabean:
public class User implements java.io.Serializable {
// Properties.
private Long id;
private String name;
private Date birthdate;
// Getters.
public Long getId() { return id; }
public String getName() { return name; }
public Date getBirthdate() { return birthdate; }
// Setters.
public void setId(Long id) { this.id = id; }
public void setName(String name) { this.name = name; }
public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
// Important java.lang.Object overrides.
public boolean equals(Object other) {
return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
}
public int hashCode() {
return (id != null) ? (getClass().hashCode() + id.hashCode()) : super.hashCode();
}
public String toString() {
return String.format("User[id=%d,name=%s,birthdate=%d]", id, name, birthdate);
}
}
Implementing Serializable is not per se mandatory, but very useful if you'd like to be able to persist or transfer Javabeans outside Java's memory, e.g. in harddisk or over network.
In for example a DAO class you can use it to create a list of users wherein you store the data of the user table in the database:
List<User> users = new ArrayList<User>();
while (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong("id"));
user.setName(resultSet.getString("name"));
user.setBirthdate(resultSet.getDate("birthdate"));
users.add(user);
}
return users;
In for example a Servlet class you can use it to transfer data from the database to the UI:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
List<User> users = userDAO.list();
request.setAttribute("users", users);
request.getRequestDispatcher("users.jsp").forward(request, response);
}
In for example a JSP page you can access it by EL, which follows the Javabean conventions, to display the data:
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Birthdate</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td><c:out value="${user.name}" /></td>
<td><fmt:formatDate value="${user.birthdate}" pattern="yyyy-MM-dd" /></td>
</tr>
</c:forEach>
</table>
Does it make sense? You see, it's kind of a convention which you can use everywhere to store, transfer and access data.
See also:
JavaBeans specification
Beans themselves
JavaBeans are everywhere, they're a convention and just about every single slightly larger library out there uses those conventions to automate things. Just a few reasons why JavaBeans should be used:
They serialize nicely.
Can be instantiated using reflection.
Can otherwise be controlled using reflection very easily.
Good for encapsulating actual data from business code.
Common conventions mean anyone can use your beans AND YOU CAN USE EVERYONE ELSE'S BEANS without any kind of documentation/manual easily and in consistent manner.
Very close to POJOs which actually means even more interoperability between distinct parts of the system.
Also there's of course Enterprise JavaBeans which are a whole another matter and shouldn't be mixed with plain JavaBeans. I just wanted to mention EJB:s because the names are similar and it's easy to get those two confused.
Beans in web applications
If you consider "normal" JavaBeans in web app context, they make more sense than wearing shoes in your legs. Since the Servlet specification requires for sessions to be serializable, it means you should store your data in session as something that's serializable - why not make it a bean then! Just throw your SomeBusinessDataBean into the session and you're good to go, laughably easy, specification-compliant and convenient.
Also transferring that data around the application is easy too since JavaBeans help you to decouple parts of your application completely. Think JavaBeans as a letter and various subsystems of the application as departments within a very large corporation: Dept.A mails a bunch of data to Dept.B, Dept.B doesn't know -or even care- where the data came from just as it should be and can just open the letter, read stuff from it and do its thing based on that data.
Beans in standalone applications
Actually what's above applies to standalone apps too, the only difference is that you can mess up with the UI a bit more since standalone applications have stateful UI:s while web applications have statelss UI:s which in some cases only simulate stateful UI:s. Because of this difference, it's easier to make a mess with standalone application but that's worth a whole another topic and isn't directly related to JavaBeans at all.
A bean is nothing much, really. For a class to be a "bean", all it requires is:
to have a public, no argument constructor
to be serializable (to implement the Serializable interface, either directly or through one of its super classes).
To that, you can add getters and setters for properties of the class that conform to a specific naming convention if you want the fields to be discoverable in certain circumstances (e.g. making that class some object you can drag and drop from a visual editor in your IDE, for example).
You can find more directly from Sun here.
A Java Bean is a software component that has been designed to be reusable in a variety of different environments. There is no restriction on the capability of a Bean. It may perform a simple function, such as checking the spelling of a document, or a complex function, such as forecasting the performance of a stock portfolio. A Bean may be visible to an end user. One example of this is a button on a graphical user interface. A Bean may also be invisible to a user. Software to decode a stream of multimedia information in real time is an example of this type of building block. Finally, a Bean may be designed to work autonomously on a user's workstation or to work in cooperation with a set of other distributed components. Software to generate a pie chart from a set of data points is an example of a Bean that can execute locally. However, a Bean that provides real-time price information from a stock or commodities exchange would need to work in cooperation with other distributed software to obtain its data.
We will see shortly what specific changes a software developer must make to a class so that it is usable as a Java Bean. However, one of the goals of the Java designers was to make it easy to use this technology. Therefore, the code changes are minimal.
Advantages of Java Beans
A software component architecture provides standard mechanisms to deal with software building blocks. The following list enumerates some of the specific benefits that Java technology provides for a component developer:
A Bean obtains all the benefits of Java's "write-once, run-anywhere" paradigm.
The properties, events, and methods of a Bean that are exposed to an application
builder tool can be controlled.
A Bean may be designed to operate correctly in different locales, which makes it
useful in global markets.
Auxiliary software can be provided to help a person configure a Bean. This software is
only needed when the design-time parameters for that component are being set. It
does not need to be included in the run-time environment.
The configuration settings of a Bean can be saved in persistent storage and restored
at a later time.
A Bean may register to receive events from other objects and can generate events that
are sent to other objects.
Here's a simple example of a Javabean:
public class MyBean implements java.io.Serializable
{
protected int theValue;
public MyBean()
{
}
public void setMyValue(int newValue)
{
theValue = newValue;
}
public int getMyValue()
{
return theValue;
}
}
This is a real Bean named MyBean that has state (the variable theValue) that will automatically be saved and restored by the JavaBeans persistence mechanism, and it has a property named MyValue that is usable by a visual programming environment. This Bean doesn't have any visual representation, but that isn't a requirement for a JavaBean component.

Categories

Resources