How to handle different versions of (credit) products?
I work for a bank where we sell various financial products. For example credit products. Let's say the name of a credit product is BicycleLoan with which you can buy bicycles. Buying a bicycle on loan can be done only if you fullfill the requirements of the Bank. If it is ok, you can get that bike. We print a contract as well.
My question is: How to handle a situation when the business rules of the BicycleLoan changes or the printed contract changes? Of course I can change the business rules of that product by changing the BicycleLoan.java but if I do so, then the old BicycleLoan-s will become deprecated. It means for example I can not print an old loan contract because the new BicycleLoan.java has less fields than the old BicycleLoan.java.
Should I use versions for that products? And If I did so, how can I organize them? BicycleProductVersion1.java, BicycleProductVersion2.java? And should I use different database tables (to store the loans) for the different product versions ( for example if a new version contains plus info)?
[1063 byte] By [
Miklewa] at [2007-10-2 21:50:22]

desribe the rules in configuration rather than code, perhaps?
I think I would end up in using some sort of business rule engine in that case because our rules are very difficult. I can not see how it would solve or versioning problem.
But I still has no solution with the database problem. Let's say a BicycleLoan has fields like: amount, bicycleType, tyreType. I can store these data in a table called BICYCLELOAN. But what can i do if after a year the BicycleLoad changes so that we don't need the tyreType. The BICYCLELOAN still has a TYRETYPE column. So, should I use a new table or the old one? If I used the old one I would have to enable null value in the column TYRETYPE, but it is dangerous because the old type of BicycleLoan must have a tyreType and I want to be sure it has in the database table as well.
code generate the crud and BOs, write one time script to transfer the data, remove old table, rename new table.
> then the old BicycleLoan-s will become deprecated.
> I can not print an old loan contract because
I you need to continue to support the old versions then it is not deprecated.
Look the Command Pattern to delegate implementation of each product to Classes that represent each class of Financial Products. BicycleLoan would the interface be a group of BicycleLoan products implementing the BicycleLoan interface but with different internal rules.
> I can not print an old loan contract because the new BicycleLoan.java
> has less fields than the old BicycleLoan.java.
Program to the Interface not the behaviour.
> should I use different database tables
No, use Polymorphism, store an Loan type indicator & version.
Use a class factory to instantiate the appropriate version
You _may_ find the Chain of Responsibility useful in some circumstances.
Thank you for your answer.
You mean something like this?
interface BicycleLoan {
}
/**
* this type of BicycleLoan can be
* purchased if the person has a wife
*/
class BicycleLoanForSpecialBikes implements BicycleLoan{
public Wife getWife(){
...
}
}
/**
* this type of BicycleLoan can be
* purchased if the person has a Car
*/
class BicycleLoanForSpecialBikes implements BicycleLoan{
public Car getCar(){
...
}
}
class BicycleLoanFactory{
static BicycleLoan instantiateLoanByIdFromDatabase(ObjectID id){
...
return ...;
}
static BicycleLoan createBicycleLoanWithWife(int amount, Wife wife){
...
return ...;
}
static BicycleLoan createBicycleLoanWithCar(int amount, Car car){
...
return ...;
}
}
-
CREATE TABLE BICYCLELOAN (
oid VARCHAR2(10) NOT NULL,
loan_version NUMBER(3),
amount NUMBER(10,2),
car_oid VARCHAR(10),
wife_oid VARCHAR(10)
);
mchan0:I'm sorry but I don't understand. Would you explain it in more details, please?
>
> But I still has no solution with the database
> problem. Let's say a BicycleLoan has fields like:
> amount, bicycleType, tyreType. I can store these data
> in a table called BICYCLELOAN. But what can i do if
> after a year the BicycleLoad changes so that we don't
> need the tyreType. The BICYCLELOAN still has a
> TYRETYPE column. So, should I use a new table or the
> old one? If I used the old one I would have to enable
> null value in the column TYRETYPE, but it is
> dangerous because the old type of BicycleLoan must
> have a tyreType and I want to be sure it has in the
> database table as well.
To be clear - you don't store rules. What you store is the results of rules.
Secondly you should use a meta-data solution. Thus you do not have a field called TYRETYPE. Instead you have a field called ATTRIBUTE. That field probably will tie to another table which is an enumeration table. One of the rows in that table would have a value called "TYRETYPE" (data not a field.)
An example attribute table would look like
attribute_id
attribute_enum id (foreign key)
attribute_value varchar(128)
You can choose to add as much complexity as you wish to this. For example by having a way to specify the field type and specify when it was no longer in use (the type, not the value.)
Not that old attributes do NOT go away until all contractual obligations that use them are removed. Normally this just means that they never go away since there are some very long term contracts.
There are going to be some fields that you will still keep however. That is because they are often used in queries and/or fields that will reasonably never go away (like initial loan amount.)
If you chose you could try to do meta storage of rules. You could for example store java source code in the database. And index that via a field which allows you to determine how the value that is stored was derived. You shouldn't do this unless the business people (not you) insist that this is required for legal/contractual reasons.
> Thank you for your answer.
> You mean something like this?
You need to use delegation. Follow the rule of 'Tell Dont Ask' (#1). Delegate responsibility to an object to do something don't ask it about its properties. Getters that expose the internal implementation of an object is an Anti-Pattern.
So use:
policy.print() ;
not
String text = policy.getText()
System.out.print( text ) ;
Also checkout the Demeter's Laws (#2) .
(#1) http://c2.com/cgi-bin/wiki?TellDontAsk
(#2) http://c2.com/cgi-bin/wiki?LawOfDemeter
thanks, I'll think it over and come up with something later.
starting from the Law Of Demeter I've found the http://www.objectmentor.com/publications/Principles%20and%20Patterns.PDF with which I started to understand how to handle this problem.So, I just wanted to thank you all again