Test Driven Design and Layered architecture [closed] - c#

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
How to apply TDD over enterprise application that has layered architecture?
I want to know how to apply TDD to an application that has following
WPF application (6-7 screens)
3-4 Modules (Prism modules)
Some application services (Logging, Exception Handling, Security, Authorization, Core Business services library)
Data Access Layer (using Entity Framework)
A bunch of WCF services
As I understand, first thing is to get the architecture right. As a result, Components are identified.
Next is to develop the components independently, where I stuck.
With TDD, design (of a component) evolves with time. For a component following is the way (I perceive) to go with TDD
Identify all use cases
Identify all test cases
For each test case, write all scenario, and for each scenario, write a failing test case. Make little code, so that test case is passed. Add to list, if new scenario is found
Follow Red-Green-Refactor until all the test cases (corresponding to all scenario) are passed
In the refactoring, dont forget DRY, YAGNI, Mocking, DI, etc,etc.
End result is well designed Component (how much well designed depends on experience and skills of developer).
Problem i face is, For a component, until i reach to Step 6 of TDD process, i donot know the interfaces. Since there are multiple components, multiple teams, No body is sure what they will come up with.
Now the summary Questions based on above scenario
Is there some basics that I am missing? Please point me to appropriate resources if yes.
How to apply TDD over layered architecture?
How to do parallel development of multiple components
Best practices for TDD with WPF UI (PRISM)
Best practices for TDD with Database (using Entity Framework)
How to decide WCF service contract, when using TDD?

I think you have the order wrong. You're choosing the architecture, then trying to get there with TDD. The idea behind TDD is to start w/ nothing, and arrive at an layered architecture if it's needed.
Of course, that probably doesn't help when you're looking at a very large project, because there has to be some organization to it all. My usual approach is to try to divide the work into something that makes sense to real people (not programmers). And no, I'm not really talking full Domain Driven Design. I'm referring to just thinking of the different pieces as an outsider would.
For example, if I want to make a program that represents a cash register (something that can hold money and figure totals).
What's the first thing I want it to do? Hold and dispense money. So, I need a drawer (first component, give it to a team). I need a button to open it (second component, second team), etc... The key is to focus on what it should do, not how it should do it.
Yes, there's a lot of contract/protocol talks that have to happen. Those are things the teams involved will have to work out as they hit the problem. The key is to focus on what you want it to do. Solve the now problem. Don't pre-optimize. You'll probably find that not all of the components require all of the layers.
The short answer to the best practices questions is "it depends." (The cheesy, common, and overused IT answer.) The general rules are you want to focus on behavior, not implementation. Ensure you can trust the tests (they produces the correct results all the time). Make sure you test as much as is possible... Or, numbered...
Start with tests, not design. Roy Osherove and others have a tons of writings on the subject. His book, along w/ Micheal Feathers are the best place to start.
If you start w/ tests, and the layers evolve as you fulfill more tests, you wind up with TDD over a layered architecture.
Divide them in a way that makes sense. My rule is to stick to what makes sense in the real world. Engine team gets the engine, tire team gets the tire. Make sure people communicate.
I don't use PRISM.
I don't use EF, but can say that database testing is a whole can of worms. Integration testing involves a lot of environmental configuration and such. Ayende has quite a few blog posts on this.
Danger Will Robinson. What makes you so sure you need a WCF service contract?
Sorry if this was really vague. Google the names I dropped, they're good places to start. If you want a leg up on TDD, hire a couple experienced coders and use pair programming. If you can't afford that, hire someone to come in and do some training, then do pair programming. Can't do that? Get some books and use pair programming.
Then, beat the pairs to ensure they're writing tests first.
At the end of the day, it's about deciding what you want something to do, then letting the tests evolve the architecture. Not the other way around.

