I once had a colleague who had a higher rank than me, and who was not only unconvinced by my rational and articulate arguments for doing a certain thing in a certain way, but he concluded the discussion by stating that --and I am not paraphrasing here, this is what he actually said-- the way he wanted it done was mentioned in a book, so unless I could find a book backing up my proposal, it was to be done his way.
I did not argue with him at that time, (how can you argue with that?), but I would now like to quickly jot down my thoughts on why saying such a thing is incredibly stupid:
2015-04-30
Wow, 5 upvotes, 10 downvotes and counting
I have this answer on programmers.stackexchange.com which, at the time of writing these words, has 5 upvotes and 10 downvotes, and in all likelihood it will continue collecting downvotes, while I adamantly refuse to remove it, standing 100% by my ideas. I am dumbfounded, as such a thing has never happened before.
Here is the programmers.stackexchange.com question:
Here is the programmers.stackexchange.com question:
Is it okay to have objects that cast themselves, even if it pollutes the API of their subclasses?
I have a base class,Base
. It has two subclasses,Sub1
andSub2
. Each subclass has some additional methods. For example,Sub1
hasSandwich makeASandwich(Ingredients... ingredients)
, andSub2
hasboolean contactAliens(Frequency onFrequency)
.
Since these methods take different parameters and do entirely different things, they're completely incompatible, and I can't just use polymorphism to solve this problem.
Base
provides most of the functionality, and I have a large collection ofBase
objects. However, allBase
objects are either aSub1
or aSub2
, and sometimes I need to know which they are.
It seems like a bad idea to do the following:
for (Base base : bases) {
if (base instanceof Sub1) {
((Sub1) base).makeASandwich(getRandomIngredients());
// ... etc.
} else { // must be Sub2
((Sub2) base).contactAliens(getFrequency());
// ... etc.
}
}
So I came up with a strategy to avoid this without casting.Base
now has these methods:
boolean isSub1();
Sub1 asSub1();
Sub2 asSub2();
And of course,Sub1
implements these methods as
boolean isSub1() { return true; }
Sub1 asSub1(); { return this; }
Sub2 asSub2(); { throw new IllegalStateException(); }
AndSub2
implements them in the opposite way.
Unfortunately, nowSub1
andSub2
have these methods in their own API. So I can do this, for example, onSub1
.
/** no need to use this if object is known to be Sub1 */
@Deprecated
boolean isSub1() { return true; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub1 asSub1(); { return this; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub2 asSub2(); { throw new IllegalStateException(); }
This way, if the object is known to be only aBase
, these methods are un-deprecated, and can be used to "cast" itself to a different type so I can invoke the subclass's methods on it. This seems elegant to me in a way, but on the other hand, I'm kind of abusing Deprecated annotations as a way to "remove" methods from a class.
Since aSub1
instance really is a Base, it does make sense to use inheritance rather than encapsulation. Is what I'm doing good? Is there a better way to solve this problem?
Tags: java, inheritance, type-casting
asked by codebreaker
2015-03-20
Mandatory disposal vs. the "Dispose-disposing" abomination
This article started as a stackoverflow answer, and then I copied it over here to expand on it.
For a discussion of the same issue but in java-oriented terms, see this stackoverflow answer of mine: Is overriding Object.finalize() really bad? http://programmers.stackexchange.com/a/288724/41811
There is this practice which is unfortunately very prevalent in the C# world, of implementing object disposal using the ugly, clunky, inelegant, ill-conceived, and error prone idiom known as IDisposable-disposing. MSDN describes it in length, and lots of people swear by it, follow it religiously, write walls of text discussing precisely how it should be done and precisely how it works, and precisely how they arrived at this particular way of doing it, etc.
(Please note that what I am calling ugly here is not the object disposal pattern itself; what I am calling ugly is the particular idiom of implementing an extra
This idiom was invented under the assumption that the invocation of
For a discussion of the same issue but in java-oriented terms, see this stackoverflow answer of mine: Is overriding Object.finalize() really bad? http://programmers.stackexchange.com/a/288724/41811
There is this practice which is unfortunately very prevalent in the C# world, of implementing object disposal using the ugly, clunky, inelegant, ill-conceived, and error prone idiom known as IDisposable-disposing. MSDN describes it in length, and lots of people swear by it, follow it religiously, write walls of text discussing precisely how it should be done and precisely how it works, and precisely how they arrived at this particular way of doing it, etc.
(Please note that what I am calling ugly here is not the object disposal pattern itself; what I am calling ugly is the particular idiom of implementing an extra
Dispose
method with a bool disposing
parameter.)This idiom was invented under the assumption that the invocation of
IDisposable.Dispose()
is something optional, or in any case something which might be OK to forget, in combination with the fact that it is impossible to guarantee that our objects' destructor will always be invoked by the garbage collector to clean up resources. So, people tend to make their best effort to invoke their IDisposable.Dispose()
methods, and in case they forget, they also give it one more try from within the destructor. You know, just in case.2015-03-13
Solid State For The Win!
These two screen captures are from CrystalDiskMark measuring the performance of my brand new Samsung 850 PRO 256GB Solid State Drive (C:) versus the performance of my old Seagate Barracuda 1TB 7200 RPM 32MB Cache Hard Disk Drive (D:). Higher numbers are better.
Both devices are capable of SATA III, but my machine only has SATA II. Under SATA III I would expect the HDD to perform somewhat faster, but the SSD to perform a lot faster. I will update this post when I upgrade to SATA III.
SSD, where had you been all my life?
Both devices are capable of SATA III, but my machine only has SATA II. Under SATA III I would expect the HDD to perform somewhat faster, but the SSD to perform a lot faster. I will update this post when I upgrade to SATA III.
SSD, where had you been all my life?
2015-03-03
Minimal MySQL Memory Footprint
The following image shows the mind-boggling amount of memory occupied by MySQL 5.6 server on Windows 7 64-bit.
(This is despite the fact that during installation I explicitly specified that this MySQL server is going to be used for development, not for production.)
A quick search on the web shows that this preposterous amount of memory can be reduced to something less preposterous by editing my.ini (usually found in some place like ProgramData\MySQL\MySQL Server 5.6\) and replacing the following line:
with this line:
(This is despite the fact that during installation I explicitly specified that this MySQL server is going to be used for development, not for production.)
A quick search on the web shows that this preposterous amount of memory can be reduced to something less preposterous by editing my.ini (usually found in some place like ProgramData\MySQL\MySQL Server 5.6\) and replacing the following line:
table_definition_cache=1400
with this line:
table_definition_cache=400
Unfortunately, even though the savings are huge, the memory footprint of mysql is still nothing short of gargantuan:2015-02-11
2014-12-30
Movie: Dawn of the Planet of the Apes
This post does not contain any spoilers, unless you would consider as a spoiler my opinion on how the quality if the movie varies as the movie progresses. (Or the image below.)
So, I watched The Dawn of the Planet of the Apes yesterday, and what can I say, wow, it blew my mind. I started watching it having very low expectations, and I was very pleasantly surprised for about one hour and fifty minutes of its total two hour and ten minute duration, which includes the end titles. Then, starting with the "I am saving the human race" incident, it transformed into the crap that I had expected from the beginning, perhaps even worse, but that does not annul the fact that the first one hour and fifty minutes were one of the most pleasant movie watching experiences I have had in quite some time.
Picture source: cgmeetup.com |
2014-11-27
The transaction pattern and the feature badly missing from exceptions.
Exceptions are the best thing since sliced bread. If you use them properly, you can write code of much higher quality than without them. I think of the old days before exceptions, and I wonder how we managed to get anything done back then. There is, however, one little very important thing missing from implementations of exceptions in all languages that I know of, and it has to do with transactions.
At a high level, exception handling looks structurally similar to transactional processing. In both cases we have a block of guarded code, during the execution of which we acknowledge the possibility that things may go wrong, in which case we are given the opportunity to leave things exactly as we found them. So, given this similarity, it is no wonder that one can nicely facilitate the other, as this sample code shows:
At a high level, exception handling looks structurally similar to transactional processing. In both cases we have a block of guarded code, during the execution of which we acknowledge the possibility that things may go wrong, in which case we are given the opportunity to leave things exactly as we found them. So, given this similarity, it is no wonder that one can nicely facilitate the other, as this sample code shows:
2014-11-24
Bug reporting: a checklist.
Here is a check list for creating useful bug reports:
1. Before reporting, make sure that you are using the latest version of the software.
2. Before reporting something as a bug, make sure it is in fact a bug.
3. Before reporting, play around with the bug to identify it with at least a bit of accuracy.
4. Report through the proper channel, usually an issue tracking system.
5. Make sure that the bug has not already been reported.
6. Invest some time to find a proper title for the bug.
7. State the name of the product in which you found the bug.
8. State the version of the product in which you found the bug.
9. Describe your environment (Operating System name and version, etc)
10. List the steps to reproduce the problem.
11. State the "observed result" of following the steps.
12. State the "expected result" of following the steps.
13. State the reproducibility of the bug. (Or your best estimate of it.)
14. Stick to the facts.
15. Address only one bug per bug report.
16. Include any useful attachments.
Here is a slightly more detailed discussion of each one of the above items:
1. Before reporting, make sure that you are using the latest version of the software.
2. Before reporting something as a bug, make sure it is in fact a bug.
3. Before reporting, play around with the bug to identify it with at least a bit of accuracy.
4. Report through the proper channel, usually an issue tracking system.
5. Make sure that the bug has not already been reported.
6. Invest some time to find a proper title for the bug.
7. State the name of the product in which you found the bug.
8. State the version of the product in which you found the bug.
9. Describe your environment (Operating System name and version, etc)
10. List the steps to reproduce the problem.
11. State the "observed result" of following the steps.
12. State the "expected result" of following the steps.
13. State the reproducibility of the bug. (Or your best estimate of it.)
14. Stick to the facts.
15. Address only one bug per bug report.
16. Include any useful attachments.
Here is a slightly more detailed discussion of each one of the above items:
2014-11-09
IntelliJ IDEA feature request: editor actions for moving the caret left & right with Column Selection.
I just submitted a feature request for IntelliJ IDEA.
It can be found here: https://youtrack.jetbrains.com/issue/IDEA-132626
It can be found here: https://youtrack.jetbrains.com/issue/IDEA-132626
Feature request: editor actions for moving the caret left & right with Column Selection.
It is a fundamental axiom of user interface design that modes kill usability. Having to enter a special mode in order to accomplish something and then having to remember to exit that mode in order to accomplish anything else is bad, bad, bad user interface design, at least when there is even a slight chance that the same thing could be achieved without a special mode. (Think of VI for example: it is the lamest editor ever, and almost all of its lameness is due to the fact that it relies so heavily on modes.)
Unfortunately, programmers tend to think a lot in terms of modes, so the first time the user of an editor asked the programmer of that editor for the ability to do block selection ("column selection" in IntelliJ IDEA parlance) the programmer said "sure, I will add a new mode for this." That's how problems start.
Unfortunately, programmers tend to think a lot in terms of modes, so the first time the user of an editor asked the programmer of that editor for the ability to do block selection ("column selection" in IntelliJ IDEA parlance) the programmer said "sure, I will add a new mode for this." That's how problems start.
Subscribe to:
Posts (Atom)