Thursday, December 15, 2005
Contextual Validation
I always felt that the validation belongs to the domain.
I think that the best solution would be to have one/several validation rules, in the domain,
which are used by the controllers.
Also Martin Fowler blogs about it, and check the Hibernate Validator.
Sunday, December 11, 2005
Languages History
Friday, December 09, 2005
Human Inteface Debate (redux)
It is all about code-organization. Every class has different views How you organize these categories, (different views), is another bussiness.
You can use Utilities-Classes, or you can extend classes and add method categories, or you can use Aspects, or traits, or mixins...
ps. Good read: the Bernard Notarianni's "Object Orientation Enlightenment".
Maye it should deserve its own post...
And today, I realized what I missed.
The important part is not the code: it is the upper part with classes, protocols and methods. Programming with Smalltalk is actually creating meaningful class’s names, meaningful methods names and organize them into self explicatory protocols.
Thursday, December 08, 2005
Scrum for Microsoft
As we all know, Scrum is XP for project managers.
But:
David Treadwell, corporate vice president of the .Net Developer Platform group at Microsoft, said that while Microsoft welcomes the use of methodologies like Scrum, "we're not mandating them, but we're encouraging them. So Scrum is one process—the idea that teams meet once a day for half an hour, figure out what they're going to do then go off and do their work very quickly.
"The other is extreme programming—the concept where you might have two people working on a given piece of code and the idea is that two minds are better than one. Because you can find problems faster."
Tuesday, December 06, 2005
Java (.Net) Style vs Smalltalk (Ruby) Style
Well I think that both parties are wrong/right.
78 Methods is a little bit too much, but in Smalltalk the Classes are extended and I believe that the 437 methods for the Object class are meant to be there. (And not in the Object-Utilities class like the C#3.0 way).
Second to that, you *must* love the way methods/classes can be categorized in Smalltalk.
It's like a quick-sort for my eyes, tired of scroll-down, scroll-down.
I must go back to C#: actually the whole "utilities" stuff, in the C#3.0 is a hack for extending/categorizing classes and methods. We will have: Object-Xml-Utilities, Object-JSON-Utilities and lots and lots of other Utilities (or Categories !?).
3rd, access by index in a List is wrong !!! The whole concept of hiding the implemetation has vanished. I don't want to write list.get(list.size() - 1) !!! This is clearly a code-smell. All the references in the code snippet are to the list, so the list should/must contain the method which wraps this code snippet , i.e. list.last() method.
Some really nice metaphors:
The cell phone is a great mental model for how to design a class. You just punch in the number of the person you want to speak to, and the phone takes care of the rest. You don't need to know anything at all about how the cell network operates, how it interfaces to the land-line system, or anything else for that matter, to complete your call. The phone is a black box with an intention revealing API.
[isomer]
Alan Kay has lamented publicly on more than one occasion that he should have called it Message Oriented programming to drive home the idea that designing the correct messages is of paramount importance.
With bitterness: "The only thing we learned from history is that we did not learn anything from history."
ps.
But there's more wrong with the collections in Java: optional methods Which means the implementation may or may not support the method. This is one of the benefits of static typing. You know at compiletime that the instance will have the method.
The same disease has the .Net Framework. Just look at the IList implementation of the Array.
"... Always throws NotSupportedException". The class Array is clearly lying about fulfilling its contract, to implement IList interface. What are the benefits of static-typing in this case, compare to dynamic typing + #messageNotUnderstood?
Wednesday, November 23, 2005
Microsoft’s recommendations for Test Driven Development are wrong!
Please also look on the TDD for some good points. I think that Microsoft only wants to sell its software, that's why:
a. "we know better"
b. "our tools are better than other open-source tools"
c. "you cannot live without our tools"
d. "Buy our software !!!"
Finally Jeremy made a really, really, good point: don't be a sheep, think for yourself
A.) We need to diversify our sources of knowledgeps. Also Scott Bellware here
B.) We need to question any and all advice from Microsoft (or anyone else) and think for ourselves
C.) We need to have an active conversation with ourselves on best practices
Friday, November 18, 2005
Thursday, November 17, 2005
Notes on "Pragmatic Unit Testing"
[my thoughts]
What Do I Want to Accomplish:
- Does it do what I want?
- Does it do what I want all the time?
- Can I depend on It ?
- Does it document my intent?
Excuses For Not Testing
- "it takes too much time":
- If you wait to begin unit testing until then it will definitely take too long
- It's like trying to clear a couple of acres of land with a lawn mower.
If you start early on when there's just a field of grasses, the job is easy.
If you wait until later, when the field contains thick, gnarled trees and dense,
tangled undergrowth, then the job becomes impossibly difficult.
- takes a partial from the time spend on debugging code, reworking code, isolating a reported bug
- "it's not my job to write tests"
- our job is "to create working code".
What to Test: The Right-BICEP
- Right: Are the results right?
- B: Are all the boundary conditions CORRECT?
- Conformance: Does the value conform to an expected format?
- Orderering: Is the set of values ordered or unordered as appropiate?
- Range: Is the value within reasonable minimum and maximum values?
- Reference: Does the code reference anything external that isn't under direct control of the code itself?
- Existence: Does the value exist (e.g. is not-null, nonzero, present in any set, etc.)?
- Cardinality: Are there exactly enough values?
- Time (absolutely and relative) - Is everything happening in order? At the right time? In time?
- I: Can you check inverse relationship?
- C: Can you cross-check results using other means?
- E: Can you force error conditions to happen?
- P: Are performance characteristics within bounds?
What Else Can Go Wrong?
In good object oriented design, you do not use a raw native type (e.g. an int or Integer) to store a bounded-integer value such as an age, or a compass heading.
Almost any indexing concept ... should be extenesively tested. Here are a few ideas to get you started:
- Start and End index value have the same value
- First is grater than Last
- Index is negative
- Index is greater than allowed
- Count doesn't match actual number of items
...
If you have to make assumptions abotu the state of the class and the state of other objects
or the global application, then you need to test your code to make sure that it is well-behaved if
those conditions are not met.
[I hate when funkyObject.DoStuff() works only when something else happened before. We should try to write stateless functions, since the name of the function usually does not state when the function works, and when not; basically the object is lying. If the functions are stateful, please make them private, so that the clients don't see them.]
Make sure your method can stand up to nothing.
In most cases, the count of some set of values is only interesting in these 3 cases:
- 0 (Zero)
- 1 (One)
- More than one
[Always prepare/test for multi-threading access of your object.]
[A function name should represent the "happy" case, what the function does, but 90% of the TestCases should specify what the function does when things went wrong]
[The object must always be able to react to any situation]
[Test the boundary conditions make me think of prolog:
quick_sort([],[]).
quick_sort([H|T],Sorted):-
pivoting(H,T,L1,L2),quick_sort(L1,Sorted1),quick_sort(L2,Sorted2),
append(Sorted1,[H|Sorted2]).
pivoting(H,[],[],[]).
pivoting(H,[X|T],[X|L],G):-X=
define the boundaries, define the "work" case. ]
...
Properties of Good-Tests: A-TRIP
- Automatic
- Thorough
- Repeatable
- Independent
- Professional
When fixing any bug, ask yourself the key question:
Could this same kind of problem happen anywhere else?
"Don't expose your privates!" (might be a warning that another class is struggling to emerge)
"All Tests Pass All The Time"
[see resources for the "Pragmatic Unit Testing: Summary"]
[Design for Testability: Think "How am I going to test my software!?", do TDD, and everybody will thank you (including the QA department)]
[Test the class invariants (like a list is always sorted). There is something that we could check for every test scenario.]
[Make the Test code proffessional: refactor, avoid duplicates, create helper classes/functions]
Who is suppossed to check the validity of input data?
"Keep the barbarians out at the gate"
Tuesday, November 15, 2005
Java Generics are Rude
When I see the "pain", the , I need to ask myself why?
Does Sun think: "Oh, this is straight forward. We can do this. This will make the life of our customers (developers) much better."
Some people are really obsessed with static-typing. They really think static-typing is safe.
On recent discussion I said that dynamic-typing requires more "common sense" than static-typing.
The whole duck-typing (and the lack of interfaces) implies a more polite discussion between the
API provider and the API customer: a more careful choice of naming, a more consequent API documentation. And probably the lack of IntelliSense improves this politeness, since the communication is based on mutual trust, and not on tools capabilities (but that's another story).
But the Java samples are really, really "rude". Instead of concentrating on the solution, I need
to understand the difference between , , and the whole generic-baggage. The generics don't show me the solution, they hide it from me. They are like a chatty guy, who is wasting my time with all-kind-of-nonsense.
Here is the James Robertson Smalltalk (civilized) solution:
initialize: aList
list := aList.
add: aThing
list add: aThing.
handle
list do: [:eachItem | "code to do stuff here"].
Monday, November 14, 2005
Saturday, November 12, 2005
Wednesday, November 09, 2005
Think Different (Visual Studio Rots the Mind)
It's more about how our tools (IDE/Language/Vocabulary) influence our way of thinking and inherently our solutions.
See also the Behaviour-Driven-Development vs. Test-Driven-Development.
Psychology tells us that the words we use shape our thinking. By continually using the word "test" when talking about TDD, we place emphasis on the side effects rather than the goal. There has been ongoing discussion about this wording problem for a number of years in the Agile community but until now, nobody has put forth a proposal to fix it.Note: I think that "test" as a name is a smell, since it reveals the implementation details.The real question is: Are we testing or are we specifying ?
Are we doing code-based-allways-up-to-date-specification, or are we testing an implementation. If we mean xUnit is a DSL for specification, then the naming is bad. In NUnit/TestNG the problem is partially solved.
Or how the java guys are asking for an IDE for Ruby. (some are asking for IntelliSense for ruby)
We should really learn a new language every year. If we speak differently, we think differently.
We should eliberate our mind from these tool/Framework/IDE/vocabulary boundaries.
And a highly interesting quote from Seattle Mind Camp:
Just more evidence that everything that was old is new again.
Friday, November 04, 2005
AppDirs for Linux
GNUstep
GoboLinux
The Zero-Install system (sort-of, installer)
Konvalo.org (sort-of, installer)
Rox Desktop (sort-of, desktop manager)
Thursday, November 03, 2005
Visual Studio Hacks
Wednesday, November 02, 2005
Behaviour Driven Development
Dave Astel here and here.
Some blog entries from Wayne Allen here and here,
and from Chris Matts here and here.
A framework for ruby: RSpec.
Notes/Quotes on BDD
- no units but "facets of behaviour"
- level of granularity much smaller than that of the typical unit test
- TDD/BDD: you write specifications of what your code will have to do.
- it's all about specifying behaviour and not writing tests
- the idea of having a Test class for each of your production classies is ridiculously limiting. And the thought of testing each of your methods with its own test method(1-1 relationship) will be laughable.
Monday, October 31, 2005
Team Size
3-5, 5-7 are the "magic" numbers.
I think 4-6 (2, 3 pairs) is more appropiate.
Unit-Test and Mocking
2nd. ThoughtWorks: Mocks are Evil
I think that the notion of OO is not really well understood: in an OO-world, we have objects,
and messages. Object A sends the message MSG to object B.
“...things often go wrong where one part of a system communicates with another (e.g. business logic connects to a database). The mocked out functions are usually called correctly, but something else is going wrong (e.g. permissions have not been set on the database).” (from comments)
I have the impression that it is not cleared what is it tested, what Unit are we testing now?
Are we testing the object A who sends a message to B, or are we testing B, which is a DB access point? In an OO world, A has no ideea hat implementation has B, and if a DB is behind. Probably,
the right question is: we have not defined how A will react, if B does not respond to the message,
or if it throws an exception.
“Why we should use mocks when we could test for free all underlying layers?” (other developers conversations).
Unit-Test !? We are testing an object, who works with several interfaces... (see PicoContainer-GoodCitizen).
And now from the original post, the story about the Lamp and the Light:
Lets take classic object Lamp.
public class Lamp {
private boolean on;
public void switchOn() {
setOn(true);
}
public boolean isOn() {
return on;
}
private void setOn(boolean on) {
this.on = on;
}
}
Might be I am missing something here. How can we make sure switchingOn behavior worked correctly without verifying the state (on/off) of Lamp?
Isn't this a philosophical question?
Is it there really a light if you are not there to see it? (I think there is an old chinese saying with a falling tree in a forrest)
Do we have light if the Lamp's button says that the lamp is on?
Maybe a better approach would be:
testLampObserverSeesLight() {
lamp.Attach(observer)
lamp.SwitchOn()
Assert.IsTrue(observer.SeesLight());
}
( I still think that test_observer_sees_light_when_lamp_switch_on() is a better name :D)
Bottom-End: Unit-Tests are a base for your development. If they are incomplete: is your fault.
If you test Setters/Getters is your fault. If you want to test the DB in the BussinessLogic layer: is your fault.
Conveying intent in tests
what is more readable:
testValidateAddressFailsWithMissingStreetName()
very long "german"-kind-of function name, or:
test_validate_address_fails_with_missing_street_name()
I found the 2nd more readable, i.e. it documents better the intent of the function validate(). Is it right to have a coding style for UnitTests (snake-style) and another style for coding !?
Matz said that for him the 2nd coding style is easier to read. I've got used with camel/Pascal case, but for the cases mentioned above, it is really a pain (in the eye).
I read the whole sentence, than I have to re-read it, to impregnate my brain with its meaning. Maybe we should reconsider Word_Separators.
On the other hand, if the name is too big, is probably a CodeSmell: the function is doing too much, the object knows too much. (DataGridPreferredColumnWidthTypeConverter !?) Maybe another namespace separation is needed?
Tuesday, October 25, 2005
Rake and Rant
rakefile.rdoc
Martin Fowler's article
Ruby for Java builds
Rant (Stefan Lang)
The Free Lunch is Over
I found the same concern in Martin Fowler and Bertrand Meyer's writings.
A better concurency model (for our brains) is needed.
Thursday, October 20, 2005
Ruby Gem
problem:
I have a class Foo which has a number of heavy, CPU intensive, number
crunching methods that take parameters.
class Foo
attr_reader :x, :y, ...
def calc1(a,b,c)
...# complicated, time-consuming calculation...
end
def calc2(a,b)
...# complicated, time-consuming calculation...
end
...
end
Foo is immutable. If a client calls a method more than once using the
same set of parameters, the same result will be calculated and
returned.
To avoid the work of recalculating a result if a client calls a method
more than once with the same set of parameters, I revised Foo to cache
results in a hash for each method for each set of parameters. The
keys in the hashes are arrays of parameters.
class Foo
def calc1(a,b,c)
param_array = [a,b,c]
@cache_calc1 ||= {}
return @cache_calc1[param_array] if @cache_calc1[param_array]
ans = ... #same complicated, time-consuming calculation...
@cache_calc1[param_array] = ans
end
def calc2(a,b)
param_array = [a,b]
@cache_calc2 ||= {}
return @cache_calc2[param_array] if @cache_calc2[param_array]
ans = ... #same complicated, time-consuming calculation...
@cache_calc2[param_array] = ans
end
end
This works great -- calculations for a given set of parameters on
each method are now done only once. However, the code seems rote,
repetitive and intrusive to the original methods.
Solution:
> original I think) on RAA (http://raa.ruby-lang.org/project/memoize).
to do. A handful of lines. I can see it works.
#my test code
f = Foo.new
f.memoize(:calc1)
f.memoize(:calc2)
f.calc1(1,2,3)
f.calc1(1,2,3) #yep its working
f.calc1(7,8,9) #yep its working
If I can ask a Ruby 101 question about it... Isn't "cache" in the
module (pasted below in its entirety it is so short) only a local
variable? Why does is retain state? How can one, for example, access
the cache to see the state of the cache?
Thanks!
--Brian
MEMOIZE_VERSION = "1.0.0"
def memoize(name)
meth = method(name)
cache = {}
(class << self; self; end).class_eval do
define_method(name) do |*args|
cache[args] ||= meth.call(*args)
end
end
end
end
Delicious.
Wednesday, October 19, 2005
Tuesday, October 11, 2005
Why I like Ruby
Here is how Martin Fowler explains it in CollectionClosureMethod
And Matz slides at OSCON2005
Actually there are more points to it (how you can mold the language, to represent your domain)
(7.hours, meme.to_yaml, etc)
But the internal iterator + closures are very powerfull.
Wednesday, October 05, 2005
Sunday, October 02, 2005
When close to natural language goes wrong
In English, these two statements ought to be considered synonymous:
path of fonts folder of user domain
path to fonts folder from user domain
But in AppleScript, they are not, and rather are brittlely dependent on the current context. In the global scope, the StandardAdditions OSAX wants “path to” and “from user domain”; in a System Events tell block, System Events wants “path of” and “of user domain”.
Friday, September 30, 2005
Dependency Injection Presentation
Dependency Injection: Vitally Important or Totally Irrelevant?
The answer is, of course, in the middle :D
Thursday, September 29, 2005
Closures in Ruby and Smalltalk
and Memoranda's comparison Smalltalkvs Ruby
You may want to work with some aspect of selected employees;
for example, to collect the spouse names of all managers.
In other words, select the managers from the employees and collect their spouse name
Smalltalk
(employees select: [:each | each isManager])
collect: [:each | each spouseName]
C#
foreach(Employee employee in employees) {
if (employee.IsManager) {
result.Add(employee.SpouseName)
}
}
Which is closer to "english", which represents better our intention (mentally)?
I find the C# solution a little bit low level: we have to many implementation details.
Smalltalk is more abstract, it says exactly what it does.
ps.
Anothe nice approach is the Smalltalk project: where:
employees
project: [:each | each spouseName]
where: [:each | each isManager]
Credits to RichardA. Demers
lesscoder
Some nice blogs about dynamic languages (python, ruby, perl).
for instance this: j2ee vs rails
Whhooau!
I think I am a "lesscoder". (talk like a pirate is very funny :D)
Tuesday, September 27, 2005
Agile Testing with Dynamic Languages
Jython : Anybody coding in a statically compiled programming language that is not using a dynamically typed programming language for the tests, has missed a golden opportunity for a productivity leap. In the C world, CPython. In the .NET world, IronPython. In the Java world, Jython.
Also check this example.
While the original comment refers to the Java world, what options do we have in .Net.
What Dynamic languages are available (except VB.Net which I personally don't like)?
- IronPython
- Smalltalk# (see some implementations details here: life is hard without the Smalltalk VM :D)
- Ruby.Net Bridge (Rook, Ruby.Net and others implementations for .Net are still "primitive")
- Boo. (has some nice features !!!)
Probably for tests I would go with IronPython/Boo.
Smalltalk# seems a very nice alternative for development. I have to see how it copes with the VM limitations. (#Dilbert would be a nice exercise).
The downside of the Ruby bridge is that you have to install 2 things: Ruby and the bridge.
And it is slow (cca 5x, I've read somewhere). That could affect the Continuous Integration.
Saturday, September 24, 2005
Dirty Glasses
entry about Thoughts on Domain Languages.
Here is his article: Closer is Better.
I found the comments really interesting:
[Anthony Nassar]: I've just seen the specification for C# 3.0. Good heavens They've added what look like some of the features of dynamically typed languages, but making C# all things to all people is going to open the door again to the coding style I remember from VB.NET.
[james bridger], on C# and LinQ: For some reason this is getting lots of love at the moment - I've only seen one negative comment on it. Maybe I'm just missing something...
[Tom Sattler]: The most annoying thing about this original post is referring to Smalltalk in the past tense. Hey, world, it's STILL HERE, dammit.
First, I must apologies to Tom Sattler: I know you are "here", so is ruby, eiffel, haskell, lisp.
But you are not here in the minds of the people who decide which technology will use on their projects. And we know why: for java/c#/c++ you will always get developers, and there is a lot of people who use it. This doesn't make it better, but it makes it safer as an investment.
And this whole push up movement gets with the numbers
(developers, developers, developers) inertia:
the bigger is the mass of the developers, the "easier" will be for the people to read these programs, more components are made available on that platform, more speeches are on this thema, more jobs will be, more people will like to learn technology X to get a job, and so on.
So in the end it gets to that: how fast are you getting the critical mass, how fast can you sell your stuff to a "flock" of developers, until they follow you until the end.
I think there are few programmers who can appreciate the elegance of Smalltalk. (Personally I like ruby better: I've got intoxicated with the C/C++ syntax for more than 10 years, so it is very hard for me to quit: I just love the dots and the parantheses :D)
Now about C# and LINQ: Yes, "Good Heavens". I already posted on that, and I don't understand it either. They (Microsoft) already have a product which does all that LINQ, and it is called FoxPro. Where is that now? If it is so good, why isn't it ported to .Net? Why don't they push the VisualFoxPro, like they did with C#?
Why can't we take a step back, and realize that "Less is More".
With less language baggage, your programs will be easier to write and maintain. With less, but better programmers, you can advance faster than with a herd of medium developers.
[Troy Brummel] said: I can read Smalltalk, and write in it, but there's nothing in it that I can pick up and show to a domain expert, have her read it, and say "yeah, that's what I meant." And, I don't think it comes any closer to doing that than any other language I've used.
I see the problem from another angle: our job is to model a domain, and every "using", "lock",
"var", "select" is a baggage which we carry and makes our job more difficult. This stuff I have to read, understand, understand what the others meant by using it. All this "baggage" stays in your way, it "hides" the domain from you. That's why we train ourselves, to be able to carry (and don't feel) this burden. (I see that Troy is a very strong developer.)
Metaphor: My glasses are dirty, and I see the "domain" with spots. :D
ps. Another post about curving the learning curve.
Thursday, September 22, 2005
Preview C# 3.0
1. Implicitly variable types
var i = 5;
Somebody said, in the context of usability: "Don't make me think".This is not the case: the code is easier to write, but more difficult to read.
2. Object Initializers
Point p = new Point { X = 0, Y = 1 };
I hope this does not encourage people to use setters.
To put everything in the constructor, and eliminate the Setters,
would be a much more object oriented approach:
new Point(0,1).
...and probably faster: if we watch the IL,
two extra calls to the setters are made.
(Discussion about why getters are good, setters are bad.)
3. Anonymous Types
hmmm...
I cannot see how this would make the code more readable/maintainable.
Maybe for LINQ stuff ?
4. Extension Methods
Ahhhh... This is a trick to extend "sealed" classes.
(Pls. read multiple-inheritance hack, partial implementation of ruby-mixins).
Eiffel supports both multiple-inheritance and .Net,
so why are we hacking around?
By the way, why do we have sealed classes?
Why am I, a client who want to use your classes,
obstructed to extend your work,
with my extra_funky_functionality?
Isn't your class Open-Close?
5. Lambda Expressions
Great!!! Finally the "modern" languages are approaching Smalltalk.
6. D/X Linq
I really don't understand this decision. Instead of "minimizing" the (syn)tax,
Microsoft is making C# more and more complicated.
Why can't we have a clear separation ofconcerns:
- here is the bussiness logic,
- here is the persistance layer, with this DB,
and this is how is mapped(SQL commands).
iBatis makes a really nice job with the databases.
So what we will have: a big FoxPro (sorry VB/C#) soup,
which nobody can maintain.
No problem, than we can (re)start from begining.
ps. Another analysis on Mixin-Closure/Block-DynamicProxy
Tuesday, September 20, 2005
Thursday, September 15, 2005
Thoughts on Domain Languages
Ruby, as well.
Eiffel, too.
Haskell as well.
from this interview:
AT: Most languages require you to pay a "language tax": code that does nothing with the main algorithm, placed there only to make the computer happy.
...
Haskell also encourages you to shape the language to fit your problem domain, so the program often reads out like a runnable specification.
(read: you will have more syntax-noise in the code).
This "noise" can help you to understand the tehnology,
but it troubles you in understanding the domain.
That's why Smalltalk is good: very simple syntax. The rest is Domain Language.
[Errata, thanks to Tom Sattlers observation]
Smalltalk is no past tense.
IConvention
snippets:
Get rid of the "I". Also you C++ programmers should get rid of the "m_" and you DAO fans should get rid of the DAO suffix. All these annotations put up a barrier to being able to "read" the code. When I read ICommand I feel like there is something missing, like I Command you to take out the garbage. When I see the C++ programmers "m_" I find myself humming while I read the code mmmmm counter, mmmmm index, mmmmm transmitter, mmmm window. Was the programmer really happy and humming, or were they confused and not sure what variable name to use? Probably the latter. Ohhh. a member variable, that is something special.
Well-written code (small classes, small methods, clear separation of responsibilities) has no need of Hungarian notation. What makes code readable is its approximation of natural language - Hungarian notation degrades that.
The second and bigger one is, the example you give is flawed. If you hose to turn your ICommand interface to a base class, then renaming isn't going to be the issue (as it can all be done by Resharper or equivalent in a few seconds at most). The problem is that many classes implementing your ICommand interface could now be very broken due to C# not supporting MI - so anything that has a base class already isn't going to work... and now you have a massive architectural nightmare.
Java has "extends" and "implements" which communicates very well on what the class inherits. C# doesn't have that, instead it uses the convention that if you inherit from more than one thing, the first must be a class and there can only be one class.
I think we have a mixture between:
- C# does not support multiple inheritance
- java's syntax is more explicit than C#'s
- The programmers need a language closed to the domain, (DSL),
the hungarian notation stays in the way.
- What we want is compiler-checked DuckTyping
I really want to learn Eiffel, to see if it delivers the answers, so shiny presented in
EiffelSoftware's presentations:
- multiple inheritance
- very close to Domain Language
The Humble Dialog Box
Here (and here) is a TDD sample for .Net, from Jeremy D. Miller.
Tuesday, September 13, 2005
Monday, September 12, 2005
a Set of Unit Testing Rules
A test is not a unit test if:
True, but communication to DB, over network, must also be Unit-Testable.
Probably a categorization fast/slow, partial/full, should also be done.
Michael answer to these points:
> Sometimes, your unit test must do some of these things:
> 1. You test a class who's function is to interact with a
> db, write/read a file, or write/read the Windows
> Registry.
I'm pig headed, I write them but I don't call them UTs when I'm with a team. Say that we are working test first and we discover we need to save things in the registry. To me it's best to think about what we need more abstractly, we just need a place to store things and chances are it doesn't need to be hierarchical in the beginning. So we can develop that abstraction (which probably looks as simple as a map) and it's guaranteed to be easier to use than the Windows registry.
If we go that route, we make an implementation of that abstraction that works in memory for testing and one that translates its calls to the Windows registry calls.
> 2. You develop a client; to make sure it works, it
> must interact with a server. At my work, for
> example, our client must exchange timestamped, signed, XML
> messages with a server. The test will not be complete
> without server interaction. Actually, you simply
> cannot test this without a server.
>
> You want to say these are not unit tests? I'll argue that
> the tests can't be any simpler.
I agree that they are necessary, but I really like to see what can be done to strip logic away from I/O for the UTs. Other tests can handle the collaboration and the tests that actually touch the database or the the server, they have tests too, but there are in some netherworld in my view. In general, I don't think there should be many of them.
I think that the main point is that we should use abstractions, "interfaces" in our program. It doesn't matter where the SmartObject.IsFunky gets his information, as long as he can answer the question "IsFunky". And this point of view should be seen in the UnitTests as well.
Friday, September 02, 2005
cream on vim
for both Microsoft Windows and GNU/Linux.
http://cream.sourceforge.net/
Xml Alternatives
http://www.pault.com/pault/pxml/xmlalternatives.html
Personal preference:
JSON, PLists, Yaml.
Wednesday, August 24, 2005
Monday, August 08, 2005
Thursday, August 04, 2005
Should an IoC Container obey the Single Responsibility Principle?
"I would think just having any IoC/Dependency Injection tool should be enough out of the box. I wrote another DI tool called StructureMap on sourceforge (predates both Castle and Spring.Net;-)). I haven't added any specific support for NHibernate yet, but it looked like it wasn't really necessary just to be able to handle creating the NHibernate objects from configuration. We use it straight out of the box to locate and create persistence service classes today."
Or an IoC container should be seen as "framework", with several features/responsibilities?
Tuesday, August 02, 2005
Sunday, July 31, 2005
Wednesday, July 20, 2005
Containers and WebApplications
NanoWar works by having a hierarchy of containers, one at the application scope, one in each session whose parent is the application container, and one is created for each request with the parent as the appropriate session container.
...
This model allows for stateful components in the meaningful scopes -- if you have session state, it is stored in a component scoped to the session. Actions can be stored at any level -- stateless ones (a la Struts or SpringMVC) may be defined in the application level scope, one-off actions (a la WebWork) can be defined in the request scope container. Wizard style ones (if you don't have a concept of wizard scope) can be session scoped, and use a state machine to figure out what is next.
Saturday, July 16, 2005
Could Rails have been built without Ruby?
Nice discussion about dynamic/static typing,
LISP-like languages, metaprograming, design patterns.
"..in the OO world you hear a good deal about "patterns." I wonder if these patterns are not sometimes evidence of case (c), the human compiler, at work. When I see paterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough - often that I'm generating by hand the expansions of some macro that I need to write."
"Code Complete" Quotes
"When you look at the architecture, you should be pleased by how natural and easy the solution seems. It shouldn't look as if the problem and the architecture have been force together with duct tape"
"You might think of the lines between subsystems as being hoses with water running through them. If you want to reach in and pull out a subsystem, that subsytem is going to have some hoses attached to it. The more hoses you have to disconect and reconnect, the more wet you're going to get. You want to architect your system so that if you pull out a subsystem to use elsewhere, you won't many hoses to reconnect and those hoses will reconnect easily"
"A class is a lot like an iceberg: 7/8 is under water, and you can see only the 1/8 that's above the surface"
-- Steve McConnell
Pico Container Good Citizens
from here
As a good citizen, I...
- Keep a consistent state at all times - init() or populate() is a code smell.
- Have no static fields or methods
- Never expect or return null.
- FailFast - even when constructing.
- Am Easy to test- all dependent object I use can be passed to me, often in my constructor (typically as Mock Objects).
- Accept dependent object that can easily be substituted with Mock Objects (I don't use Concrete Class Dependency).
- Chain multiple constructors to a common place (using this(...)).
- Always define hashCode() alongside equals()
- Prefer immutable value objects that I can easily throw away.
- Have a special value for 'nothing' - e.g. Collections.EMPTY_SET.
- Raise checked exceptions when the caller asked for something unreasonable - e.g. open a non-existant file.
- Raise unchecked exceptions when I can't do something reasonable that the caller asked of me - e.g. disk error when reading from an opened file.
- Only catch exceptions that can be handled fully.
- Only log information that someone needs to see.
Friday, July 15, 2005
txt2tags
txt2tags seems perfect for small-scale, revision controlled, documentation.