Like many people, I've wanted to really learn smalltalk and TDD. For fun, I've been going through the excellent Tetris TDD tutorial at: https://github.com/orfjackal/tdd-tetris-tutorial/blob/tutorial/README.md
and converting the code to Smalltalk.
I've gotten to the third set of tests (https://github.com/orfjackal/tdd-tetris-tutorial/blob/tutorial/src/test/java/tetris/RotatingTetrominoesTest.java) which wants the objects representing the pieces to be immutable.
I'm not sure how to do this. Every attempt I make breaks the earlier tests. I did create a TetrisTetrominoe class as a subclass of TetrisPiece.
Using Pharo 3.0.
Thanks.
You have to take into account the dramatic difference between languages. Some time ago I've wrote a blog post with thoughts about immutability.
I think that if you want to follow test's for another language, you should try to find some for python or ruby, because they are also dynamic languages.
If you want to maintain immutability, I suggest you going the functional way, where each method that has intent to modify object creates a new one, with required properties. I doubt that this will satisfy java tests as java is not functional as much as it's not dynamic.
In smalltalk you would normally test for immutability by asking the mutators for their senders and then verifying that only the class method that creates the instances refers to it. So for instance:
testOnlyOneMutatorOfPrivateColor
self assert:
(SystemNavigation default allSendersOf: #privateColor:) size = 1
I've occasionally found myself in situations where I have to type out redundant code... where only one variable or two will change in each block of code. Usually I'll copy and paste this block and make the necessary changes on each block of code... but is there a better way to handle this?
Heavy use of cut and paste usually means there's something not quite right in the design of the code. Think about how you could refactor such as breaking out the cut/paste functionality into commonly called methods.
Yes. There is always a better way to do it than copy-and-paste. You should always get a little uneasy (kind of like you feel when you're about to give a speech in front of a huge crowd) when you're about to hit "Ctrl-V."
In almost any introductory class you're likely to be using a language that has functions, methods, or sub procedures. (What they're called and what they do depends on the language in question). Any variable that changes needs to be a parameter to that function/method/subprocedure.
When you do that (and the method/function/sub is accessible) you can replace the HUGE chunks of code with a single call to your new m-f-s.
There are a lot of other ways to do this, but when you're just getting started this is probably the way to go.
you have a lot of approaches to this situation. I don't know if you're working with OO or structured programming but you can build methods or functions and give them cohesion and unique responsibilities. I think it's an easy way of thinking...
In the OO paradigm we use some therms on how to avoid this situation: cohesion and low decoupling (you could search for them over the Internet). If you can apply both of them in your code, it will be easier to read and maintain.
That's all
I have inherited an existing code base where the "features" are as follows:
huge monolithic classes with
(literally) 100's of member variables
and methods that go one for pages
(er. screens)
public and private methods with a large number of arguments.
I am trying to clean up and refactor the code, to leave it a little better
than how I found it. So my questions
is worth it (or do you) refactor methods with 10 or so arguments so that they are more readable ?
are there best practices on how long methods should be ? How long do you usually keep them?
are monolithic classes bad ?
is worth it (or do you) refactor methods with 10 or so arguments so that they are more readable ?
Yes, it is worth it. It is typically more important to refactor methods that are not "reasonable" than ones that already are nice, short, and have a small argument list.
Typically, if you have many arguments, it's because a method does too much - most likely, it should be a class of it's own, not a method.
That being said, in those cases when many parameters are required, it's best to encapsulate the parameters into a single class (ie: SpecificAlgorithmOptions), and pass one instance of that class. This way, you can provide clean defaults, and its very obvious which methods are essential vs. optional (based on what is required to construct the options class).
are there best practices on how long methods should be ? How long do you usually keep them?
A method should be as short as possible. It should have one purpose, and be used for one task, whenver possible. If it's possible to split it into separate methods, where each as a real, qualitative "task", then do so when refactoring.
are monolithic classes bad ?
Yes.
if the code is working and there is no need to touch it, i wouldn't refactor. i only refactor very problematic cases if i anyway have to touch them (either for extending them for functionality or bug-fixing). I favor the pragmatic way: Only (in 95%) touch, what you change.
Some first thoughts on your specific problem (though in detail it is difficult without knowing the code):
start to group instance variables, these groups will then be target to do 'extract class'
when having grouped these variables you hopefully can group some methods, which also be moved when doing 'extract class'
often there are many methods which aren't using any fields. make them static (they most likely are helper methods, which can be extracted to helper-classes.
in case non-related instance fields are mixed in many methods, do loads of 'extract method'
use automatic refactoring tools as much as possible, because you most likely have no tests in place and automation is more safe.
Regarding your other concrete questions.
is worth it (or do you) refactor methods with 10 or so arguments so that they are more readable?
definetely. 10 parameters are too many to grasp for us humans. most likely the method is doing too much.
are there best practices on how long methods should be ? How long do you usually keep them?
it depends... on preferences. i stated some things on this thread (though the question was PHP). still i would apply these numbers/metrics to any language.
are monolithic classes bad ?
it depends, what you mean with monolithic. if you mean many instance variables, endless methods, a lot of if/else complexity, yes.
also have a look at a real gem (to me a must have for every developer): working effectively with legacy code
Assuming the code is functioning I would suggest you think about these questions first:
is the code well documented?
do you understand the code?
how often are new features being added?
how often are bugs reported and fixed?
how difficult is it to modify and fix the code?
what is the expected life of the code?
how many versions of the compiler are you behind (if at all)?
is the OS it runs on expected to change during its lifetime?
If the system will be replaced in five years, is documented well, will undergo few changes, and bugs are easy to fix - leave it alone regardless of the size of the classes and the number of parameters. If you are determined to refactor make a list of your refactoring proposals in the order of maximum benefit with minimum changes and attack it incrementally.
I'm thinking of writing a CLI Monopoly game in Ruby. This would be the first large project I've done in Ruby. Most of my experience in programming has been with functional programming languages like Clojure and Haskell and such. I understand Object Orientation pretty well, but I have no experience with designing object oriented programs.
Now, here's the deal.
In Monopoly, there are lots of spaces spread around the board. Most spaces are properties, and others do other things.
Would it be smart to have a class for each of the spaces? I was thinking of having a Space class that all other spaces inherit from, and having a Property class that inherits from Space, and then having a class for every property that inherits from Property. This would mean a lot of classes, which leads me to believe that this is an awful way to do what I'm trying to do.
What I also intended to do, was use the 'inherited' hook method to keep track of all the properties, so that I could search them and remove them from the unbought list when needed.
This sort of problem seems to arise in a lot of programs, so my question is: Is there a better way to do this, and am I missing something very crucial to Object Oriented design?
I'm sorry if this is a stupid question, I'm just clueless when it comes to OOPD.
Thanks.
You're on the right track, but you've gone too far, which is a common beginner's mistake with OOP. Every property should not be a separate class; they should all be instances of the Property class. I'd do classes with attributes along these lines:
Space
Name
Which pieces are on it
Which space is next (and maybe previous?)
Any special actions which take place when landing on it
Property (extends Space)
Who owns it
How many houses/hotels are on it
Property value
Property monopoly group
Rent rates
Whether it is mortgaged
So, for example, Boardwalk would be an object of type Property, with specific values that apply to it, such as belonging to the dark blue monopoly group.
Classes for spaces is probably not a bad idea; but let's see why that's the case.
If you were writing this in a procedural language, where would the majority of the 'if' and 'switch' statements be? They'd be in determining what happened to each player when they landed on a space. In OO, we want to prevent as many if/switch statements as possible, and replace them with polymorphism. So, clearly, if we create many derivatives of Space, we will prevent a large number of if/switch statements.
But before we make that leap, let's look at the metaphor of the game. The game is all about a city. Addresses, streets, utilities, public works, jails, etc. Each square on the board represents some kind of location in the city. Indeed the players travel through the city paying rent (or some other action) anywhere they happen to land.
So let's call the spaces, CityBlocks. Each CityBlock has an address, like "Boardwalk" or "Electric Company", or "Community Chest". Are there different types of CityBlock objects? Or should we simply consider CityBlocks to be locations that have a certain kind of ZoningOrdinance?
I kind of like that. |CityBlock|---->|ZoningOrdinance|
Now we could have several different derivatives of ZoningOrdinance. This is the "Strategy" Pattern. I rather like the flexibility this give us, and the separation of 'where' and 'what' that it provides.
You'll also need a Game class that understand the rules of dice, tokens, FreeParking, Passing Go, etc. That class will manipulate the players, and invoke the methods on CityBlock. CityBlock will invoke methods on ZoningOrdinance.
Anyway, that's one way...
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
For those of you in the Visual Studio environment, how do you feel about wrapping any of your code in #regions? (or if any other IDE has something similar...)
9 out of 10 times, code folding means that you have failed to use the SoC principle for what its worth.
I more or less feel the same thing about partial classes. If you have a piece of code you think is too big you need to chop it up in manageable (and reusable) parts, not hide or split it up.It will bite you the next time someone needs to change it, and cannot see the logic hidden in a 250 line monster of a method.
Whenever you can, pull some code out of the main class, and into a helper or factory class.
foreach (var item in Items)
{
//.. 100 lines of validation and data logic..
}
is not as readable as
foreach (var item in Items)
{
if (ValidatorClass.Validate(item))
RepositoryClass.Update(item);
}
My $0.02 anyways.
This was talked about on Coding Horror.
My personal belief is that is that they are useful, but like anything in excess can be too much.
I use it to order my code blocks into:
Enumerations
Declarations
Constructors
Methods
Event Handlers
Properties
Sometimes you might find yourself working on a team where #regions are encouraged or required. If you're like me and you can't stand messing around with folded code you can turn off outlining for C#:
Options -> Text Editor -> C# -> Advanced Tab
Uncheck "Enter outlining mode when files open"
I use #Region to hide ugly and useless automatically generated code, which really belongs in the automatically generated part of the partial class. But, when working with old projects or upgraded projects, you don't always have that luxury.
As for other types of folding, I fold Functions all the time. If you name the function well, you will never have to look inside unless you're testing something or (re-)writing it.
While I understand the problem that Jeff, et. al. have with regions, what I don't understand is why hitting CTRL+M,CTRL+L to expand all regions in a file is so difficult to deal with.
I use Textmate (Mac only) which has Code folding and I find it really useful for folding functions, I know what my "getGet" function does, I don't need it taking up 10 lines of oh so valuable screen space.
I never use it to hide a for loop, if statement or similar unless showing the code to someone else where I will hide code they have seen to avoid showing the same code twice.
I prefer partial classes as opposed to regions.
Extensive use of regions by others also give me the impression that someone, somewhere, is violating the Single Responsibility Principle and is trying to do too many things with one object.
#Tom
Partial classes are provided so that you can separate tool auto-generated code from any customisations you may need to make after the code gen has done its bit. This means your code stays intact after you re-run the codegen and doesn't get overwritten. This is a good thing.
I'm not a fan of partial classes - I try to develop my classes such that each class has a very clear, single issue for which it's responsible. To that end, I don't believe that something with a clear responsibility should be split across multiple files. That's why I don't like partial classes.
With that said, I'm on the fence about regions. For the most part, I don't use them; however, I work with code every day that includes regions - some people go really heavy on them (folding up private methods into a region and then each method folded into its own region), and some people go light on them (folding up enums, folding up attributes, etc). My general rule of thumb, as of now, is that I only put code in regions if (a) the data is likely to remain static or will not be touched very often (like enums), or (b) if there are methods that are implemented out of necessity because of subclassing or abstract method implementation, but, again, won't be touched very often.
Regions must never be used inside methods. They may be used to group methods but this must be handled with extreme caution so that the reader of the code does not go insane. There is no point in folding methods by their modifiers. But sometimes folding may increase readability. For e.g. grouping some methods that you use for working around some issues when using an external library and you won't want to visit too often may be helpful. But the coder must always seek for solutions like wrapping the library with appropriate classes in this particular example. When all else fails, use folding for improving readibility.
This is just one of those silly discussions that lead to nowhere. If you like regions, use them. If you don't, configure your editor to turn them off. There, everybody is happy.
I generally find that when dealing with code like Events in C# where there's about 10 lines of code that are actually just part of an event declaration (the EventArgs class the delegate declaration and the event declaration) Putting a region around them and then folding them out of the way makes it a little more readable.
Region folding would be fine if I didn't have to manually maintain region groupings based on features of my code that are intrinsic to the language. For example, the compiler already knows it's a constructor. The IDE's code model already knows it's a constructor. But if I want to see a view of the code where the constructors are grouped together, for some reason I have to restate the fact that these things are constructors, by physically placing them together and then putting a group around them. The same goes for any other way of slicing up a class/struct/interface. What if I change my mind and want to see the public/protected/private stuff separated out into groups first, and then grouped by member kind?
Using regions to mark out public properties (for example) is as bad as entering a redundant comment that adds nothing to what is already discernible from the code itself.
Anyway, to avoid having to use regions for that purpose, I wrote a free, open source Visual Studio 2008 IDE add-in called Ora. It provides a grouped view automatically, making it far less necessary to maintain physical grouping or to use regions. You may find it useful.
I think that it's a useful tool, when used properly. In many cases, I feel that methods and enumerations and other things that are often folded should be little black boxes. Unless you must look at them for some reason, their contents don't matter and should be as hidden as possible. However, I never fold private methods, comments, or inner classes. Methods and enums are really the only things I fold.
My approach is similar to a few others here, using regions to organize code blocks into constructors, properties, events, etc.
There's an excellent set of VS.NET macros by Roland Weigelt available from his blog entry, Better Keyboard Support for #region ... #endregion. I've been using these for years, mapping ctrl+. to collapse the current region and ctrl++ to expand it. Find that it works a lot better that the default VS.NET functionality which folds/unfolds everything.
I personally use #Regions all the time. I find that it helps me to keep things like properties, declarations, etc separated from each other.
This is probably a good answer, too!
Coding Horror
Edit: Dang, Pat beat me to this!
The Coding Horror article actual got me thinking about this as well.
Generally, I large classes I will put a region around the member variables, constants, and properties to reduce the amount of text I have to scroll through and leave everything else outside of a region. On forms I will generally group things into "member variables, constants, and properties", form functions, and event handlers. Once again, this is more so I don't have to scroll through a lot of text when I just want to review some event handlers.
I prefer #regions myself, but an old coworker couldn't stand to have things hidden. I understood his point once I worked on a page with 7 #regions, at least 3 of which had been auto-generated and had the same name, but in general I think they're a useful way of splitting things up and keeping everything less cluttered.
I really don't have a problem with using #region to organize code. Personally, I'll usually setup different regions for things like properties, event handlers, and public/private methods.
Eclipse does some of this in Java (or PHP with plugins) on its own. Allows you to fold functions and such. I tend to like it. If I know what a function does and I am not working on it, I dont need to look at it.
Emacs has a folding minor mode, but I only fire it up occasionally. Mostly when I'm working on some monstrosity inherited from another physicist who evidently had less instruction or took less care about his/her coding practices.
Using regions (or otherwise folding code) should have nothing to do with code smells (or hiding them) or any other idea of hiding code you don't want people to "easily" see.
Regions and code folding is really all about providing a way to easily group sections of code that can be collapsed/folded/hidden to minimize the amount of extraneous "noise" around what you are currently working on. If you set things up correctly (meaning actually name your regions something useful, like the name of the method contained) then you can collapse everything except for the function you are currently editing and still maintain some level of context without having to actually see the other code lines.
There probably should be some best practice type guidelines around these ideas, but I use regions extensively to provide a standard structure to my code files (I group events, class-wide fields, private properties/methods, public properties/methods). Each method or property also has a region, where the region name is the method/property name. If I have a bunch of overloaded methods, the region name is the full signature and then that entire group is wrapped in a region that is just the function name.
I personally hate regions. The only code that should be in regions in my opinion is generated code.
When I open file I always start with Ctrl+M+O. This folds to method level. When you have regions you see nothing but region names.
Before checking in I group methods/fields logically so that it looks ok after Ctrl+M+O.
If you need regions you have to much lines in your class. I also find that this is very common.
region ThisLooksLikeWellOrganizedCodeBecauseIUseRegions
// total garbage, no structure here
endregion
Enumerations
Properties
.ctors
Methods
Event Handlers
That's all I use regions for. I had no idea you could use them inside of methods.
Sounds like a terrible idea :)