views:

151

answers:

7

I have placed comments with my questions inline. The code supports making rest calls.

    // (1) Is appending Base to the name of base classes useful?
    public abstract class RestCallBase : IRestCall
    {
        // (2) Is there a good way to decide on the ordering/grouping of members?
        // I have seen code that uses #region for this, but I feel like it's not
        // pervasive.
        public string Url { get; set; }
        public string Method { get; set; }
        public string PostData { get; set; }
        public string ResponseText { get; set; }

        // (3) How do you feel about using the same name for type and identifier
        // in cases like this?  I go back and forth because on one hand it feels
        // cleaner than using underscore (_MyPrivateProperty) or
        // camel cased (myPrivateProperty).
        private HttpWebRequest HttpWebRequest { get; set; }

        // (4) Is it clear that the target of the lone verb comprising the method
        // name is the noun which is the name of the class?  To me, it is 
        // redundant to say 'PrepareForRestCall'.
        protected abstract void Prepare();

        public IRestCall Go()
        {
            this.Prepare();

            HttpWebRequest = (HttpWebRequest)WebRequest.Create(Url);

            // (5) Here a region is used in place of a comment, but I have not
            // seen any other code that uses regions this way.  My thinking is
            // that it brings the code one step closer to becoming a private
            // method but can stay like this until it actually needs to be called
            // from multiple points in the logic.
            #region Add post data to request if present.
            if (!string.IsNullOrEmpty(PostData))
            {
                // (6) I changed this from 'sw' to 'writer' after code review.
                // Would you have as well?
                using(StreamWriter writer = new StreamWriter(HttpWebRequest.GetRequestStream()))
                    writer.Write(PostData); // (7) Would you use curly braces for a single statement?  I opt to save two lines so I can see more code on the screen.
            }
            #endregion

            using (HttpWebResponse response = HttpWebRequest.GetResponse() as HttpWebResponse)
            {
                StreamReader reader = new StreamReader(response.GetResponseStream());
                ResponseText = reader.ReadToEnd();
            }

            return this;
        }
    }
+2  A: 

Even though no one liked all the rules associated with StyleCop, our team decided to adopt is so at least the simple things would be consistent throughout our code base.

  1. Yes.
  2. StyleCop
  3. I do it all the time (as does the .NET Framework)
  4. Agreed.
  5. I personally wouldn't use regions like that.
  6. Definitely
  7. Yes. StyleCop would enforce this.
Russell McClure
I use it for exactly that reason. It forces answers to some of these questions, but not all (ordering of the properties, for example, isn't enforced, nor would the name of the class, method descriptions, etc)
Reed Copsey
Thanks for the suggestion on style cop. I used it for a little while but stopped when I got mad that it would not let me use constructor parameter names that matched the member names as in MyConstructor(Logger logger) { this.logger = logger; }. Do you know a way to relax the rules or something? Even if you don't I think I'll go back to using it as one of the other reasons I stopped was I simply didn't know if others out there used it much... thanks again.
Gabriel
I'm not sure what error you ran into. I write code like that all the time and StyleCop has never flagged me for it. Let me know if you find out the actual StyleCop error code you were getting.
Russell McClure
+1  A: 
  1. Prefixing the class name with Abstract is also used. You could use this instead of adding Base, but you would normally use this for abstract base classes of course;

  2. Use whatever grouping/ordering is useful for your object;

  3. This is quite normal, but, for public properties/fields. For private properties, you would probably use _myPrivateProperty;

  4. Agree;

  5. I think this is very confusing. You should just use regions to group many lines of codes. You usually see this to group all properties, methods or implementations of an interface. Not on this detail level;

  6. Yes;

  7. I always use curly braces for using, while, foreach. For if statements, I tend to leave them out for single line blocks, but only when all else's also have a single line.

Pieter
@Pieter, thank you for the response. Re 1, I'm assuming prefixing with Abstract is mutually exclusive with appending Base because one implies the other. Re 3, do you ever worry the code will be mis-read by others that the call is to a static method? Re 5, thanks for the honesty, I think you're right.
Gabriel
Updated the answer. Concerning 3. why would you think this would be confused with a static method call?
Pieter
@Pieter, I think this is one of those times when I am missing something simple. The thought process: if I (a) type name and property name are the same as in 'private MyClass MyClass {get;set;} then (b) calling an instance method on MyClass would look the same as calling a static method, i.e. MyClass.TheInstanceMethod() and MyClass.TheStaticMethod().
Gabriel
By MyClass.TheInstanceMethod() would give a compile error, because it's not a static method. That's how the developer sees it's not a static method :).
Pieter
OK, I knew I was missing something (sound of self clonking self on head).. :)
Gabriel
+1  A: 

