Showing posts with label Software. Show all posts
Showing posts with label Software. Show all posts

2012/08/27

Why do teams make their jobs so hard?

The more developers I meet, the more I realize that developers continue to make their own lives difficult. They simply accept that the environment they work in (technically) is all that they have. They don’t bother learning more advanced things about it, or even trying to customize it in any way. It’s even worse when an entire team chooses to just use the default environment and everybody is left on their own to do what they want to develop the product. Granted there is something to be said about just getting something out the door, but if you just open up your IDE and get coding without ever customizing it to how *you* code you’ll soon be running into headaches.

I may end up making this a series of posts so I can simply hand this out to future team members so they can understand how their life could be vastly improved. The first tool I’ll dig into is StyleCop.

If your team is doing manual code reviews (like every team does, right?) I strongly hope that the reviews don’t cover things about formatting the code or naming conventions. Make use of a tool that can enforce those rules for you automatically. This is especially important for a team of developers where everybody has different preferred programming languages. As an example, my current team consists of developers who have backgrounds in VB6, Clojure, Ruby, and Java. That alone is a plethora of patterns for how the code should be formatted. Because everybody’s background drives how they format their code going forward you can wind up with a lot of source code commits that are purely reformatting of code so the next developer can understand the code. Why waste the resources when you can have a tool tell the developer they aren’t following the rules of the team prior to even checking in?

There’s a lot of rules that some people that don’t agree with, but I’ve found good reasons for nearly every single rule that comes with StyleCop. One of the key things to do when using StyleCop is not to every change the default settings that are installed on the machine. StyleCop allows you to create a settings file for a folder (and all of its children folders) that override its parent. My general approach is that in the root of every project folder I place the Settings.StyleCop folder that should apply to every single project.

Now, in that base settings file, I typically change the following options:

  • Options –> uncheck “Cache StyleCop analysis results”. I’ve yet to hit a project that takes a long time to analyze, so there’s no point in caching results.
  • Settings File –> ensure that “Merge with settings file found in parent folders” is the selected option.
  • Rules –> C# –> Detailed Settings –> check “Analyze generate files”. This way if you’re doing some sort XAML work, any XAML generate fields will be flagged as part of the naming conventions.
  • Rules –> Documentation Rules –> Detailed Settings –> check “Ignore privates”, “Ignore internals” and uncheck “Include fields”. My main reasoning for turning off this level of documentation is that the classes should be very small and concise to adhere to the Single Responsibility Principle. If the class is so massive that you need to document your fields and all the private members, then you really should be having some lengthy conversations in your code review.
  • Rules –> Documentations Rules –> Element Documentation –> Check SA1609, SA1610, SA1628, SA1629, and SA 1630. This way you have everything documented (a) for Intellisense, and (b) so anybody can look at the (hopefully up-to-date) documentation and know what to expect when working with the item.
    • Depending on the team/project, I uncheck SA1600, SA1601, and SA1602. This way StyleCop doesn’t complain about having to document every public or protected element, but when there’s some level of documentation it must meet the criteria.
  • Rules –> Documentation Rules –> File Headers –> Uncheck SA1633, and check SA1639. I don’t believe every file needs to have documentation about the file. The rest of the documentation should describe all of that pretty clearly. But again, if there is any level of documentation in the file header it needs to conform.
  • Rules –> Readability Rules –> Regions –> Check SA1124. For the love of a higher deity, please stop using regions. If you need regions, your code is tackling too much.

That’s quite a bit to configure, but seriously makes your code at least consistent. Not only for yourself, but for your team.

Side Note: For those that use StyleCop, you’ll notice that this means that SA1101: PrefixLocalCallsWithThis. Yes, this is intentional because it does improve readability when I’m looking at the code outside of an IDE. Is the line BuildDetails.Name an instance property digging into the Name property, a static property digging in, and static class, or what? By saying this.BuildDetails.Name it is now much more obvious where I need to look for that code.

2012/08/20

Is There A Good Way To Send A Mass Email?

This is going to be more about the options that are out there rather than true technical details.  I’ve done all of these before in the past, but never really put the thought into how the receiver sees these types of emails until lately.

I’m pretty open with handing out my email when a company wants to get it on a form so they “can keep in touch.”  Since GMail is my primary client, it’s capabilities let me deal with the bulk of the incoming junk messages pretty efficiently without a lot of hassle.  Also their spam protection has been pretty top notch from what I (haven’t) seen.  All that being said, the general filtering capabilities of it are the same as any other client: when messages arrive, perform specific tasks on them.  Common filters that people tend to have include “Sent only to me”, “I’m in the TO:”, “I’m in the CC:”, “Sent from somebody/some domain”, “Does it have an attachment”, etc.  When it comes to sending mass emails there’s a few different options and each has an impact on how the receiver’s email client deals with it.