I think that you are going in the right direction with all of your plans so far. What I advise is that you spend just enough time on upfront design so that you DO have the interfaces between each layer defined. It's simply impractical to start doing any development (let alone TDD) without it. Once the interfaces are agreed upon by all teams, you can then easily transition to TDD by using mock objects to implement the interfaces. There are many well established mocking frameworks available, such as Rhino Mocks. The idea of creating the interfaces upfront may be easier said than done, and you will undoubtedly end up having to make changes along the way. But you need to have a starting point. This is sort of challenge is exactly where a Component Model Diagram becomes useful. By having the teams work together to create this upfront, you won't be able to predict the final interfaces exactly, but you will get the high level details hammered out which will help avoid earth-shattering refactorings later in the project.
Also, I would give special consideration to your database layer. This is a debatable topic worthy of it's own separate discussion. Using EF you will find that you cannot simply "mock out" the entire layer. You would have to create a whole separate abstraction on TOP of EF to do so. Doing so may add unnecessary complexity to your application. You should consider very carefully if this is required - if you can just populate a test database with test data, there's no reason not to let your automated tests directly call the database.

Related

What are the disadvantages/advantages of starting a program from UI Layer?

Recently, our Development team came up with an idea of reorganizing our processes. Aside from the new methodology that needs to be implemented, our consultant suggested that we should start our development from UI layer and release it weekly for user testing even if the backbone is not yet completed. His idea is that, we need to release a module as quickly as possible in weekly bases. According to him, the users do not really mind what's behind the application, their concern is only about the output of the application (i totally agree with Him on this). Although I am not totally convinced with the idea of starting from UI Layer as I tend to start coding either from the application's domain or the Database instead of doing the UI Design. I don't know if I am just being bias here.
Any thoughts, ideas or suggestions would be very much appreciated.
This is a very broad question, not knowing your development/sale structures.
I've expierienced this kind of points very often, resulting in a not-maintainable whatever (The result had nothing to with software anymore)
Modern development will mostly fail without an strategy like Scrum or Agile.
Consultants and sales-department often push in that direction because they want to sell stuff and get therefore money in their own pocket due to provision. Usually they have nothing bad in their mind. They simply just dont know it better and probably have never heard about Softwarearchitecture before.
Anyway, following some points on pros and cons:
Pro
Sales-Dudes can sell products better because they have something to show to the customer
Users/Customers can get an early feel for the Application and can point out what they like and what you have to improve
Cons
Hardly you will be able to follow architectonical patterns (MVVM just to name one)
Mosty you produce non-maintainable-code
In most cases your application will not be extensible (Plugins)
Sales-Dudes and Users usually dont know what they even want, ending up in applications like this
Your code will be really hard to test. So TDD will not be possible
These are only a few examples stuck in my mind. I could extend this list to 4 pages why it is NOT a reasonable idea to develop by UI-First.
I know this is mostly based on my opinion, but its also full of Expierence i made by myself, resulting in developing the same Application over and over again.

