I've got an ASP.NET web application, that is essentially our intranet site. I made a lot of progress on the administration office's employee management pages. It ties into an SQL server database, and I'm using a three layered design (Objects, Logic, DataAccess). It was all reviewed and all of it was accepted, except! for the part that manages vacations and vacation histories.
My question, before I go into details is, how does one efficiently "untangle" code that is no longer necessary?
For example: previously I was treating each VacationDay as it's own entity with it's own history. Such that I could track the history of an individual day. To help in tracking, I have an enum called VacationDayAction, which includes options such as .Submitted, .RequestDenied, .CancellationRequested, and so on. This was in an attempt to provide meticulous detail for each day. It was then determined that we no longer need that. We do, however, still need VacationDays and all the basic functions of that (saving days, getting days, etc.), but now we no longer need any of the "history" related classes.
My problem is, when I right click a class that I no longer need in VS and go to "Show All References," I get a ton of results scattered across several pages. I need to get rid of all of them, without breaking the rest of the application. Is there not some kind of "smart" technique or method for easily untangling parts that are no longer necessary? This is particularly difficult because 90% of what I did was just fine, and needs to stay like it is. Yet scattered in that 90% is 10% of stuff that is no longer needed. I can't just go storming through with the delete key either, because with the removal of each reference, I need to be sure that any dependencies on that reference are also fixed in a way that they don't call stuff that isn't there anymore. And I still need the application is a compilable state, so that I can test along the way that the rest of the application didn't fall apart as a result of some deletion.
To give you an idea of my low level of experience, I started two years ago with having never used C#, ASP.Net, or Visual Studio. It blew my mind when, way after starting and as I was learning, someone taught me that I could use breakpoints. And then it really really blew my mind when I learned about multi-layered design. I'm wondering if there is not some technique or trick or feature that can help in scenarios like this, where you have to "untangle" and throw away unnecessary stuff.
This is not a simple question. In fact, I would say this is one of the major challenges for any systems developer; how to handle and get rid of old code which is not in use. There is lots of literature on this, and few really excellent answers. A good book may be "Working effectively with legacy code" by Michael Feathers, which deals with many related problems. It is no light read though, and will probably take some time to get through, but it will likely help you become a better coder, and better at these kinds of tasks in particular.
Maybe you can have a look at the Resharper tool? ( http://www.jetbrains.com/resharper/ ) It is a productivity tool which among other things shows "dead" code (unused code) in grey, and lets you remove it. It will also help you remove unused references from each class (again, they will be grayed out and let you remove them automatically).
Drawing diagrams where each major piece of code /component is a box with a line linking it to any related component might help you get a better overview; try to draw a hierarchy showing how different parts of the code are related and dependent.
The bottom line as far as I know, is that you just have to muddle through it, commenting out code a little at a time, then recompiling and testing it. If it still works, fine, now you can remove the commented out code completely. This would be easier if you had unit-tests covering your code, but I take it as a given that you don't, as is unfortunately often the case.
Related
I'm working with a product development firm having multiple releases simultaneously for same product.
We have around 4 environments with their own copy of SQL database and TFS branches.
Now the problem is we spend lot of time on merging code, resolving conflicts and merging within various branches to make sure we do not mess with deployment.
We are taking help of Redgate tool(new for this) for sql db side management but still feel like we are not in good condition.
Can you please suggest me best architecture/solution or set of tools that can be implemented ?
If you are concerned about the number of merging related activities that are going on then we need to reduce the number of merging activities. This is not going to be an easy thing to change as the culture and expectation within your organisation is currently tuned to produce this result.
You need to move towards a single line, or single branching model. If you are using Git then you can still use many short lived activity branches for Hotfixes or Releases as laid down in GitFlow, but your source line where you add all new code (DEV, MASTER, TRUNK, Main, whatever) should be a single line. As soon as you have feature or version branches you are in the world of merging.
There are a number of engineering activities and practices that you can use to support much of what you are physically doing now in the new model:
Feature toggles - This is your primary engineering solution for merging. If you are working on a single code line, and always have coders check in working code, then feature toggles allow you to ship features that are half done and you don't want folks to see. You hide them.... Now the first thing that you are going to throw out is "but we do database work and you can't do that there", and you would be wrong. Many organisations practice feature toggles and include database work. You need to have a solid and consistent practice of 'additive only' so that you don't break existing work and actually do work to make sure that both a new feature and an old one can coexist. There is work in that, but not as much as merging (in my experience) and not as error or bug prone. One key to remember is to think of them as Feature toggle and not code toggles. If you add a new feature then hide it till its ready. If you are incrementally improving an existing feature then just ship the new functionality. Achieving this WILL be hard and will require courage to implement major cultural changes at your organisation from coders and testers, all the way up to sales and management.
Definition of Done - Which leads to the question of how do we maintain quality in this new world of feature toggles? Think about this: if you have 3 feature teams all working on different functionality and one team decided to reduce their quality but what they have is buggy but good enough, what would be the impact? You are protected from this in a branching model until then end when you make all sorts of compromises to make everyone's mediocre (or just plane crap) code work together. Now we have to have this on every check-in and every release. So what do you need? You need a shared and agreed Definition of Done that represents the quality bar that must be met to ship. Without it you will have chaos. The cultural issue here is that you need everyone, every coder, and every tester, on board with the sacrosanct nature of the DOD. No you cant just compromise just this once as it will have a knock on effect.
Reduce cycle time - Which leads to our ship cycle. You need to 'ship' more regularly. Or more specifically you need to create potentially shippable increments of working software on a regular basis. This support the above in a number of ways, but first and foremost it reduces the amount of work that is under way. This will help reduce the complexity and help teams focus. With what is in effect shorter batch sizes we can get a much more regular adherence to the definition of done and have those touch points of "working software with no further work required to ship it". The side advantages here is that you increase your business ability to change as they can change at the end of each cycle sure in the knowledge that unfinished features are not going to in fact introduce complexity. You also gain the ability to inspect and adapt more frequently. Most companies, on gathering the evidence, find that more than 60% of their software is used little if ever. Lets use the reduced cycle time to get users in front of the software and only focus on building the 40% that they care about. (whoa! did we just get a 60% efficiency gain there?)
There are a number of other supporting practices that it would make a lot of sense for you to adopt to get there and I would probably recommend that you read the Scrum Guide (http://www.scrumguides.org/) and think about how you might start moving towards the goals above.
Currently, the developers of my team format their source code (C++, C+, stored in MS's TFS 2012) manually. We are now considering to use Visual Studio's auto formatting option (probably with Uncrustify as the pretty print engine). The idea would be to make sure that nobody has any outgoing changes, and then to format the whole code base and to commit the result. From then on, we would integrate automatic formatting into our workflow.
However, our fear is that we will afterwards not be able to easily find out who has done the last changes on a particular line of code using Source Control/Annotate (that information is often quite useful, e.g. for asking the according developer about that code).
So here are my two questions:
a) Does anybody have experience with introducing auto-formatting into a team's workflow (given an already existing and quite large code base)? Are there any best practices for this?
b) In particular: Is there any way to format our complete code base without loosing the history information? I could e.g. imagine a tool which would keep track of where each line has gone after formatting, and to adjust TFS's history such that that information is preserved. However, I haven't found anything like that by now.
Annotation will indeed be 'screwed up' by pretty-printing the whole project. There are no tools that I know of that can work around that.
A way to get the least amount of history issues is to have each developer prettify a method when he is making changes to it to add functionality or solve a bug, this will take time to propagate the whole code base, but it's the only way I know of.
I just had a conversation with my manager relating to checkin\out policies on a project I'm currently working on. Basically I tried to edit a file that was already checked out by another developer and I couldn't - I asked my manager why we couldn't edit the same class at the same time and he gave this reason for turning that functionality off: We had a lot of problems with developers editing the same Form (or anything visual done in the designer) and then cheking it in. Merging the changes in the designer generated code was a lot of hassle...
As I'm writing this I'm struggling to see what problem they were having - surely they were getting the latest code before trying to check something in??
Have any of you come across problems with editing the same Form (or something in the designer) as another developer and then checking into TFS? If so how did your team get around the problem? Did you also turn off the ability for developers to work on the same class?
EDIT: The following post (found here) is exactly the problem my manager was describing. Anyone know of a simpler way to resolve the issue than the ones in that post?
I would argue that the solution to your problem would be to establish best practices for source code modification.
Discourage people from going into UI code and arbitrarily jiggling the components around in the designer. Any reasonable UI modifications should be easily mergeable. Your best bet is to try and educate people as to the best way to merge in any given source control system. Also, as helpful as the designer is, ignorance of what code is being automatically generated in the background will be significantly detrimental in the long-term.
People who insist on locking checked-out files for the reasons you stated in your post typically wait long periods of time to check their code in. Naturally, the more time passes, the more code gets modified, so it makes merging difficult for these people. Checking in early, often, and incrementally requires people to think about their changes in stages, and for some coders, this is a rather painful cultural/psychological adjustment.
I've just checked back through the histories of some of my .designer.cs files and I can't see any changes that would cause a merge problems. There were no wholesale rearrangements of code for example.
Another thing to consider is to make sure that everyone does a "get latest" at regular intervals then any individual merge/resolution isn't going to be that great thus minimising the chances of anything going wrong.
It might also be worth investigating a 3rd party merge tool. There are plenty around.
Now it could be that the changes I've done are simple compared to the ones you've got so you should take my anecdotal data with a pinch of salt.
It can cause problems (in general) when a lot of people are editing UI concurrently. The merge logic will do a fine job merging things, but in a lot of cases the UI is drawn according to how things are added to the form. Your UI can get messed up quickly.
I don't know if I would use this as an excuse to enforce exclusive checkouts across the board, though. I might go from a (non programmatic) policy standpoint that says shared checkout for business logic, but exclusive for UI changes.
I would couple that with a strong MVP, MVC, or MVVM approach, though, which should limit the number of people that have to touch the UI concurrently.
As others have alluded to, keep one of the seminal rules of SCM in mind: merge early and often, and your problems are reduced. (along with that is "always get latest before you start working on the code).
If it is possible to auto-format code before and after a source control commit, checkout, diff, etc. does a company really need a standard code style?
It feels like standard coding style debates that have been raging since programming began like "put the bracket on the following line" or "properly indent your (" are no longer essential.
I realize in languages where white space matters the diff will have to consider it but for languages where the style is a personal preference is there really a need to worry about it anymore?
Auto-format can really only address whitespace.
It wont address developers giving variables bizarre nonsensical names.
It won't address some developers having functions return null on an error vs throwing an exception.
I'm sure others can think of more examples.
This is what we do at my work:
We all use Eclipse. We don't have a policy for using Eclipse but somehow none of us is an IDEA/IntelliJ guy. We also think our code should be written with legacy in mind. This means our code has to be readable in a certain way even years after (#1) no matter who wrote it and if that person even is in the company anymore.
Eclipse has couple handy features, automatic format on save and a specific Formatter tool. As you can see from the linked screenshot, it can be configured with XML. Thus there's a bunch of premade XML:s available for every worker in our company so that when a new guy comes in, we walk him through of the whole process and configure their Eclipse for them (yes, it's slightly evil thing to do) so that it actually uses those formatting XML:s we have provided. We do not enforce automatic format on save, we don't want to be completely intrusive, we just want to push all our developers into the right directions. For even increased compatability, we mostly use rules defined in JCC.
Next comes the important part, the actual builds. We are those who embrace automatic builds and for that we use Hudson Continuous Integration Server. There's two important parts in our configurations beyond this:
We use CVS loginfo to trigger builds whenever something is committed.
We utilize several plugins available for Hudson, including Continuous Integration Game in conjuction with the most important one, Checkstyle.
The Checkstyle Plugin is the magician in our code style enforcement guide line:
After commiting code to CVS, Hudson build is triggered
After build has been completed succesfully (all unit tests pass etc.), Checkstyle inspects the actual source files
Checkstyle ranks the code based rules we have defined for it
Continuous Integration Game sees the result of Checkstyle and awards/takes away points for the person who has the ownership for the relevant part of the code
Leaderboard shows total points for every commiter in system
Basically this means that when anyone commits ugly code into our CVS, our build server automatically reduces that person's points.
This means that eventually any one of us can be ranked on the Leaderboard based on the general code quality in both look and OO principles such as Law of Demeter, Cyclomatic complexity etc. etc. Naturally this isn't a completely serious statistic, but it's a good indication you're doing something wrong when causing a build to be initiated in our CI won't reduce your points - most of our commits are worth between 1 and 5 points.
And is it working? Sort of, I don't think anyone of us at my work writes ugly or unmaintainable code and personally I love to hunt all kinds of scores so it's definitely motivating me to make code that looks nice and follows all the OO paradigms I know of.
And do we as a company really need it? I think we do as you should see from reading this entire answer, it can be considered a good practice for the advancements it brings.
#1: in a related note, I refactored legacy code from 2002 today which used those standards, didn't look "bad" at all even in its original form and certainly not worse in its new form
No, not really.
If you can actually get it to work consistently and not make it flag code has changed due to a different style of laying the code out.
However, this is just a small part of coding standards. It won't cover multiple return statements, the use or not of ternary operators, etc.
It is always nice if the coding style that the shop uses is the same one that is also followed by the development tools.
Otherwise, if there is a large body of code that already follows a shop standard which is NOT the same as that of the tools you have two choices:
Modify all of the code to follow the tool standard, or
Maintain the existing shop standard.
Many shops do the latter. Regardless, there does need to be some kind of standard, and it does need to be followed.
Some development tools allow you to tweak their standard. In some cases you may be able to bring the tools in alignment with the shop standard.
It probably doesn't matter that much anymore if you can ensure that everybody in the team sees the source code "correctly" formatted, whatever they think it is. However I've not seen a system that can do that - you can do parts of it (say, reformat before and after checkin/checkout) but these days you also have to consider web interfaces into the version control, external code review systems that interact directly with the version control system etc.
The main purpose of a standard code style is (IMHO) to ensure that you can read other team members' code easily without having to start reverse engineering it because all the code is written using the same sort of guiding principles. Indenting and parentheses placement seem to be a major hangup on this but they are only a very small and in my opinion, somewhat overblown and not very important part of the need to make code consistent.
Unfortunately I'm not aware of any tools that can automatically apply consistent coding principles to source code...
Yes, coding styles are needed if there is a desire to have a homogeneous code base. Such a code base can be useful in preventing individual ownership of parts of the code base, which can cause problems when people leave the team. If you can't imagine having wildly different styles and problems understanding all of it, just look at all the different ways English text can be organized in various communications, all written but quite different such as tweets, e-mail, text messages, IM, message board posts, etc. and changes in fonts, capitalization, decorations, etc.
I am having a problem with one of my team members output. He seems to be always 'busy' yet I am unable to see exactly what code he has done and he seems be delivering very little and it seems to take a long time to do so. I'd like to investigate further using TFS and was wondering if there is any functionality in TFS that shows what has been written by an individual or similar?
Just to clarify I am NOT spying I am trying to resolve situation. This is only a starting point. I un derstand that quantity of code does not equate to best programmer
thanks for any answers
Your best programmer may in fact write less code than your worst programmer, in fact really good programmers often write less code. Be careful about using this information to evaluate performance. Since you are using TFS, I assume you are also using the work item tracking. That is really a better way to evaluate performance than using lines of code. See which checkins cause the most problems, which fix the most defects, and how many rounds it takes for something to be truly fixed.
For me the simplest thing is to set up email alerts for checkins. You get the checkin comment, some work item info assuming they are associating/resolving on checkin, and list of changed files, as they happen. Lets you see what part of the code that dev is in and after a while you get a sense when "it's quiet. Too quiet" because someone isn't checking in. It doesn't take the place of forensics of what he did all month, but it keeps me feeling connected. It also gives me intuitive feelings like "he's in the reports, so I'll be able to show those to the user earlier in the cycle" or "jeez, he's doing all the stupid typos in error messages and other no-thinking things, and not tackling his real hard stuff" or even "he's doing his pri 2 stuff while he has a large pile of pri 1". All of these enable a 30 second hallway conversation to deliver a course correction as close in time to the problem as possible.
See the following blog post I put together a while ago:
Getting Started with the TFS Data Warehouse
This one talks you through getting code churn for each area of your codebase, but it would be easy to add team members into that as well to get a breakdown by team member who did the check-in.
But I agree with your question - this is not a good way to check on the productivity of your colleague. Instead I would talk with them to raise your concerns.
While I am away from TFS right now, you can view a list of checkins by user in Team Explorer, and in each of these you can see the files which have been changed and look at the diffs for each.
You can get this from the TFS Cube, if you have it set up. There are a large number of dimensions within Code Churn. Some of this is also available in the TfsWarehouse database as well.
If you do have the cube set up, just point Excel at it and have some fun playing around. Keep in mind, though, that the numbers can point you in the wrong direction. Use discretion.