All email addresses in the TO:/CC: field

Most people (and especially companies) shy away from sending a mass email with everybody in the TO: or CC: field these days*.  Why?  What if I’m a rival company to you and I put my email address on your mailing list.  Now you send me an email, along with the rest of your huge list.  I can now look over that entire list of email addresses and add them to my own mailing list and start soliciting to them.  Or taking that list and selling it off to other companies that will spam you.  Granted any company that uses this practice is most likely winding up in a spam folder anyways, but it does mean others now have your email address when you didn’t intend for them to get it.

As a business this is the worst way to mass email your clients.  Yes, the recipient’s email client can process the message based on it’s rules with no problem, but they may have a rule similar to “If I’m not the only recipient, make the message as low priority and move it to this folder I only read during a blue moon on the fifth Tuesday of the month.” 

* Although I’m sure we still have that parent/sibling/grandparent/friend/third-cousin-twice-removed that still sends those absolutely funny photos.  Just as annoying, but not the types of mass emails I’m talking about.

All email addresses in the BCC: field

Well, if we don’t want one recipient to see everybody, let’s just put the entire list in the BCC field since that isn’t sent to the recipients.  Problem solved, right? I suppose from the business’s point of view, it does take care of the concern about people stealing the list of recipients.  But it raises a couple more issues.  First, if you don’t have anybody in the TO: field, a lot of spam filters will deem the email much more likely to be spam.  There’s a number of other criteria that will determine if it is flagged as spam, but not having one email address in the TO: field doesn’t help.  The other issue is that it essentially gives a big middle finger to the recipient if they make use of rules to filter the deluge of emails.  Not having their email address show up in any of the normal fields means that the recipient needs to filter on the other criteria like who sent it.  Why is this an issue? Here’s an example:

Running my own business and domain I am going to receive a ton of email that I actually want to receive (current client emails, newsletters, convention information, partner programs, etc.), but I’ll also receive emails that I should be aware of but didn’t necessarily think about.  Things like emails to the ‘webmaster’ or ‘admin’ of my site are sent to my inbox because of a catch-all email account.  To quickly spot these types of emails it’s nice to be able to have a filter that has rules along the lines of “If <my email address> does not appear in the TO: or CC: field, flag the email for manual investigation”.  Since no email address shows up in the email this filter now catches all those BCC’d emails and flags them even though it’s a regular, legitimate email.

Or another example:  One of the trainers I communicate with at my gym regularly sends out newsletter-like emails, but about 1/5th of the time he also sends out emails directly to me.  The problem is that he tends to use BCC in both cases.  When trying to prioritize my inbox, I would like to quickly skip the newsletters but actually know what’s going on with the other emails.  Since the BCC hides any indication if I was the only recipient or part of a mass mailing trying to create a filter is neigh impossible.  That leaves wasting the time to look at each email.  Granted I know the business value I’m getting by keeping in contact with him so I tolerate it, but for most businesses I look at it as a sign of the business not really putting any thought into how their customers perceive them.

Mail merge each address individually.

This option seems to have the best of both worlds, but it presents a different issue.  When you perform a mail merge, you’re sending out nearly identical emails to lots of people.  There’s a number of spam filters that will start flagging these emails as spam because a large number of extremely similar emails are coming through in such a short amount of time.  Larger companies that send out newsletters and such have realized this and send out batches.  You may have likely noticed this if you subscribe to coupon or deal based newsletters that generally arrive in your inbox at the same time every day, but vary by a few hours.

The other issue with performing mail merges is that normal consumer tools (using Microsoft Word and Outlook) are very limited in the customization of the mail merge.  For example, the subject line cannot be merged.  You also cannot attach files as part of the merge.  To have better dynamic content (say optional paragraphs), they have to be part of the merge data rather than flags controlling whether to add them or not. Once the merge is completed it sends out every email at the same time rather than batching them automatically.

Sure there are some open source projects out there for advanced mail merges, but it takes that extra effort to get that type of functionality.  Most people will only need these tools once or twice, and thus never think about using them regularly.  If the usual tools had some of these features built in the experience would be much better for both the sender and the recipient.

Which option to go with?

So which method should people go with? It really depends on what you’re looking to achieve.  As an end user, I want to see my address in either the TO: or CC: field somewhere.  If I’m BCC’d on an email, I’m likely going to mark it as spam and not even bother reading it. The Mail Merge option would allow for a single individual to appear in one of those fields, but of course it has the limitations I mentioned above.

I know I tend to be an extreme power user for some things, but what other gripes do people have when it comes to handling and filtering email?

2010/01/18

The Problem of Developers and the English Language

This is more of a rant on development rather than useful code, but hopefully it helps provoke some thought.  And while I may be targeting the English language in this post, I believe the other languages run into this issue just as much.