I'll try to answer these in order:

  1. Personally, I avoid this unless necessary. When using an abstract class, you're really setting up a class hierarchy where using a concrete class should be possible via the abstract class's API (see Liskov Substitution Principle for details). I feel strange typing RestCallBase instance = ... instead of just RestCall.

  2. Ordering of members is entirely up to you. Order them in a way that makes sense.

  3. There is no problem using the same name as the type identifier for a property. This is common in the BCL.

  4. Yes. This seems perfectly acceptable as a rule. However, in this case, what does "Prepare" actually do? I would be confused seeing this API as I have no idea what "Prepare" would do for a rest call.

  5. This is somewhat odd to me. If you feel that this deserves to be a private method, make it a method. Otherwise, use a comment. Using a region directive as a comment seems strange in my opinion.

  6. I would have used streamWriter, personally, as it's even more clear.

  7. This is personal preference, but I personally prefer to wrap in braces, even when it's a one liner. StyleCop will enforce their usage, BTW - as it's found to be less problematic over time.

Reed Copsey
Thanks for the observations, particularly on (4). It's hard to put yourself in someone else's shoes sometimes.
Gabriel
+2  A: 

(1) Is appending Base to the name of base classes useful?

This is a matter of personal preference. I personally can't stand it. I hate seeing code like RestCallBase instance = new SomeConcreteRestCall(); instance is a RestCall. Period.

(2) Is there a good way to decide on the ordering/grouping of members? I have seen code that uses #region for this, but I feel like it's not pervasive.

I like to see related items grouped together. I hate #region (it's just a way to hide code and it increases maintenance costs trying to keep all the #regions organized) and I consider it a code smell.

(3) How do you feel about using the same name for type and identifier in cases like this?

Love it. Please see my previous answer on this subject.

I go back and forth because on one hand it feels cleaner than using underscore (_MyPrivateProperty) or camel cased (myPrivateProperty).

I do not like the leading underscore anymore (I have to admit I use to). Now I prefix members with this; it's just clearer to me.

(4) Is it clear that the target of the lone verb comprising the method name is the noun which is the name of the class? To me, it is redundant to say PrepareForRestCall.

I could go either way on this one but would probably lean towards the shorter Prepare but if someone argued that PrepareForRestCall is clearer or asked what is Prepare preparing for, I would probably concede the point.

(5) Here a region is used in place of a comment, but I have not seen any other code that uses regions this way.

I hate regions. The way it is used here is ridiculous.

(6) I changed this from sw to writer after code review. Would you have as well?

Yes.

(7) Would you use curly braces for a single statement? I opt to save two lines so I can see more code on the screen.

Oh you better believe I would. Clearer, reduces maintenance costs.

Jason
The insights are much appreciated. Thanks for the honesty regarding my attempt at originality on using region for comments. Funny how something seems perfectly logical until you see that it only makes sense in your own mind.
Gabriel
+1  A: 

#5 - I would replace that region-as-comment with a method named AddPostDataToRequestIfPresent.

+1  A: 
Richard
I originally thought the same as this. After reading comments here it made me think more and I believe it's the idea of maintainability that counters it - i.e. if you make a decision based on the size/number of lines of the enclosing context, then you have placed a requirement on yourself to change something later if the code grows. Of course at some point anyone has to arrive at a non theory based practical coding style, for which the terse quality brings more plus than minus. This might be more accentuated if i were using multiple objects with long type names.
Gabriel
@Gabriel if the code expands significantly it is very easy to rename (your IDE will do all the work for you) so I would discount that argument.
Richard
@Richard, fine point. Maybe a good rule of thumb is to equate using 'nonsense' variable names with implied information to the future reader of the code like, 'count on the fact that these are very locally scoped and can be fully understood by the surrounding context of the code, otherwise they would have more meaningful names'
Gabriel
+1  A: 

(5) Here a region is used in place of a comment, but I have not seen any other code that uses regions this way.

I would say this is interesting. Here are my thoughts on why.

Possible pluses:

  • If the comment explains what you are doing then it is enough to just read the comment and keep the region closed. Thus helping to understand the program with minimum effort.

  • You see clearly what region the comment is referring to. Sometimes it's not as clear if you use a regular comment.

To me its like a method except its code is at the most logical place, where its used.

Possible minuses:

  • The input and output is less clear.
Skúli
Your thoughts definately echo my own. After reading the other comments here I feel like it's too against the grain to move forward with. Thanks for the response.
Gabriel