Best c# archeticture / pattern for communicating between separate plugins of application [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I am currently involved in designing a system from the ground up, and we have come across an architectural design scenario that I'm not sure of the best way to solve - but I'm sure other people have solved and there's probably even a pattern for it.
The story so far:
We have a multi-tenent website in which we are implementing various features as Plugins, our clients will choose which plugins they wish to use in their application. And each plugin could have a variety of "widgets" that a user can add to a page. (eg. similar idea to how Android apps often come with widgets that you can add to the main screens).
A plugin can depend upon other plugins to be enabled (eg an eCommerce Plugin would need Payments Plugin). Also plugins can use other plugins to enhance thier functionality (eg Blogs plugin has the option of using the Comments plugin, could also use Comments with eCommerce Products).
As much as possible, we want each plugin to be self contained, with a very skinny plublic interface. We beleive this separation of concerns will give us the best long term flexibility and maintainablility of the overall system.
The problem:
When we started to layout all the plugins we currently know about (let alone future requriements), and their depenendencies and possible relationships with other plugins - it started to have a very strong resemlance to a spider web of madness. And we also started to see some Circular References happening.
eg Navigation Plugin needs to know about what Pages are on the site. But you can also add a Navigation widget to a Page.
The partial/potential solution:
We were thinking that each plugin should be completely separate from other plugins, but would get info from and communicate with other plugins via Messages. These messages can be broken down into 2 basic types
request for info from another plugin (Request / Response Messages)
event notifications (Event Messages)
Both of these message types will be very simple DTO type classes - they shouldn't contain any business logic - just the info required for some other service to process the request, and provide a response.
I have mocked up a very simplified version of a couple of plugins and what we see the solution to their interactions to other plugins would be: http://screencast.com/t/Mdb9wUmMF
In this diagram, the Navigation, Page, Search and Other plugins wouldn't know anything about each other. But they would know about the Messages that are available, and the ProcessMessages interface.
eg Request / Response Messages
The Navigation and Other Plugins would know that if it sends a GetPagesRequest to ProcessMessages, it will get back a PagesResponse with all the info they need. (The Nav/Other plugins would need a response to the GetPagesRequest immediately.)
The Navigation and Other Plugins would't know anything about the Page plugin.
Request / Response Message Requirements
A plugin that raises a Request Message would always (usually?) expect a Response message immediately.
Only 1 service would know how to process a Request Message, and provide the Response Message that would get passed back to the calling Plugin.
eg Event Messages
When a user updates the url of a page in the Page Plugin, the plugin would send a PageUrlUpdated message to ProcessMessages. The Navigation and Other plugin would then consume the PageUrlUpdated message and do whatever it needs to.
Event Message Requirements
A plugin that raises an Event would never expect a response.
0-Many plugins might consume a given message.
(Tech Note: for Event messages we are going to send them to MassTransit and RabbitMQ - then have 1-n consumers for each message)
The questions
From a few sketches we've made, the above idea seems to work, and has a lot less inter-dependencies between different elements of the system. But I don't know the name of the design pattern or architectural structure - or if I'm on complete the wrong track. I was hoping that someone could point me to the proper solution - some good documentation and examples would be excellent. (Trying to avoid re-inventing the wheel - and an existing pattern is likely to be more robust and successful)
For the Request Messages, we were envisioning some kind of StructureMap-ish mapping from the Request Message to the concrete plugin / service that would process the message. Again - I'm sure that this has been solved before and there's a pattern for it, or we're completely on the wrong track and there's a better solution.
Any help and ideas are greatly appreciated
Saan
PS - I would also have an IWidget in a common project with some basic properties - so the Pages Plugin could just request all classes that implement IWidget to add to a page
Your question is subject to a lot of different approaches; but I might suggest Service Oriented Architecture. Mostly because it can bend to a business in a very quick and agile manner. This architecture provides many bonuses:
Lightweight
Agile
Code Re-usability
However it does come with an array of hurdles that may need to overcome such as:
Interoperability
Security
Performance
Persistence
So implementing some of these resolutions may alleviate such an issue. However, that will require some knowledge of the matter on your part. As this Architecture is agile, but everything is exposed to a degree. Additionally what about multiple instances being instantiated?
Those are all potential items you'll have to identify.
What I would personally do, is find the true core of the business- Not the project; but the business. Then determine what approach would best accomplish that task. That will be a model that will last as the business core is at it's heart.
Some things I'd highly recommend on this matter are:
Patterns Of Enterprise Application Architecture.
Implementing Domain Driven Design.
Domain-Driven Design: Tackling Complexity In The Heart Of Software.
Service Design Patterns: Fundamental Design Solutions.
There are a lot of other viable books, but those were some I found very helpful. As they culminate a vast array of design discussions that involve:
Lazy Loading
Unit Of Work
Repository
Dependency Injection
Model Extensibility Framework
and more...
This will fill in several gaps; but I can't emphasize enough. No technology is better then one another, they all have pros and cons. But the technology that captures your business goals the best is the ideal choice.
And I understand your need for a response to help you, but remember:
Ask not the Elves for counsel, as they both say yes and no.
Simply because we don't know your project or your business, those goals are going to heavily impact your decision. Those are things that only you will know. As I stated things we don't know that you'll want to account for:
Company Objectives
Maintainability
Companies Growth Projections
Possible Shifts in the Company paradigm.
There are more, but you'll have to account for some of those variables for the applications rate of decay to stay stagnant for awhile. So the life of the application will endure for quite awhile.
Hopefully that helps, but that is my two cents.