The very first post I made on this blog was a quote from the book "1984" about a pared down language because (a) it surprised me that everybody focuses on the Big Brother aspect of the story rather than the redefined communication, (b) an explicit language where each word can only mean one thing makes a lot of sense, and (c) having words that are meant to be a scale (good, better, best) actually having the same initial word in them (good, plusgood, doubleplusgood) is more in line with the Latin roots of the English language.  Think back to when you were first starting to understand all the oddities that make up the English language.  I before E except after C. To pluralize a word, add an S; except if it ends in these letters, then do this instead.  There’s a lot of rules to the language that don’t make  a lot of sense.  Although I’m pretty sure Ph.D. bearing learned people can give me the reasoning, the general answer to why it must be done this way is “Because that’s how it’s always been done”.  Outstanding.  Way to think outside the box.

When you're gathering requirements for a problem, how often do the developers interpret a different meaning than what the end users actually meant?  Like referring to the "home page" of a site as the first page a logged in user sees versus the first page that every user sees.  When the manager is talking about the project, are they talking about the entirety of building the software, the Microsoft Project file, the Visual Studio project file, or some other meaning to them entirely.  It gets even worse when a word is used that has a completely different meaning in another language (which at least one project has run into).  Assuming you're programming only in the English language, you have somewhere in the range of 475,000 to 600,000 words to work with.  Not only that, but more words are added to the collegiate dictionaries every year.  And then there are words that are commonly used that don't even exist in a standard dictionary.  So why must we overload the same words over and over again?  Stop being lazy and calling every application that serves out data or hosts another application a "service".  Give it a unique name.

Microsoft’s been getting taking flack about overly descriptive (but entirely accurate) developer product names.  Sure it’s easier to simply say “Astoria”, “Geneva”, or “Longhorn”, but unless you’ve heard of them before you have no clue what they’re actually for.  Now hearing “ADO.NET Data Services”, “Claims-based Identity Management”, or “Windows Vista”, you actually have some idea what’s being talked about without having to spend a lot of time digging into what the product actually is (albeit, not a much better idea in the case of Geneva…).  Sure we need to account for being able to talk about things abstractly in some cases, but we should be able to categorize whatever we’re talking about in a similar way that biologists categorize plants and animals.  IIS is a type of web server, which is a type of server, which is a type of computer, etc. StructureMap is a type of IoC containter, which is a .NET piece of software, which is a development tool.  Although there’s a lot of overlap when describing software, it seems like there could be an easier way to describe and categorize specific software.

If you really think about it, each and every word only exists because a group of people have agreed on a general meaning for it.  Words like "blog" and "podcast" were created to sum up new trends in technology that had not been defined at the time.  All it takes is for somebody to come up with a word and others to start using it for it to catch on.  In much the same way Scott Hanselman wants to have a word that says “I’m a technical person and know what I’m talking about”, I’m think I’ll start using Newspeak terminology to better describe parts of the software I write. 

2009/05/01

Updating the Last Modified Date of a directory

Working with a lot of compressed (.ZIP) folders can have some interesting side effects when you decompress them.  Windows will list all the folders (and subfolders) as having a last modified date of when you decompressed the file.  That may be well and good for most people, but it annoyed me to no end because I typically sort directories by the Last Modified Date as I work with the most recent files the most often.  Plus, downloading a file that hasn't been updated in a couple years and unzipping it can cause some confusion when you see the folder as being last modified today, but every file in it was created/modified a few years ago.  Why not have the folder actually reflect the date it was last modified by the files, not the OS?  That makes better sense to me, so I created a dead simple console app to do just that.

The console application will recursively go down a directory structure and give you a status of the folders and the Last Modified Date's new value.  By default, it will go down a maximum of 300 folders.  That should more than cover most directory trees.  If you want to limit it to only a couple levels, you can call the application from the command line, passing in a number after the folder and it will recourse only that many levels.

image

One thing you'll notice in the output (more so if you run it in a console window rather than from the context menu that's part of the installer) is that the path names are rarely wider than the screen.  There's a few different ways to accomplish this task, and since I'm not a fan of depending on system libraries in managed code, I took the approach of implementing the function myself based on code I found online.  I can't recall where I originally came across it, but I modified a couple logic errors that were in it.  Take a look at the DirectoryUpdater.CompactFilePath() method if you're interested.

I also built a Windows Installer Xml (WiX) installer because it's so much easier to just right-click on a folder and tell it to update the last modified date.  So as a custom action in the installer it creates the appropriate registry keys for the context action.  As I'm still extremely new to WiX, the only way to have it install them is to choose a Custom install and change the "Context Menu" item to "Will be installed on local hard drive".  Hopefully will get that figured out at some point.

image

image

Source code download from here.
Executable download from here.
MSI Installer download from here.