I've read a lot of books on software design, and more and more I'm wondering if what I learned about separation of concern between business object and serialization makes me more productive.
I'm influenced by Domain Driven Design, so when I design my business classes I don't think about persistance. The only objects who are coupled to my database/web service technology/caching technology are encapsuled behind a repository with a nice domain interface.
To illustrate, for a traditionnal application database<->web service<->RIA, I design my business classes Account and Employee. Then if I want to get accounts from a data source I create a IAccountRepository, and implement methods to query, or add accounts to my data source.
To add caching capability to my application, it's only a matter of creating a proxy class which implements IAccountRepository and wraps the real repository, then inject it in my IOC container.
To implement a database repository, I use an ORM which create classes from my database schema, then I use create a translator to transform database classes to/from business classes, this way my business classes are decoupled from my database schema.
I also create dedicated data contract classes for my web services, then the web service use translators to transform an aggregation of business objects to its data representation from the web service perspective.
When I create my RIA application, again I design its own domain model, but this time the repository implementation use a webservice instead of the database (and again translators).
For WPF developers, I create then my ViewModel and my View.
I used to program like this.
BUT, when my boss comes and says : can you add a field to this form to... blah blah blah I must :
I'm more and more thinking to couple my business object with database access technology and web service technology or serialization technology.
This way I don't need to maintain my translators anymore. For example why not using attributes/annotations of these technologies on the business objects ? Yes it brings some contrains, yes I will need a get/set on my fields, even if I want my property to be readonly, yes my business module will have external dependencies. But I think it will result to less code, and a more maintenable system.
The implementation of my repositories will be trivial, and won't rely on translators.
Although I see advantages to code this way, I always feel guilty to code like this. I feel really guilty about adding a 5 attributes/annotations coupled with my data access technology/web service technology/Serialization technology on my business objects and I feel it's not right.
why my separation of concerns Database/Business objects/Web service, makes me write more code ?
Do you have some alternatives ?
Your personal productivity is not the point.
The point of separation of concerns is to increase the value of the software you produce by making it usable, maintainable and adaptable.
I'm sorry if this makes you write more code, but your time is typically a tiny fraction of the life-time cost of using, maintaining and adapting what you're writing.
Separation of concerns is essentially for keeping the life-long total cost of ownership down. It has little to do with your personal productivity.
If your boss is asking you for a pervasive change... well... it's pervasive. I'm sorry it's pervasive.
Edit 1
The value of your software is the value that is produced by people using it.
"Is it the purity/beauty of the code? To me, value is in simplicity and readability." It's neither. It's the value created applying the code to real-world problems.
If the code is hard to maintain, adapt or use, that devalues it. If the code is easy to maintain, adapt or use, then there are fewer barriers to getting full value from the code.
Your time developing the code is a tiny, tiny cost compared to the value of using it. Also, your time developing is a smaller cost than maintaining or adapting.
Edit 2
Pervasive change is an unavoidable consequence of building software. Nothing -- no practice -- can prevent your boss from making a change that breaks your architecture.
If you have one layer, almost any change breaks that layer.
if you have 3 tiers, 7 layers or n+1 layers, it's always possible for your boss to ask for a change that breaks more than one layer.
The idea is that MOST changes are isolated. Nothing can assure that ALL changes are isolated.
When designing an application, the levels of abstraction should provide value. They should not be there just because it is a 'best practice'. Some applications have a rich domain model and benefit from the layers of abstraction. However, an application that is very data centric without much logic may not have a need for as many layers.
I have seen some applications that define multiple layers corresponding to each object with the names dutifully matching the layer EmployeeDL, EmployeeBL, EmployeeUL. None of the objects added any value and simply passed values between layers from the user interface to the database. It was pointless.
I find when working with applications with a richer domain model, changes may affect multiple layers, but seldom are as simple as passing a value from the UI through several layers to the database. There is business logic in the middle that would be much more difficult to implement without the levels of abstraction.
At the end of the day, it is most important to choose an architecture that matches the needs of your application in terms of its complexity and maintainability.
A maintainable application is one which has a low cost of maintenance. If common changes take a long time, then that is not a maintainable application.
The key question to ask is how common feature requests are, versus technology changes.
If you change your preferred technology set every 3 months or so, then you will never have time to implement new features, so your architecture is optimal...
I also have the same experience, alot of the stuff I learned in school about abstraction and separation of "stuff" makes my code actually more and more complicated.
I'm come to realize that, when you have high cohesion (your classes are very small and very to the point), you will have high coupling. By simplifying each individual class further and further, each component will be more and more useless by itself; to get simple functionality you'll need to manage complex interactions between these simple "cohesive" objects.
Then, simple tasks will be complicated!! Think about reading a file in Java, I don't remember how to do it (I've had to do it many times), and I don't ever want to do it again.
In Python it's dead simple:
for line in open("filename"):
# do something with line
I'm not saying separation of concerns and abstractions are bad, just do them sanely.
IMO, it's always better with something that "just works" even if it's spaghetti, given that you do refactor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With