How should data be accessed. The working practic

I am newbie C# developer. When I just have started to learn programming thins were pretty simple, you see the problem, you develop solution, test it and it works, that simple.
Then you find out the design patterns and the whole abstraction thing, and you begin to spend more time on the code that yields no results, always tiring to protect code from possible changes in future. More time less result.
Sorry for the boring introduction, but I just trying to show how frustrated I am now.
There is a bunch of data-access technologies provided by Microsoft itself, and even larger bunch of technologies provided by third-party companies.
I don’t have team leader or neighbor super skilled programmer friend, so I have to ask an advice from you.
How do you realize the data access in your real applications written in C#?
From a very overall perspective, I always hide and data access implementation details behind an interface, like this:
public interface IRepository<T> { /*...*/ }
The .NET framework offers a lot of different ways to access data, so I can understand that you are confused. However, at this time, there are only really two or three reasonable options for accessing relational databases:
NHibernate
Entity Framework
(Low-level APIs like IDataReader may still have their place in limited scenarios)
It's often difficult to see the benefit of abstraction without seeing the benefits it provides in a real world application. The best advice I can give is to read up on the SOLID principles then in writing your application try and think about ways the client may come to you and say "Now I need it to do this" which maybe a subtle change to the functionality or a major change. Think about how this would affect your code and in how many places you'd need to make those changes. Once you've made those changes how confident would you be that you haven't broken something else?
Another idea would be to download one of the sample applications. One of my particular favourites is the Data Access Platform sample provided on Codeplex. Try working through this code and see how the abstraction and pattern implementations minimise the impact on the code overall when it comes time to change.
The bottom line is it's easy to learn a programming language but understanding how to build robust solutions with it takes time. Stick with it though because when you do finally get a good understanding of software architecture it's immensely rewarding.
Some points to consider for the DAL: (note: very opinionated, but answers to this question have to be)
Encapsulate logic behind a Repository
Use interfaced-based coding
Use Dependency Injection
Use a mature ORM like NHibernate/Entity Framework 4.0 (but know when to use SPROC's for db-intensive work)
Use the Unit of Work pattern
Prevent SQL Injection attacks by using parameterized queries (or LINQ-Entites, as above)

Is there a logical progression to application development?

I am currently working on an application in WPF/C# for personal use. I am not a "classically trained" programmer. Simply a hobbyist that likes to code in his spare time. Is there any accepted approach to the progression of application development? I. E.; Make it work, add fault tolerance, create a gui, then performance optimization. Or maybe should I design the entire GUI first? Basically I am going to start a new project soon and would like to have some sort of "every program needs this" checklist.
There's really no "every program needs this" list, because there's absolutely nothing that every program needs.
Some advice, though: don't "make it work", then "add fault tolerance". Defensive programming and accounting for errors should be a continuing part of development. It's much simpler (and usually more effective) if you account for errors and unexpected input when you're writing a piece of code rather than after it's done.
As far as whether or not to make the GUI first, answer this question: is the most important aspect of the program what it does or what it looks like? That's a serious question that, honestly, can vary from application to application (though it's usually the former that's more important).
If functionality is more important, model your information in code and get some basic "business logic" (a term of art that represents the non-visual logic in the application that carries out the rules and operations that are fundamental to the purpose of the program) in place, then create a GUI that interacts well with it.
If the GUI is genuinely more important, create it first and model data objects and business logic around the GUI.
I would advise you to peruse this Wikipedia article. It's pretty heady (as most technical Wikipedia articles are), but it provides some good links and will give you a rough idea of how the progression of software development and maintenance moves in the "real world".
I'd say first of all, as simple as it sounds, write (either on paper or in your head) what the app is actually going to do. (Most businesses can't even do this part!)
Knowing that, sketch on paper what you think the screens will look like.
For example, say you're writing a home budget program and you want a drop down for accounts, and a grid for transactions, etc. Knowing what the GUI looks like will help tremendously.
Then fill in the details.
If this is something you're doing as a hobby, you can choose any development methodology you want.
Typically, for commercial development, there's some form of prototype made first (for WPF, SketchFlow with Blend is fantastic for this). This is typically required since you most often need to "sell" the concept, either to a client, management, etc.
However, if you're doing this on your own, you have the freedom to do things any way you wish. One comment, however. I would, personally, not thing of "fault tolerance" as separate from "making it work", however, since "fault tolerance" comes with testing, and unit testing as you go is much more effective...
I try and take a look at my audience for the application. Then I'll create some use cases where I try and figure out what and why my application should even be built. Sometimes evaluating what you're writing and why you stumble across a lot of ideas that might shape the way you architect the application.
From there you can do as others suggest and put more importance on areas of focus.
This is a huge topic that will probably garner a lot of opinions, so I'll chime in with this: Test-driven development. Try reading about it, and make the effort to incorporate it into your development strategy as soon as possible. TDD is the one thing I wish I had known when I started writing software years ago. It makes a world of difference in the quality of the stuff you put out.
What has worked for me in the past is the following (high level) sequence:
Understand and record the requirements (who, what and when) - use-cases, feature list, flowcharts, service level requirements - whatever works for you (I am partial to use-cases though).
Understand and record the design (how) - class diagrams, sequence diagrams, screen designs, API specifications - start high level and drill down (could start development before complete drill down)
Implement - start with API/stubs and unit tests, then fill in the code, update unit tests and execute unit tests as you go.
System test - test the components operating together and fix defects. Don't forget about performance testing (check that you have met your service level requirements from step 1).
Package, deploy and enjoy.
The development lifecycle varies a lot. Variance is due to project size, team size, timeline, etc...
For small hobby projects, I usually follow this approach:
Specs: this could be a half page typed about what I think I'm doing, and maybe some diagrams to make it more clear.
Plan: Usually a document where I outline what I think major milestones will be, such as "complete proof of concept", "basic gui", "system logging", "successful CRUD operations"
Code: Try to meet the first milestone in 2., then possibly re-evaluate 2. Continue until project is done, or I get bored / distracted by something else (usually shinier than whatever I'm working).
This last step may also involve sub-steps such as data modelling (if it's a database app) or graphics design for icons (if the GUI needs fancy icons).

How can I help junior members gain confidence in their ability to refactor code? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I wanted to see what folks thought were the best way to help junior members gain confidence in their ability to refactor code. I find that often junior developers simply follow the existing patterns and sense an aversion to break anything due to the perceived risk. I am trying to get them to look at the requirements (new and existing) and have the code map onto the domain model versus "tweaking" or "bending" the existing code base to support new functionality. Just wanted to see if there were any folks who have success here. We are currently thinking about pushing more pair programming, TDD, code reviews etc., but wanted to check if there were other success stories...
The only reliable answer will be unit tests IMHO. Not necessarily TDD -- just get them to write tests for the existing methods/classes they want to refactor, make sure they're doing what they're doing, then allow them to refactor like crazy while relying on the tests to make sure the methods are still valid.
The confidence level and flexibility unit tests allow are immensely valuable in these kinds of activities.
It seems that pair programming with a senior developer in combination with writing tests would be the optimal situation. If the more experienced developer in the pair is leading, the testing will just be part of it.
Writing tests alone leaves room for improvement. Writing tests in a pair environment is the best of both worlds and therefore should build the confidence quicker.
I recommend you to have Unit Tests before start a heavy refactoring, if you have a good code coverage, by simply running the tests you'll be able to see if some test fail, which refactoring affected the desired program behavior.
Basically Unit Testing can give you the confidence your team needs to refactor.
No matter what, you should push for "more pair programming, TDD, code reviews etc". You should also make sure that your programmers (both Junior in years and in habits) are skilled in the fundamentals.
I reccomend suggesting that they read McConnell's Code Complete and Fowler's Refactoring.
I agree - unit tests, and pair programming.
The first step would be to have them write tests for whatever they want to refactor FIRST and then refactor. I also think there is some merit in code reviews with more senior developers as well as pair programming.
My suggestion would be to take a system that will change quite a bit over time and let a junior developer give a plan of what basics they want to apply to it, e.g. are unit tests missing, what design pattern may make sense to use to add the new functionality, do you feel this is "good" code and if not, what changes would you make to it? Part of this is getting them into the code and comfortable with it as when a developer doesn't know what anything within the system does, chances are they want to make minimal changes for fear of breaking something and the subsequent negative fall out. If there can be a senior member that can act as a mentor and guide what junior developers suggest into something that better matches what is being sought, this may be the big thing to get in there.
Note that for the above that senior member may have to have a good deal of familiarity and in a way already done the planning of how to make the changes that the junior developer will do, but the idea is to get the juniors more into the code is how I'd see it. If the junior developers can get in the habit of jumping into things and be encouraged to do that, then I can see some success there. The key is to have the idea of how to correct what the junior developer suggests and yet encourage them to give more into the overall process rather than be told what to do.
Some people are more likely to stand out and take a chance, the key is for the group to see how this turns out as what you want in the end is a group of junior developers all working on various solutions where the senior developer may have originally built the system or integrated various products together and thus can give an input on what should be done but act as a guide rather than a parent in getting stuff done.
Another way to view this is to simply visualize things from the junior developer's view. If they suggest something and get something, e.g. praise or better assignments, then this may get things rolling, though one has to be careful on what is given as to keep taking things up a notch can run into problems if it grows too high.
Ask them to write or investigate existing test cases
Run the those test cases, record the result
Ask them to refactor the code
review the refactor code
Run the test cases match the previous observations
Also, try doing some coding dojo's. One pair sits and programs at the beamer, rotating one developer every five minutes. Have them talk about how they refactor, and why.
See: http://www.codingdojo.org/
I believe the question is not specific to C#, so I'll suggest giving it a try with Java using Eclipse. Eclipse has the best refactoring tools I have ever seen so far (although I never tried IntelliJ IDEA or Resharper). I have benefited a lot by learning refactoring through Eclipse, especially using the Preview window before performing any change.
I would recommend a combination books, tools, coding and mentoring.
Before anything else - get the candidate to buy or borrow Refactoring by Martin Fowler and read it.
If you have a good source control system - it should be trivial to create a separate branch to play with. Also if the end result of the exercise is useful you can easily merge it into the trunk.
Next, pick a specific task that you know would require them to comprehend the application structure. For example, ask them to instrument a part of the system. This provides a task within which to work instead of general directives (like read the framework documentation or read this code)
The next part is to ask that tests be written to support the functionality touched by this task. Review the tests and encourage writing of comprehensive tests. It is important to use a tool for this like NUnit or if your IDE supports unit testing, use that. Encourage the person to ask questions and find out why things are the way they are.
If you are using an IDE that supports it introduce the refactoring tools in the IDE and encourage them to refactor the code. Use pair programming or regular code reviews to mentor the person. The tests can be used to show how unit tests are a vital part of a good refactoring effort. Start small - may be change the names of things or extract fields into properties and then move to more complex ones.
Hopefully, by the end of the exercise, not only will the person be comfortable enough to question, tweak and change the application and you would have some useful functionality out of it as well :-)

Categories

Resources