Question regarding the "Tell, don't Ask" idea - c#

There is this famous quote that says
Procedural code gets information then
makes decisions. Object-oriented code
tells objects to do things. — Alec
Sharp
The subject of the post is precisely about that.
Let's assume we are developing a game in which we have a Game where there is a Board.
When facing the problem of deciding which methods are we going to implement on the Board class, I always think of two different ways:
The first approach is to
populate the Board class with getSize(), getPieceAt(x, y), setPieceAt(x, y, piece). This will seem reasonable and is what is generally found in libraries/frameworks. The Board class has a set of internal features that wants to share and has a set of methods that will allow the client of the class to control the class as he wishes. The client is supposed to ask for the things he needs and to decide what to do. If he wants to set all board pieces to black, he will "manually" iterate over them to accomplish that goal.
The second approach is about
looking for Board's dependent classes, and see what they are "telling" it to do. ClassA wants to count how many pieces are red, so I'd implement a calculateNumberOfRedPieces(). ClassB intends to clear all the pieces on the Board(set all of them to NullPiece, for example), so I'd add a clearBoard() method to the Board class. This approach is less general, but allows for a lot more flexibility on other aspects. If I "hide" Board behind an IBoard interface, and decide that I'd want to have a board with infinite size, doing in the first way, I'd be stuck, as I'd have to iterate over an infinite number of items! On the other hand, in this way, I could do fine (I could, for instance, assume all pieces are null other than the ones contained in a hashtable!).
So...
I am aware that if I intend to make a library, I am probably stuck with the first approach, as it is way more general. On the other hand, I'd like to know which approach to follow when I am in total control of the system that'll make use of the Board class -- when I am the one who is going to also design all the classes that'll make use of the Board. Currently, and in the future (won't the second approach raise problems if later I decide to add new classes that are dependent on the Board with different "desires"?).

