Some design questions.

Some design questions.

Old forum URL: forums.lhotka.net/forums/t/679.aspx


ajj3085 posted on Thursday, July 20, 2006

Hi all,

I have two applications now, which currently share a common Contacts business layer.  The main application uses all of the layer, but the other app, which is actually an outlook plug-in, uses only a few objects.  My concern though is that I may make some changes to a portion of the database or business object model which don't affect the plug-in, I don't want to re-deploy the plugin, but at the same time technically the libraries its using is outdate.   I'm starting to think I should seperate out the functionality common to both to yet another assembly. 

Also, I have some classes in the Contacts assembly which could be used as is in my Quoting business assembly.  My thought is to move these classes to a base business assembly, which is referenced by both.  Does this sound acceptable?  Or should I just forget about what I have in my Contacts assembly for now, and design what I need for quoting in isolation?  I don't want to tightly couple the assemblies, but it may be useful to have them collaborate by using shared interfaces.

Thanks
andy

RockfordLhotka replied on Thursday, July 20, 2006

My opinion on this isn't likely to be popular, so take it for what it is worth.

There's the idea that the primary goal of OO is reuse. I think that is a myth. Reuse is a fortunate side-effect if and when it happens, but it isn't the goal. The goal is maintainability.

In practical terms this means that an object should exist within a use case. If it happens to fit into another use case that's awesome, and you should reuse it - but only if you don't have to compromise the object's responsibility to do it (in other words, you shouldn't add conditional code to make it work in another use case). This kind of reuse is surprisingly common, even with these rules, and that is good.

But then you get into cross-application reuse. Over the past 12 or so years, I've come to the conclusion that this type of reuse has a higher cost than benefit. Another word for this type of reuse is coupling - because you are taking a tightly coupled dependency on a shared assembly/component. Yes, you get reuse, but you also effectively combine both your applications into one application that must be versioned together. That cost is too high!

This is one area where I think the SOA people are getting it right. Applications should be silos. They should share nothing. No sharing of assemblies, components or databases.

Over the years we've all tried different things - using formal interface DLLs to help decouple applications from their actual components, etc. But it has never worked. Even if you can change the underlying assembly without changing the interface, you still changed the underlying assembly, and that functional (semantic) change almost always breaks other consumers of that assembly. This was (and is) one of the primary causes of DLL hell.

So what I am suggesting? That you make a concious choice as to whether you have a single big application with multiple UI's, or seperate applications. If you have seperate applications, then I suggest you not share assemblies between them.

If that is too hard to swallow, then share the assemblies, but do so in a side-by-side manner. In other words, allow each application to have a copy of the assembly, and to continue running with that copy even if a newer version is available and in use by another application. This is the default .NET way of doing things anyway, so is easy from a technical perspective - but it may or may not be practical from a business perspective...

ajj3085 replied on Thursday, July 20, 2006

Some very good points to think about.  The end goal is that we have one database with contacts, quoting / invoicing, and inventory information.  Sales needs to know how many items we have in stock right now, orders place need to reduce inventory, and parts / manufacturing needs to add to inventory / add new items, etc.  One database to rule them all, as it is.

So I've been thinking of this as one application with many UIs.  One for sales / invoicing, one for manufactoring, and in the future, we want to allow customers to order over the web.  Maybe this is the wrong approach though?

More specifically, the two apps I have now are the full contacts app, and the outlook plugin.  The app supports the idea of 'notes' for a contact.  Notes have a subject, body and attachments.  Users could drag an email to the desktop, then drag the .msg file to my application to save it as a note for a contact.  The outlook plugin simply automates this process; its adding a new note (the email) to the contact's notes as automatically. 

I'm not sure if that changes anything though, and I certainly need to think about this quite a bit... I'm starting phase two, which will build the quoting / invoicing system.  Phase three will add the manufacturing piece (which will affect ordering behind the scenes, as a placed order will now have the responsibility to update inventory).  I think the use case is mostly the same, except with that added responsibility..

Thanks for the reply.
Andy

malloc1024 replied on Thursday, July 20, 2006

If you are going to use the Contacts assembly in multiple projects, break it up logically.  Do not break it up based up shared functionality.  This will help solve your problem and protect you from future projects that use these assemblies.
There is nothing wrong with sharing assemblies as long as it done correctly.  This can get tricky though.   Make sure that the behavior of the classes doesn’t change much between applications.  If they do change slightly, there are elegant ways to handle this.  However, if the differences become great, it just becomes a nightmare.  This is one of the reasons why a DAL is valuable.  You can swap in a different DAL for different project without creating problems.  Further, before you share assemblies between projects, keep in mind the OOP principles.  These will help guide you down the right path.

ajj3085 replied on Thursday, July 20, 2006

malloc1024:
If you are going to use the Contacts assembly in multiple projects, break it up logically.  Do not break it up based up shared functionality.


Contact note managment, although a small subset of the functionality, could be a good logical seperation.  This is where I was leaning.

malloc1024:
Make sure that the behavior of the classes doesn’t change much between applications.


This won't be a problem.  The Note concept in each application will always be the same; this is because the plug-in is simply automating something that can be done manually in the main application.

malloc1024:
If they do change slightly, there are elegant ways to handle this.


Would you mind sharing what these ways may be? Big Smile [:D]

malloc1024:
Further, before you share assemblies between projects, keep in mind the OOP principles.


Always, well I try to anyway.  In this case, one application is simply automating something that can be done manually.  The end result is the same.

Thanks for the post.
Andy

malloc1024 replied on Thursday, July 20, 2006

It sounds like you are on the right track.
What I meant about elegant ways are design patterns.  Design patterns like the strategy, decorator, state etc. will allow you to change the behavior of an object dynamically.  They will allow you to add code instead of change code (open-closed principle).  Therefore, making changes to your code will not break things.  Design patterns, when used correctly can help bridge the differences between your projects elegantly.

ajj3085 replied on Thursday, July 20, 2006

Ah, got ya.  Good thing I just got a design patterns book; I need to finish though, i've only read the stragegy pattern so far.

Copyright (c) Marimer LLC