Let’s take a look at the following problem domains insurance and loan underwriting, more specifically, contracts. There are many industries that can drive a developer nuts. One of them is of course insurance, and the other is loan underwriting, especially mortgage loans. They change so often, and always create new products, with a new set terms and conditions, and you learn quickly to be very weary of your architecture because it can change at any moment.
I remember reading an article in the Wall Street Journal about insurance and how the industry has the ability to change the entire financial stability of the Global Market. In the 1970’s, FTC issued findings in Whole Life Insurance, and said that the product was not beneficial paid a measly 1.5% in interest. As a result, the industry decided they needed to revamp its entire product line. So they said, the heck with whole life, we need a new product, let’s create Universal life insurance, and solve all our problems, and the interest earned would now be closer to 15%. Their revenue streams now positive and the sale of the most beneficial job (insurance sales) in the late 70’s and 80’s created a massive shift of money. Trillions of dollars were transferred throughout the end of the century, in the largest money transfer of any kind in the history of the world.
My point is, the products the insurance industry offers varies often, and can have a significant impact on the financial market in a hurry. This can lead to the suits scrambling to have departments create a new product in a hurry. This brings us full circle to you, the poor developer left to create this “Magical” solution tomorrow, that was needed yesterday by the suits to gain a stronghold on the changing market.
I will give you my perspective from my limited business intelligence knowledge in insurance, and give my perspective on a more general design on contracts and policies. This domain basically revolves around a set of terms and a set of conditions, tied to a policy holder.
Terms:
Typically these terms (or definition), can join 2 or more people or business entities and an obligation. The term defines the obligations and is considered the “body” of the policy. Take for example a Term Life Insurance product. I, the underwriter, will pay out to your policy of 100,000 dollars to your beneficiary, if you die within the next term length x years. You, the policy holder, will pay us 30 dollars a month, for term length x years.
The problems you’re left with are, since these are set in stone as a contract, how do you maintain new products that might arise, and still maintain a good grasp on the policies that are already in place? How do you make adjustments to the policy, riders, etc., and still keep the terms in tact and know whether or not that adjustment was made prior to or after any particular date. We’ll talk about your inheritance model in just a bit.
Conditions:
The next portion is the conditions, which are by definition always includes the unknown and variables that would break the obligations and the policy is no longer valid. An example would be, if you jump off a bridge, we, the underwriter will not pay out any money. There are a series of these, which would be considered mostly the policy rules if these are broken this is not valid.
I hear what you’re saying about using inheritance to determine a whole life vs. term policy in way that inheritance makes sense. The problem here is that the products behavior can change, and they can change often. They can change from year to year, and their conditions can change. You can add a rider on your policy, in mid-stream, and those conditions can change as well.
In OO, we’re first taught about inheritance and that’s really the hook. Look see, a Car is a Vehicle, and a Truck is a Vehicle too. The IS-A construct makes sense and makes us believe that inheritance will solve all our problems. I’d like to say that a
Well that’s great and all, but the reality is that there is a huge difference in the components that make up these cars, and they potentially change every year. Just go into your local auto parts dealer and see the massive books they have on parts for individual cars.
So here’s my recommendation, and I’ve attached the sample code as well, because this editor applies breaks and it’s difficult to see. You will be able to see that the architecture and patterns in use, make it possible to not have to scramble all the time, even in a complex development environment, like yours. I recommend and show that using inheritance is good, but only for Type Matching only and not for behavior. Behavior typically varies the most, and changes the most. and behavior should be left to the Processors. This whole manager pattern follow the open/Closed Principle, meaning, the architecture is left open for inclusion but closed for modification, so you are able to add additional products at any time, and it will not affect any current code. Or if you have to suddenly change a product, you may do so without affecting any other code(nothing like bringing down an entire system). You will never be left having to manager a fury of if/then/else conditional logic, as all of the code as it’s place and we’re always separating out the code for the differing products. The code is not in one place as in the Components pattern by itself, however, in very large systems, it’s easier to manage many files because the different parts of the overall entity usually follow an organizational pattern to them as well. So behavior will always be found in a single location.
So this statement works, but there’s really nothing to TermLifePolicy, because the actual implementation is in the body and processors.
if (policy is TermLifePolicy)
All of the inheritance is mostly used only for type matching and all of the implemlentation code favors composition when coding toward an interface. The HAS-A Construct lends itself great with the Strategy Pattern, and does not tie yourself down with coupling. and lies within the body of the entity, Terms, Conditions, and PolicyHolder, using a Strategy pattern. I’m using a marriage of both the manager pattern and the Components pattern to show you that there is still flexibity in using both patterns, or I could use extensively one without the other and still be able to manage.
I hope this helps, I’m not sure it does, please let me know if I just made things more confusing.
Post Edited (Robert Hinojosa) : 11/11/2005 8:52:19 PM GMT
Robert Hinojosa ------------------------------------- Member of the Codesmith Tools, .netTiers, teams http://www.nettiers.com-------------------------------------
Zach,
That syntax is for generics in .Net 2.0. In a nutshell, generics give you the ability to have strongly typed collections or lists. List<Person> says that you are declaring a List object that contains Person objects. It gets around having to cast objects are you retrieve them from the collection. Just do a search on google for generics and you will get all the info you ever wanted.
Ben Johnson------------------------------ Member of the .NetTiers team Visit http://www.nettiers.com------------------------------
This is a fantastic article, thanks!
Am I right in assuming the newer xxxxxxService classes are synonomous with the Manager class in this example? How would Service.Execute(ProcessList) be incorporated as in this example there is no processing pipeline, just a single processor. Also, here the processor has multiple public methods: Create, Save, Delete, GetBy, one for each unit of work. Where appropriate should they be replaced with methods in the Service class calling a dedicated processor for each work unit? e.g.:
public void CreatePolicy (IPolicy policy)
{
Execute (new CreatePolicyProcessor (policy));
}
Obviously some of those methods are now provided out of the box.
Also in the above example where do the derived entity types such as TermLifePolicy : Entities.Policy, IPolicy come from? Can they only practically be used for Create operations? When updating you have usually retrieved and existing entity which would of the base type Entities.Policy.
Any chance of a few pointers as to how this could be implemented with the 2.2 templates?