Dynamic Expansion of Java applications

Source: Internet
Author: User

 

Abstract: Do you want to write programs that can be extended without changing the source code? This article introduces how to useInterface and dynamic class load to create a highly scalable system. You can also learn how to extend the program without your source code. First, let's look at a simple example that does not use interfaces and dynamic loading. Then, let's talk about an example of a dynamic loading class that is read by a file or database table.

Have you ever developed an application that frequently adds new features? In the following example, the marketing department will provide various price processing for each customer. Your program needs to deal with these new requirements, and you must also allow users to customize your software without changing the source code.

Can you avoid modifying existing code and test new functions? Can you add new classes without re-compiling all the items? The answer is yes. As you may have guessed, it is to use interfaces and dynamic classes for loading.

The classes and systems described here are simplified for convenience.

What is an interface )?

Interface only describes how an object is called. When you define an interface, you define how other objects use it.

For most Java users, you may already know what interfaces are. But for those who are still unclear, I will introduce some basic knowledge and then create some complex examples. If you are clear about the interface, you can directly jump to the section "using strings to specify the class name.

Interface power

The following example illustrates the power of an interface. Assume that your customers engage in brokerage and they want you to establish a transaction system. Their transactions are various: including stocks, bonds, and daily necessities. The number of transactions for different customers is also different, which is defined by the number of customers called pricing plans.

First, consider the design of the class. The main classes and their attributes are defined by the customer. They can be:

Customer: Name, Address, Phone, and PricingPlan

Trade: TradeType (stock, bond, or commodity), ItemTraded (stock mark), NumberOfItemsTraded, ItemPrice, CommissionAmount

PricingPlan: calls a process to calculate the CommissionAmount of the transaction.

Do not use the interface Encoding

You can skip the interface when starting encoding, and then use the code to enhance its functions. The customer now has two price plans:

Plan 1: for regular customers, $20/transaction

Plan 2: The first 10 transactions in a month, $15/transaction, and then $10/transaction

The Trade object uses a PricingPlan object to calculate the customer's commission. You have created a PricingPlan class for each price plan. For Plan 1, this class is called PricingPlan20, and plan 2 class is called PricingPlan1510. Both classes calculate Commission through a process called CalcCommission. The Code is as follows:

Class Name: PricingPlan20

Public double calculateCommission (Trade trade)
{
Return 20.0;
}


Class Name: PricingPlan1510

Public double calculateCommission (Trade trade)
{
Double commistion = 0.0;

If (trade. getCustomer (). getNumberOfTradesThisMonth () <= 10)
Commistion = 15.0;
Else
Commistion = 10.0;

Return commission;
}

The following code gets the commission in the transaction:

Public double getCommissionPrice ()
{
Double commissionPrice = 0.0;

If (getCustomer (). getPlanId () = 1)
{
PricingPlan20 plan1 = new PricingPlan20 ();
CommissionPrice = plan1.calculateCommission (this. getCustomer ());
Plan1 = null;
}
Else
{
PricingPlan1510 plan2 = new PricingPlan1510 ();
CommissionPrice = plan2.calculateCommission (this. getCustomer ());
Plan2 = null;
}

Return commissionPrice;
}

Use interface

Using Interfaces makes the preceding example easier. You can create the PricingPlan interface and define the PricngPlan class that implements this interface:

Interface Name: IPricingPlan

Public interface IPricingPlan {
Public double calculateCommission (Trade trade );
}

Because you define an interface, you do not need to define a method body for calculateCommission. The real PricingPlan class will implement this part of the code. Next, you need to modify the PricingPlan class. The first step is to declare that it will implement the interface you just defined. You only need to add the following code to the PricingPlan class definition:

Public class PricingPlan20 extends Object implements IPricingPlan {

In Java, When you declare that an interface will be implemented, you must implement all the methods in this interface (unless you want to create an abstract class, which is not discussed here ). Therefore, all classes that implement IPricingPlan must define a calculateCommission () method. All the tags of this method must be exactly the same as those defined by the interface, so it must accept a Trade object. Because the calculateCommission () method has been defined in both of our PricingPlan classes, because we do not need to make further modifications. If you want to create a new PricingPlan class, you must implement IPricingPlan and the corresponding calculateCommission () method.

Then you can modify the getCommissionPrice () method of the Trade class to use this interface:

Class Name: Trade

Public double getCommissionPrice ()
{
Double commissionPrice = 0.0;

IPricingPlan plan;

If (getCustomer (). getPlanId () = 1)
{
Plan = new PricingPlan20 ();
}
Else
{
Plan = new PricingPlan1510 ();
}

CommissionPrice = plan. calculateCommission (this );
Return commissionPrice;
}

Note that you define the PricingPlan variable as the IPricingPlan interface. The object you actually create depends on the customer's price plan. Since both PricingPlan classes implement the IPricingPlan interface, you can assign two new instances to the same variable. Java does not actually care about the actual objects that implement this interface, but it only cares about interfaces.

Use a string to specify the class name

Suppose the boss tells you that the company has two new price plans, and more. These price plans are $8 or $10 for each transaction. You decide to create two new PricingPlan classes: PricingPlan8 and PricingPlan10.

In this case, you must modify the Trade class to include these new price plans. You can add more if/then/else sentences, but this is not a good method. if the price plan becomes more and more large, the code will look very heavy. Another option is to create a PricingPlan instance through the Class. forName () method, instead of using new. The Class. forName () method allows you to create an instance using a string name. The following is an example of applying this method in the Trade Class:

Class Name: Trade

Public double getCommissionPrice ()
{
Double commissionPrice = 0.0;

IPricingPlan plan;
Class commissionClass;

Try
{
If (getCustomer (). getPlanId () = 1)
{
CommissionClass = Class. forName ("string_interfaces.PricingPlan20 ");
}
Else
{
CommissionClass = Class. forName ("string_interfaces.PricingPlan1510 ");

}

Plan = (IPricingPlan) commissionClass. newInstance ();

CommissionPrice = plan. calculateCommission (this );
}
// ClassNotFoundException, InstantiationException, IllegalAccessException
Catch (Exception e)
{
System. out. println ("Exception occurred:" + e. getMessage ());
E. printStackTrace ();
}

Return commissionPrice;
}

This part of the Code does not seem to be much improved. Because you must add the exception handling code, it actually gets longer. But what if you want to create an array of the PricingPlan class in the Trade class?

Class Name: Trade

Public class Trade extends Object {

Private Customer customer;

Private static final String []
PricingPlans = {"string_interfaces.PricingPlan20 ",
"String_interfaces.PricingPlan1510 ",
"String_interfaces.PricingPlan8 ",
"String_interfaces.PricingPlan10"
};

Now you can change the getCommissionPrice () method:

Class Name: Trade

Public double getCommissionPrice ()
{
Double commissionPrice = 0.0;

IPricingPlan plan;
Class commissionClass;

Try
{
CommissionClass =
Class. forName (pricingPlans [getCustomer (). getPlanId ()-1]);

Plan = (IPricingPlan) commissionClass. newInstance ();

CommissionPrice = plan. calculateCommission (this );
}
// ClassNotFoundException, InstantiationException, IllegalAccessExcepti

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.