The quote is really warning you away from data structures that don't do anything with the data they hold. So your Board class in the first approach might be able to be done away with and replaced by a generic collection.
Regardless, the Single Responsibility Principle still applies, so you need to treat the second approach with caution.
What I would do is invoke YAGNI (you aren't gonna need it) and try to see how far I could go using a generic collection rather than a Board class. If you find that later you do need the Board class its responsibility will likely be much more clear by then.

Let me offer the contrarian point of view. I think the second approach has legs. I agree with the single responsibility principle, but it seems to me that there's a defensible single mission/concern for a Board class: Maintaining the playing field.
I can imagine a very reasonable set of methods such as getSize(), getPiece(x,y), setPiece(x, y, color), removePiece(x, y), movePiece(x1,y1,x2,y2), clear(), countPieces(color), listPiecePositions(color), read(filename), write(filename), etc. that have a congent and clear shared mission. The handling of those board-management concerns in an abstracted way would allow other classes to implement game logic more cleanly, and for either Board or Game to be more readily extended in the future.
YAGNI is all well and good, but my understanding is that it urges you to not start building beautiful edifices with the hope that one day they'll be usefully occupied. For example, I wouldn't spend any time working toward the future possibility of an infinite playing surface, a 3D playing surface, or a playing surface that can be embedded onto a sphere. If I wanted to take YAGNI very seriously, I wouldn't write even straightforward Board methods until they were needed.
But that doesn't mean I would discard Board as a conceptual organization or possible class. And it certainly doesn't mean that I wouldn't put any thought at all into how to separate concerns in my program. At least YAGNI in my world doesn't require you start with the lowest-level data structures, little or nothing by way of encapsulation, and a completely procedural approach.
I disagree with the notion that the first approach is more general (in any useful way), or what appears to the the consensus that one should "just see how far you can get without abstracting anything." Honestly, that sounds like how we solved eight queens. In 1983. In Pascal.
YAGNI is a great guiding principle that helps avoid a lot of second system effect and similar bottoms-up, we-can-do-it-so-we-should mistakes. But YAGNI that's crossed the Agile Practice Stupidity Threshold is not a virtue.

CurtainDog is right, invoke Yagni and figure out what you actually need right now, implement that, then make sure it's not going to prevent any features that may be desirable in the future.
The second approach violates the principle that superclasses should not know about each of its subclasses. I think the element you're missing is that the base class can define template methods, like getBoardSize, countRedPieces, countBlackPieces, that can be overridden by subclasses and your superclass has code that uses those template methods, therefore telling its subclasses what to do, but not how to do it.

Related

Static - Good or Bad?

Alright, so I've been trying to figure out this for far too long now.
I've read countless articles/questions on static, and also singletons.
This is how I have been using static for quite some time:
I have a GameManager.cs, which has TileMap.cs & Player.cs. TileMap.cs needs to access the player's camera, for updating the position of the map:
GameManager.cs:
public static TileMap map;
public static Player player;
Update code, draw, etc. below...
There will only be one of each of these.
TileMap.cs:
Vector2 mapPosition = new Vector2(GameManager.Player.position.X, GameManager.Player.position.Y);
Is this acceptable? What downsides are there to this?
Edit: Seeing as though this question is too broad, let me see if I can be more specific.
Is there a better way to do this rather than through static methods? I have multiple lists of classes inside TileMap.cs, some of which have Lists inside of them (thinking mostly of my particle engine), so would Update(Player player) be more efficient, or would it not really matter?
P.S, I have noticed when the player moves the game map sort of "jitters" (lags for a small fraction of a second). Could this be causing it?
Thanks,
Shyy
As you are asking about downsides:
1) does the code that uses static variables involved in muti threading ?
If yes, you may consider locking management. Which easily makes apparently easy code complicated.
2) Are Player, position and others structures ? If so, every time accessing them via property, you create a copy of instances and not access to the references directly. Considering that code provided some 2D engine, and you are creating a Vector, so probably some rendering pipeline code, this may introduce some serious performance implications.
I've noticed similar questions quite often professionally. So let me give you a straight answer, of which I am well aware that it doens't apply to the general case. See it as an opinion of what I consider 'best practice for beginners'.
static is often used for making variables available across class boundaries, as-if they are singletons. The singleton pattern here is just a design pattern wrapper (which doesn't solve most of the problems). While this might make programs easier to write, using static can also make programs much more complex if you want to make your application multi-threaded.
In general I therefore think it's a good idea to avoid using static alltogether and simply pass objects around.
There is one exception, that is: if you need to have data that is accessible across thread boundaries. If this is the case, you'll quickly find yourself in a world of hurt, and it is best to learn as much as you can about locking and use that for all static variables (including their members if they are structures/classes!).
If that isn't good enough as well, you can continue on that path and learn about things like interlocked and memory barriers (but I wouldn't recommend that if you don't need it).
Fortunately, most applications are fast enough to work in a single thread. I imagine your application to be no exception (and you can probably use a standard game framework to do the multi-threaded part of the application -- PS: if so, be careful with class variables as well, since they might be passed across thread boundaries as well).
As for your lag: I think you should use a good profiler to find performance hotspots; it's probably unrelated to the use of static.

I'm getting Confused over Classes

I bet this is the dumbest question anyone could ever ask but I can't seem to wrap my head around this topic. I understand a Class is used to create an object (when you instantiate it) but what is confusing me is, "When do you know if it is viable to create a Class in a program?".
Say hypothetically your creating a program that gathers an input from the user (be it a name, a number or any other details), use those details to do some calculations and then storing all of it locally. Its basic but would you need to use a class to make the program smoother/faster or more maintainable?
Am I confusing myself?
EDIT: I am mostly using programs like Visual Studio and NetBeans IDE.
As you say a class is a construct that allows you to describe a type, which has properties methods and events on it.
In simple situations you can easily get away with not using classes, but in larger, more complex projects having a properly thought out object model makes things so much easier. Easier to maintain, extend, reuse, read.
It may feel like more work at the time (and in most cases it probably is), but it is definitely not wasted effort if you're creating something that will need to be supported.
In Java you don't have a choice: you can't write code that's outside of a class.
A class is a template for instances. It encapsulates state and behavior together into a single software component. You write programs by creating instances of classes that interact together to accomplish your goals.
would you need to use a class to make the program smoother/faster or
more maintainable?
I can't speak for C#, but in Java you don't have a choice. You either create a single class that does all that in a main class or you break it up into several classes that handle different parts of the problem (e.g. I/O, calculations, persistence, etc.) You have to have one or more classes.
You write classes and create objects from them because they map well to the kind of problems that you want to solve. They're either real objects that model physical things in the world (e.g. Person, Car, Bank, etc.) or reifications of ideas (e.g. PersonFactory, Account, etc.) You choose to write object-oriented code because objects model the problem you'd like to solve well.
Some problems lend themselves to functional programming. There are more than one way to write programs to solve problems.
here is a very simple / easy to understand Tutorial that will help you in learning / understanding C# especially Classes also look at Structs as well
C# Class Tutorial
Classes are primarily for us humans to help us organize code. They don't necessarily make software run faster on a computer. When I first learned about classes, I found it helpful to model "real-world" objects. For example, if I wanted to write a program that calculates the area and perimeter of geometrical shapes, I would create a simple Shape class which defines the abstract methods which do the calculations. Then I extend this class to create different kinds of shapes, say Circle, Square, and Triangle. By starting with simple applications of classes and through more programming experience, I have been able to gradually see other places to use classes.
For a simple program, like your example, to gather input from the user (name, number, comment), you can easily do this without creating a new class, excluding the fact that languages like C# and Java require a static class to put your main function inside. If you used a non-object oriented language like C, you could easily do it without a class.
For a simple class like you describe, in fact, it might seem like a little extra work to have to create the class (although it is probably negligible). However, that is only because you are referring to a small set of data.
The point where it gets useful to create classes is when you have many pieces of data. The class acts as a way to group that data together, and possibly store it locally as one. You can also add other related methods onto each class that are directly related to the class members.
When you app becomes more complex, say you need to keep track of customers, products, billing information (Credit Card, PayPal, ...), addresses (ship to, and billing), is when classes become extremely valuable in keeping each bit of information together as well as relating each of those larger "bundles" (classes) of information to each other.
You could have a customer who has an order who has a bill to and a shipping address. Each of these classes, itself has many fields inside of it. But you can relate the larger concept of customer to a target shipping address a lot easier with classes.
As far as "When do you know if it is viable to create a Class in a program?", the answer is not always easy, but any time you see data fields which naturally fit together (well, like an address, or a product description or billing information). I wish I had a more concrete answer, but it really depends on what you are building, and what type of data you are working with.
And no, it's not the dumbest question anyone could ever ask! I hope this helps your understanding.
1. When do you know if it is viable to create a Class in a program?
I think just about everyone who answers this question will have a slightly different response, but typically, you should use Classes to modularize your program's functionality. In your example, you said that your program might take input from the user, use input to perform some calculations, and persist the user data and calculation results somewhere. You could have the following three classes:
UserInput - handles keyboard input and converting it into some easier-to-process format
Calculator - processes all input after it has been converted
DataPersistence - handles reading/writing from/to disk, or database, or whatever you need.
This way, all of your code isn't just piled up inside a massive Java/C# main() call, you can focus on the smaller parts independently of each other. The interaction between these components is what determines your program's behavior.
2. Its basic but would you need to use a class to make the program smoother/faster or more maintainable?
Classes may actually end up adding overhead to your program because of how objects are referenced in languages like Java or C#, but they make your code much easier to read and modify than if your program was written inside one gigantic function. This is sort of analogous to dividing up math textbooks into chapters. If Algebra, Calculus, and Differential Equations were all condensed into a single chapter of the text book, then the text book wouldn't be very useful to those who want to skip ahead to the Calculus part. The overhead of adding chapter headings is negligible because it allows the author/reader to focus on certain portions of the book.
Likewise, Classes help you divide up your work so it's easier to maintain later. Speed/Performance are generally not affected by how you divide your program into classes, provided you do it intelligently - this is where the real artistry of Object Oriented Design manifests itself :)

How/When to write reusable methods in OOP

I often find myself in a situation where i am repeating two,three lines of code in a method multiple times and then think whether i should put that in a separate method to avoid code duplication. But then when i move those lines out of the method i find that the method just created is not reusable, was used only one time or requires an overload to be useful for another method.
My Question is what sort of patterns should we be looking for that indicate we should create a new method. I appreciate your response.
Don't put too much functionality in one method/class. Try to follow the single responsibility principle. It'll take some time getting familiar with that approach. But once you reach that level, you'll notice that it's done all by itself. Before coding, try to ask yourself, what functional units your concept includes.
For example, you want to develop an application, that can index the content of pdf files. It's just fictional, but at first sight, I could identify at least three components:
PdfParser - this provides you with the content of a pdf
Indexer - gets input from parser and counts meaningful words
Repository - it's for persistence; this could be made generic; so just say repository.Get<IndexData>(filename) or something
You should also try to code against interfaces. Especially when some kind of UI is involved. For example, you are developing a chat client with WinForms. If you follow the MVC/MVVM-pattern, you can easily (i.e., easier than coding against a Form object) use your original logic with a WPF version of the client.
I would start by reading about the DRY principle (Don't Repeat Yourself) hopefully it will give you a good answer for your question, which is a question that all developers should be asking themselves by the way, great question!!
See Don't repeat yourself
I wanted to leave it at DRY because it is such a simple but powerful concept that will need some reading and a lot of practice to get good add. But let me try to answer directly to your question (IMHO),
If you can't give your method a name that reflects exactly what your method is doing, break it into pieces that have meaning.
You'll find yourself DRYing up your code with ease, reusable pieces will show up, and you probably will never find yourself repeating code.
I would do this even if it meant having methods with only couple of lines of code.
Following this practice will give meaning to your code, make it readable and predictable, and definitely more reusable
If the lines of code that you intend to move to another method perform a specific set of actions (like read a file, calculate a value, etc.) then it is best to refactor into another helper method. Again, do this only if the helper method is being called at several places in your code or if your caller method is too long (definition of too long depends on the developer).
Similar questions
How do programmers practice code reuse
What techniques do you use to maximise code reuse?
Code Reusability: Is it worth it?
Coding Priorities: Performance, Maintainability, Reusability?
As a general rule, always think of those situations as functional entities. If a piece of code functionally performs a task (complex string conversion, parsing, etc), you should write reusable method.
If that function is specific to a certain type, then write an extension method.
You could create a local variable inside your function of type Action<> or Func<> and assign the code snippet to it. Then you can use it everywhere inside your function without polluting your class with too many little helper functions.
If you build a method for reusability, but don't use it in more than one place, then the reusability of you method isn't really verified.
Extract methods when it makes sense, and redesign those methods for reusability when you actually have the opportunity to reuse code.

Internal and protected in a private api

I work in development team of about 12 and we build a reasonable set of API's that we use on a strictly in-house only basis. Typically all classes and interfaces are public because that is just how they get done. I have often considered the value of making some of the constructors internal so that the consumers of the API (albeit internal) have to use the factory or some other reason that I can't think of now.
Is this something that you and your team practice?
How does this effect your unit tests? Do you find that it is okay to unit test a class through it's factory or do you access the constructor through something like PrivateObject?
The answer is yes; my current project has exactly one developer working on it - me - and yet I still use visibility and other access modifiers, along with more complex design patterns, as necessary. Here's why:
The compiler, if you let it, can be one of your greatest tools to enforce good design patterns. Making everything public can cause a lot of headaches down the road, when you have to maintain an object whose normal state during program execution is the object-oriented equivalent of a human living his life on an operating table with his chest cracked open and everyone who knows him from his children to his electric company poking around in his vital organs to get him to do what they want. Adding another hand, or removing one, can cause the patient to go into cardiac arrest.
Code should be self-documenting. A class or class member that is marked as internal means it probably should be; if everything's public, you don't know if there's anything you shouldn't touch when interfacing with the object. Again, you've got your patient sitting on the operating table, and all of a sudden a new guy comes in, grabs the liver and goes "hey, what does this do?". Objects should have their hands shaken, be told to do something and let go to do it, and the function of their liver is of no concern to anyone but them.
Code should be maintainable by your posterity. This ties back to the first two rules, but basically, someone should be able to open up your codebase, find the entrance point and trace through basic execution flow, all the while looking at objects utilized along the way and determining their general form and function. Back to our patient on the operating table, let's say five years from now someone walks in on this scene; a guy split open on a table with 50 guys in his guts. It's not going to look like any polite social custom he's ever seen; it'll probably look most like a ritual human sacrifice, and most people's first instinct when encountering such a situation is to run.
However, the flip side of the coin is that a design pattern implemented for its own sake is generally a Very Bad Thing. Once you graduate college and get your first job, nobody really cares that you know how to implement a Strategy pattern, and you shouldn't do so at the first opportunity just to say you did. Every pattern has a set of circumstances in which it applies. If you were a doctor, would you perform an angioplasty on the next patient who walked in just to say you were able to do it?

In C# (or any language) what is/are your favourite way of removing repetition?

I've just coded a 700 line class. Awful. I hang my head in shame. It's as opposite to DRY as a British summer.
It's full of cut and paste with minor tweaks here and there. This makes it's a prime candidate for refactoring. Before I embark on this, I'd thought I'd ask when you have lots of repetition, what are the first refactoring opportunities you look for?
For the record, mine are probably using:
Generic classes and methods
Method overloading/chaining.
What are yours?
I like to start refactoring when I need to, rather than the first opportunity that I get. You might say this is somewhat of an agile approach to refactoring. When do I feel I need to? Usually when I feel that the ugly parts of my codes are starting to spread. I think ugliness is okay as long as they are contained, but the moment when they start having the urge to spread, that's when you need to take care of business.
The techniques you use for refactoring should start with the simplest. I would strongly recommand Martin Fowler's book. Combining common code into functions, removing unneeded variables, and other simple techniques gets you a lot of mileage. For list operations, I prefer using functional programming idioms. That is to say, I use internal iterators, map, filter and reduce(in python speak, there are corresponding things in ruby, lisp and haskell) whenever I can, this makes code a lot shorter and more self-contained.
#region
I made a 1,000 line class only one line with it!
In all seriousness, the best way to avoid repetition is the things covered in your list, as well as fully utilizing polymorphism, examine your class and discover what would best be done in a base class, and how different components of it can be broken away a subclasses.
Sometimes by the time you "complete functionality" using copy and paste code, you've come to a point that it is maimed and mangled enough that any attempt at refactoring will actually take much, much longer than refactoring it at the point where it was obvious.
In my personal experience my favorite "way of removing repetition" has been the "Extract Method" functionality of Resharper (although this is also available in vanilla Visual Studio).
Many times I would see repeated code (some legacy app I'm maintaining) not as whole methods but in chunks within completely separate methods. That gives a perfect opportunity to turn those chunks into methods.
Monster classes also tend to reveal that they contain more than one functionality. That in turn becomes an opportunity to separate each distinct functionality into its own (hopefully smaller) class.
I have to reiterate that doing all of these is not a pleasurable experience at all (for me), so I really would rather do it right while it's a small ball of mud, rather than let the big ball of mud roll and then try to fix that.
First of all, I would recommend refactoring much sooner than when you are done with the first version of the class. Anytime you see duplication, eliminate it ASAP. This may take a little longer initially, but I think the results end up being a lot cleaner, and it helps you rethink your code as you go to ensure you are doing things right.
As for my favorite way of removing duplication.... Closures, especially in my favorite language (Ruby). They tend to be a really concise way of taking 2 pieces of code and merging the similarities. Of course (like any "best practice" or tip), this can not be blindly done... I just find them really fun to use when I can use them.
One of the things I do, is try to make small and simple methods that I can see on a single page in my editor (visual studio).
I've learnt from experience that making code simple makes it easier for the compiler to optimise it. The larger the method, the harder the compiler has to work!
I've also recently seen a problem where large methods have caused a memory leak. Basically I had a loop very much like the following:
while (true)
{
var smallObject = WaitForSomethingToTurnUp();
var largeObject = DoSomethingWithSmallObject();
}
I was finding that my application was keeping a large amount of data in memory because even though 'largeObject' wasn't in scope until smallObject returned something, the garbage collector could still see it.
I easily solved this by moving the 'DoSomethingWithSmallObject()' and other associated code to another method.
Also, if you make small methods, your reuse within a class will become significantly higher. I generally try to make sure that none of my methods look like any others!
Hope this helps.
Nick
"cut and paste with minor tweaks here and there" is the kind of code repetition I usually solve with an entirely non-exotic approach- Take the similar chunk of code, extract it out to a seperate method. The little bit that is different in every instance of that block of code, change that to a parameter.
There's also some easy techniques for removing repetitive-looking if/else if and switch blocks, courtesy of Scott Hanselman:
http://www.hanselman.com/blog/CategoryView.aspx?category=Source+Code&page=2
I might go something like this:
Create custom (private) types for data structures and put all the related logic in there. Dictionary<string, List<int>> etc.
Make inner functions or properties that guarantee behaviour. If you’re continually checking conditions from a publically accessible property then create an private getter method with all of the checking baked in.
Split methods apart that have too much going on. If you can’t put something succinct into the or give it a good name, then start breaking the function apart until the code is (even if these “child” functions aren’t used anywhere else).
If all else fails, slap a [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] on it and comment why.

Categories