Ok, this is probably highly subjective but here it comes:
Let's assume I'm writing a method that will take a printscreen of some region of the screen. Which method signature would you prefer and why?
Bitmap DoPrintScreen(int x, int y, int width, int height);
Bitmap DoPrintScreen(Rectangle rect);
Bitmap DoPrintScreen(Point point, Size size);
Other
Why?
I keep seeing myself repeatedly implementing both 1) and 2) (redirecting one of them to the other) but I end up usually just using one of them, so there really is no point in having both. I can't decide which would be better. Maybe I should use the signature that looks the most with the method I'll be calling to make the printscreen?
It depends. If this is a library for general use, by all means add all three. The .NET framework, especially GDI+, is full of examples of this. If the conversion is trivial, it's not much effort, and your users will be thankful.
If it's just an internal class, I'd go for the option that is easiest to use from the call site. For example, if the caller already has a Rectangle available, the Rectangle overload is better. If there are multiple call sites with different preferences, it's probably better to add multiple overloads as well.
Rectangle best describes the behavior of the function (at least I hope it does!) The X & Y associate with width & height so as to define a rectangle; they are not arbitrary unrelated variables.
I would go with 2)
Bitmap DoPrintScreen(Rectangle rect);
As mark said the parameters can be swapped in the following:
Bitmap DoPrintScreen(int x, int y, int width, int height);
I wouldn't choose this as it is not as explicit as 2) to someone else reading it. Whereas there is no ambiguity to someone read 2)
Bitmap DoPrintScreen(Point point, Size size);
Of course that's just my opinion of course!!!
If you only end up calling one of these overloads, then there's really no point in having the other two sitting around. There's nothing I hate more than having to sift through 27 overloads of some method, hoping that a) I find the right one for my purposes, and b) the person who wrote this mess actually ran and tested the overload I'm using even once.
In the specific case of a screen-capture method, the overload with the Rectangle parameter would probably be the most handy, since forms always have a rectangle associated with them. Also, if you need to grab the same screen area repeatedly, it's easier to save one variable (a Rectangle) than four (x, y, width and height).
The best one is
Bitmap DoPrintScreen(Rectangle screenArea);
If you think about the method parameters as being part of a "concept", in this case the concept of a screen area, then the other options don't abstract that concept nicely enough.
Also, use a good name for the parameter, because it might make calling code even more clear by the use of named parameters in C# 4.0.
I would personally include the three of them, letting the user choose which one she/he prefers to use, all to offer the most freedom of use possible to the user. No one likes to be handcuffed. Well, not in programming! ;)
Rectangle is probably the most clear because the argument does not depend on the position. It would be easy for a user to accidentally swap x and y or width and height.
Point/Size is also better than x-y-width-height, and sometimes the extra explicitness can be a little more clear to read.
But ultimately, there's no good reason to not use all three overloads.
I think you should select the version that maps best to the other methods that would be used in conjunction with your code. I am referring to .Net methods and methods from other standard or common 3-rd party libraries. In that way the code looks uniform and the same objects can be passed to other methods directly.
I would provide all 3 if it would be convenient for the consumer. After all, your actual implementation will (or should) only exist in one place. All of the other overloaded methods will simply extract the appropriate parameters and pass them to the local method with the actual code.
...so it's a convenience for your users with little to no effort on your part. Win/Win.
Both - 1 and 2.
And also one without params for full-screen =)
Some times you have separated x,y,width, height,
some times you already have rectangle.
Varian 3 - IMHO is very rare =)
But user always can convert values to rectangle, or break apart rectangle to values)
I think this is philosophical question.
So make them all or pick random one )))
All 3. Like you said, you're going to redirect them to 2 any who so, why not keep all three? I do think you should change the Rectangle parameter name to something more meaningful - like printArea.
cheers.
Related
I have a StatBarView class that holds a Stat, an int named percentage and two Colors. In the Update() method I smoothly change around the percentage value of the bar, how full it has to be. Next up I have four Draw() methods, one for drawing the bar small, one for medium, one for large, and one for drawing it as text instead of graphically.
It works, but.. I feel like this will become a mess if I want to implement more drawing cases.
I could turn the 'text view' into it's own StatTextView, but that only moves the problem elsewhere. I also want to avoid having to pass along all kinds of parameters to the draw method, it would make me run all over the place if I want to change the sizes of a few things. I'd also like to avoid some massive method using switch statements, that feels even worse.
I considered passing along an IStatBarContext that has a Draw(int percentage), which would work, but feels very complicated.
Would I have to call Stat.Draw(spriteBatch, position, new StatBarLarge()) on every iteration of Draw()? That's a load of useless new objects per second. Besides, new StatBarString() would make no use of that percentage stat. I think I went wrong with my design somewhere.
That said, I don't know how to actually -do- make this code cleaner. Would someone help me out?
It sounds like your last example/choice is spot on. It even has a name, the Strategy pattern.
In the class based version of this pattern, you would normally just pass in a new object every time (as in your example) but because this is in the Draw method, I would just have a sample of each strategy stored in your class and pass the existing reference.
Another way to implement this pattern is by using delegates. To do so you would have the Draw method take a delegate with the information you need. Something like:
public void Draw(SpriteBatch spriteBatch, Vector3 position, Action<int> drawStrategy)
{
...
drawStrategy(percentage);
}
You would then pass the function for large, small, text, etc. to this function. Action<int> was just an example of course, you can have it return values or take additional parameters as needed.
If the text-version doesn't use percentage, that is a code-smell, but you may not need to worry about it to much. Strategy is definitely the way to go here.
I have a class that wraps around a Bitmap and I would like to have a way of knowing if the bitmap has been changed (via SetPixel or GDI+).
I don't need to know exactly when it happens, I just need a way to tell if it has happened since the last check.
Now, I'm assuming that something like that isn't already packed in the Bitmap class, so what would be the best way to solve this problem?
I could provide my own wrapper functions for GetPixel and SetPixel, but then I'd have no idea if the Bitmap was changed using GDI. I COULD make a wrapper for that too but that really seems like a huge overkill.
Another possible option would be to save a copy and then check pixel by pixel. This would obviously work and would be trivial to write but it's much too slow for my needs.
You should use a hash or check sum. There are some easy ways to do this but I think the simplest way would be to have a string hash property in your class then call GetHashCode() on the bitmap/binary string/whatever container you're storing it in. Set it to the classes property, check the current hashcode against that value to see if anything has changed. You could also write your own little checksum function or choose from (I'm sure) a vast array of third party options.
Background:
I am having a discussion with a friend regarding the correct way to refer to elements within a 2D array for something I'm designing. I was unhappy with using XNA's Point and Vector2 structs as array references because the properties of them are labelled X and Y.
I created my structs for these, ArrayPoint and ArrayVector2 and called my own properties I and J. My friend thinks this is a massive waste of time, however, I do not like swapping the X and Y references because my maths background has always taught me to use i and j for matrices, e.g using myArray[i, j] instead of myArray[y, x].
What is the best way to deal with this situation?
Is it simply a case of swapping x and y? Or creating your own structs to deal with it how you like? Is it all down to personal preference since this is pretty much all arbitrary anyway?
Listen to your friend!
There are so many reasons this is a bad idea, here are a few:
Your maths background may say i and j. But for arrays that map into 2D space (eg: a tile map, as opposed to a matrix) then x and y are actually preferable as they convey semantic meaning that makes your code easier to understand. (ie: you have X and Y axes, not I and J).
(Usually the cases where i and j make more semantic sense, you won't be storing the indexers in a struct anyway - they'll just be temporary locals.)
Without a genuine reason, less code is always preferable to more code. Writing and testing code takes up valuable time. Using someone else's code (like the built-in XNA types) saves you time.
One day you might write some utility function that takes a Point. If you have two versions of Point then you could well end up with two versions of that function. More code and, worse still: duplicate code!
"Not Invented Here" is a really, really, really bad habit to get into as a programmer. Learn to live with other people's code (as long as it works - which, in this case, it does).
No one else does this. Your code is going to confuse and annoy everyone who tries to work with it.
Small performance hit needlessly copying things around. (Plus a few other esoteric things that will have a minor affect on performance.)
(Also: indexing into an array with a Vector2 (floating point) is kinda weird.)
It's not down to personal preference because you're going to have to convert to/from your structs to pass data to XNA library methods. You'll incur a conversion cost which will is admittedly very small, but could add up to being pretty significant if done repeatedly in a loop.
Sure, it's silly that SpriteFont.MeasureString() returns a data structure consisting of X and Y members instead of Width and Height, but it's easier to deal with the oddity than try to fight it.
My advice would be to try getting along with using x and y as indices and avoid the additional overhead.
I think that what you are doing is fine. The only time I would advise against it is if you are adding significant complexity. As yo know, XNA software and others that have to handle many calculations and graphics can really get bogged down by slight changes if they are inefficient. However, what you are doing is only aiding you and shouldn't add said complexity. I'd say go for it.
I have a method for pulling data from a database, and I want it to get this:
Limit of Five entries,
Item type is Newsletter,
Needs to be active (PublishDate < DateTime.Now)
So I'm thinking of naming it GetFiveActiveNewslettersByCreatedDate()
This seems a little long to me. I looked on the site for a good way to name things like this, how would you handle it?
How about something like this instead?
public IEnumerable<Newsletter> GetActiveNewsletters(int maxRecords = 5)
{
// ...
}
Top 5 is still the default, but it's not overly specific anymore.
The reason I would avoid baking "five" into the name, personally, is what it might mean down the line.
For example, what if later, there were some demand for 10 newsletters in certain scenarios instead of 5? Well, you'd create an additional method GetTenActiveNewslettersByCreatedDate(). And now, you have a 'design pattern' that subsequent developers will follow when 20, 50, 100 newsletters are needed. This is a design that will rot, and you can stave it off now by parameterizing the five.
Of course, this might be YAGNI/speculative generality. If 5 really is some kind of magic, hard-fast, will never change rule, then you might cautiously bake it in. I just find that I've regretted doing and seeing things like that far, far more often than not.
I would recommend renaming it to: GetNewsletters(int recordCount=5)
The number of newsletters would be a parameter for the method.
The rest could be assumed and described in the ///Summary.
To avoid this specific naming I would think about making the method generic. Something like:
GetNewsLetters(int amount, bool onlyActive, SortOrder orderBy)
Name it so that it is evident to any developer what the method does. Self commenting code is king. If your method name gets too long, you're probably doing too many different things inside of it and would be a candidate for refactoring.
As for your specific example, I don't have a problem with the name you've given.
I would add parametrized method, like
GerEntries(T typeofEntity, DateTime date, int maxNumber)
And naturaly document method with comments
For quick tasks where I only use an instantiated object once, I am aware that I can do the following:
int FooBarResult = (new Foo()).Bar();
I say this is perfectly acceptable with non-disposable objects and more readable than the alternative:
Foo MyOnceUsedFoo = new Foo();
int FooBarResult = MyOnceUsedFoo.Bar();
Which do you use, and why?
Would you ever use this type of anonymous instantiation in a production app?
Preference: with parenthesis "(new Foo()).Bar();" or without "new Foo().Bar();"?
(Edited to abstract question away from Random class)
Side note regarding random numbers: In fact, no, your specific example (new Random().Next(0,100)) is completely unacceptable. The generated random numbers will be far from uniform.
Other than that, in general, there is not much difference between the two. The compiler will most probably generate the exact same code in either case. You should go with the most readable case (long statements might harm readability; more code will do it too, so you have to make the trade-off in your specific case).
By the way, if you chose to go with the single line case, omit the unnecessary parens (new MyObject().Method() will do).
You might want to consider the implications of using the code in the debugger. The second case will allow you to inspect the object you've created, whereas the first won't. Granted you can always back out to the second case when you're attempting to debug the code.
I've done it both ways and don't really have a preference. I prefer whatever looks more readable, which is highly dependent on the complexity of the class and method being called.
BTW -- you might want to pick a different example. I fear that your point might get lost in discussions over the best way to generate random numbers.
If you are only using the object once, the first way is better all the time.
It is shorter and clearer, because it makes it explicit that you will not use the object later.
It will probably compile to the same CIL anyway, so there's no advantage to the second form.
First statement. It's more readable, has less code and doesn't leave temps around.
The second one is debugging friendly, while the first one isn't. The second wins only because of this.
In fact the first way, creating a temporary, is more readable for two reasons:
1) it's more concise
There's less code to read, there's no unnecessary local variable introduced, and no potential name clash with another local, or shadowing of any variable with the same name in an enclosing scope
2) it communicates something that the second form doesn't, that the object is being used temporarily.
Reading it, I know that that instance is never going to be used again, so in my "mental compiler" that I use to understand the code I'm reading, I don't have to keep a reference to it any more than the code keeps a reference to it.
As Mehrdad notes, though, doing it with a Random class isn't a good idea.
As he also notes, the redundant parentheses make it less concise; unless you're in a dusty corner of a language, assume that competent programmers know the language's operator precedence. In this case, even if I don't know the operator precedence, the alternative parse (calling new on a function's return) is nonsensical, so the "obvious" reading is the correct reading.
int RandomIndex = (new Random()).Next(0,100);
int RandomIndex = new Random().Next(0,100);