Deploying .NET Applications – Learning MSBuild and ClickOnce
Friday, March 13, 2009 12:56:23 PM (Mountain Standard Time, UTC-07:00)
I recently finished reading.
I was interested in this book mainly to find an easier way to deploy ClickOnce applications via an automated build. Most of my build automation experience has been with Nant, so I figured learning MSBuild couldn't hurt.
This book targets the Visual Studio 2005 time frame, so some of the things that it describes is out dated, mainly in regards to ClickCnce.
There was a little coverage on mage.exe but not as much as I had liked. If you're looking for a book to get you into the world of Clickonce or MSBuild, this one's pretty good!
Here are some of the things that I learned straight from the book.
MSBuild
Microsoft.Build.Framework and Microsoft.Build.Utilities contains some stuff to help you with your builds. There's an ITask interface and a Task base class that you can implement if you want to run some custom tasks from MSBuild.
ClickOnce is driven by two XML-based manifest files called the deployment manifest and the application manifest.
- Deployment manifest (.application) contains information specific to the deployment of the system.
- Application manifest (.manifest) captures information specific to version of the system.
ClickOnce Deployment
The ClickOnce technology also has a programmatic interface that you can use to customize deployment and updates. For example, if you have a plug-in where the core of the application is deployed initially and then users are allowed to choose optional features (plug-ins) and have them installed on demand, the ClickOnce API can help.
ClickOnce applications have to be deployed to a Web server, to a file server, and/or to removable media (such as CD/DVD). Moreover, you can deploy these applications in one of two modes: offline or online.
For applications that require finer-grained control over doing updates, application authors can use the ClickOnce APIs to customize installation and updates.
Code Access Security (CAS)
- Permission: The authority to do something.
- Permission set: A grouping of arbitrary permissions.
- Origin based Evidence: Where your code comes from determines what permissions your code gets.
- Content base evidence: Your code content is signed and has a publisher certificate, and that determines what permissions you get.
- Code Group: Associates evidence with a permission set
- Security Policy: Policies define a hierarchy of code groups.
On-Demand Download
ClickOnce offers a facility that called on-demand download. The idea is that you create groups of files and then use the ClickOnce APIs to download each group at runtime. The initial download is reduced to what is needs to be downloaded to run the application, and if a piece of functionality is not needed, it is not downloaded.
You can get the path to the Data directory via:
-
AppDomain.CurrentDomain.GetData("DataDirectory");
-
ApplicationDeployment.CurrentDeployment.DataDirectory;
-
Application.LocalUserAppDataPath;
Data-Driven Services with Silverlight 2
Wednesday, March 11, 2009 7:54:23 AM (Mountain Standard Time, UTC-07:00)
I recently finished reading...

Data-Driven Services with Silverlight 2
I have been wanting to get in to the world of WCF for some time now, but wasn't really sure how to get started. This book was good at explaining how to get into WCF quick and easy. The sample apps that the author goes through and provides are pretty cool which makes it more fun.
The book explains how data binding in silverlight (which seems to be similar to how it works in WPF), how to pass objects across the wire using WCF. It explains what RESTful services means, and how to build them leveraging tools on the .NET stack.
The sample apps include one that consumes Amazon's RESTful services, as well as a Twitter client called SilverTwit. There's lots of code to dig through, and try out for yourself.
For anyone interesting in Silverlight or WCF, this is a good book to get you started.
If you're looking for the sample code that comes with the book, you can find it here. http://examples.oreilly.com/9780596523091/
Introducing NLP
Monday, March 02, 2009 1:19:10 PM (Mountain Standard Time, UTC-07:00)
I recently finished reading...
I first heard about Neuro-linguistic programming (NLP) while I was reading The Game: Penetrating the Secret Society of Pickup Artists
. I thought that it sounded like an interesting subject, because I spend a good deal of my time dealing with people and trying to learn new things. If you're interested in trying to become a better communicator or you are interested in trying to find out what your preferred way of learning is, this book will probably help!
Below are some of the things that I learned straight from the book.
The Four Stages of Learning
- Unconscious Incompetence
- Conscious Incompetence
- Conscious Competence
- Unconscious Competence
If you always do what you've always done, you'll always get what you've got. If what you are doing is not working, do something else.
Communication is so much more than the words we say. These form only a small part of our expressiveness as human beings. Research shows that in a presentation before a group of people, 55 per cent of the impact is determined by your body language - posture, gestures and eye contact - 38 per cent by your tone of voice, and only 7 per cent by the content of your presentation.
We move our eyes in different directions in a systematic way depending on how we are thinking. Neurological studies have shown that eye movement both laterally and vertically seem to be associated with activating different parts of the brain.
Movements and gestures will also tell you how a person is thinking. Many people will point to the sense organ that they are using internally: they will point to their ears while listening to sounds inside their head, point to the yes if visualizing, or to the abdomen if they are feeling something strongly. These signs will not tell you what a person is thinking about, only how he or she is thinking it. This is body language at a much more refined and subtle level than it is normally interpreted.
Beliefs can be a matter of choice. You can drop beliefs that limit you and build beliefs that will make your life more fun and more successful. Positive beliefs allow you to find out what could be true and how capable you are. They are permissions to explore and play in the world of possibility.
Towards people are energized by goals and rewards. Away people are motivated to avoid problems and punishment. Arguing which is best in general is futile.
It is easy to recognize this pattern from a person's language. Does she talk about what she wants, achieves or gains? Or does she tell you about the situation she wants to avoid and the problems to steer clear of? Towards people are best employed in goal-getting. Away from people are excellent at finding errors and work well in a job like quality control. Art critics usually have a strong away orientation as many a performing artist can testify!
A good teacher will be able to create an environment, so her students learn for themselves how to get the results.
Learning to learn is the most important skill in education, and needs to be taught from reception class onwards. The educational system concentrates mostly on what is taught, the curriculum and omits the learning process. This has two consequences. First, many students have difficulty picking up the information. Secondly, even if they do learn it, it has little meaning for them, because it has been taken out of context.
Object Thinking
Thursday, February 12, 2009 9:32:44 AM (Mountain Standard Time, UTC-07:00)
I recently finished reading...
| | Object Thinking by David West |
As usual I fold down pages that contain paragraphs that interest me... below are a few excerpts from the book that I enjoyed!
"Better people" has been recognized as the most promising silver bullet for addressing the software crisis, and yet almost all of our energy has been spent on creating better tools, methods, and processes instead of better people?
Imagine what a team of "better people" can accomplish. Now stop imaging, and start investing in fostering cultures that cultivate "better people" all working towards the same goal.
An unspoken but just as widely held belief that really good developers were not to be trusted - they could not be "managed", they all seemed to be "flaky" to some degree, and they did not exhibit the loyalty to company and paycheck of "normal" employees. Really "good" developers tended to be "artists", and are was (is) not a good word in the context of software development.
Those flaky artist types... *sigh* It's important to allow individuals do what they are good at, that's obviously something they like to do. It breeds innovation, and efficiency. When working in a team it's important to be respectful of one another's opinions and work together.
Every once in a while someone on the team will have a crazy idea that just might slash the complexity of the whole system. If they have courage, they'll try it out. It will work (sometimes).
It's important to have courage on any team. XP teams value courage. Without the courage to grow and challenge one another, your team will remain stagnant. By challenging one another you're showing one another respect by saying that "I want you to get better, and I expect you to want me to get better as well"!
Object thinking is a "crazy idea" capable of increasing simplicity in software design - crazy in the sense that it does not conform to traditional thinking about software development, crazy in the sense that it revolts against the computer thinking employed by most software developers, and crazy in many of the same ways that XP is crazy.
Trying to introduce object's into a culture that's firmly devoted to thinking in terms of data can seem like a crazy idea too. There is a time and place for everything, I'm sure objects aren't great for every system. A little bit of object "thinking" can help though, I'm sure.
As a formalist, the computer scientist expects order and logic. The "goodness" of a program is directly proportional to the degree to which it can be formally described and formally manipulated. Proof - as in mathematical or logical proof - of correctness for a piece of software is an ultimate objective. All that is bad in software arises from deviations from formal descriptions that use precisely defined tokens and syntactic rules. Art has no place in a program. In fact, many formalists would take the extreme position: there is no such thing as art; art is nothing more than a formalism that has yet to be discovered and explicated.
Art is something that I enjoy. One of the reasons that I was drawn to software was the creative aspects of it. I first thought of developing software as a form of art. It's great how Test Driven Development allows you to prove the correctness of a piece of software, but also enables you to refactor and be creative.
An analogy to chess playing might illuminate the relationships among method categories. A beginning chess player follows rules and defined procedures (they are formalists), while a journeyman (informalist) relies on patterns and heuristics. A grandmaster has internalized and transcended the informal to become an aformal player.
I'm currently reading a book on NLP, and it describes how experts do most of their work subconsciously, instead of consciously. It's like when you learn to drive a car (assuming you learned on a manual transmission). First you have a set of steps that you must follow, and repeat. Then you begin to follow patterns. (I used to look at my current speed to decide whether to shift gears.) Then you stop thinking about it, and you just drive.
A human uses mechanical weights and machines in a gym to increase his innate capabilities - to make his own muscles strong and more reliable. Using a more cerebral metaphor (and one therefore more appropriate for object thinking), Kent Beck suggest using method and even XP practices as if they were etudes (musical exercises designed to help the musician internalize certain skills and techniques.)
Time and Focus equates to discipline, according to me. In order to excel at something you need to invest both time and focus to truly excel at it. There really is no secret to getting better.
A common tendency for new object developers is to list as responsibilities things that an object must "know." An airplane must "know its current location." While this may be true, it can be misleading. It implies too much about how the object might be implemented because "knows" implies an instance variable. It's also quite possible that an object will know things (a private key for decryption, perhaps) that it will not be willing to share with others and that therefore will not be included in the interface for that object. Provide private key would not appear as a service, although the message privateKey might be in the object's protocol with the designation that it is a private message. Decrypt message, on the other hand, might be a listed responsibility. Always state your responsibilities in terms of a service, with an awareness of a possible client for that service.
I know when I first started transitioning from procedural to object oriented programming, I thought mostly about where and how the data was going to stored, and how to get the data. "This auditor class needs to have a sorted list of audits"... Now it's a little more like "An auditor can submit an audit of a company to ..."
This was a great read for anyone wanting to get into objects, or learn more about the history of objects. It was great to read about were a lot of present day ideas originated from.
Disciplined Agility
Saturday, August 09, 2008 10:01:28 AM (Mountain Standard Time, UTC-07:00)
I finished reading...
What an excellent book, seriously! It was written by Robert C. Martin and his son Micah. The following is a list of excerpts from the book that I can appreciate:
"Continuous attention to technical excellence and good design enhances agility. High quality is the key to high speed. The way to go fast is to keep the software as clean and robust as possible. Thus, all agile team members are committed to producing only the highest quality code they can. They do not make messes and then tell themselves that they'll clean up when they have more time. They clean any messes as they are made."
"The goal of refactoring, as depicted in this chapter, is to clean your code every day, every hour and every minute. We don't want the mess to build. We don't want to have to chisel and scrub the encrusted bits that accumulate over time. We want to be able to extend and modify our systems with a minimum of effort. The most important enabler of that ability is the cleanliness of code."
"Specifying contracts in unit tests. Contracts can also be specified by writing unit tests. By thoroughly testing the behavior of a class, the unit tests make the behavior of the class clear. Authors of client code will want to review the unit tests in order to know what to reasonably assume about the classes they are using."
"Databases are implementation details! Consideration of the database should be deferred as long as possible. Far too many applications were designed with the database in mind from the beginning and so are inextricably tied to those databases. Remember the definition of abstraction: "the amplification of the essential and the elimination of the irrelevant." At this stage of the project, the database is irrelevant; it is merely a technique used for storing and accessing data, nothing more."
"This style of testing is called behavior-driven development. The idea is that you should not think of tests as tests, where you make assertions about state and results. Instead, you should think of tests as specifications of behavior, in which you describe how the code is supposed to behave."
Holy Conditionals Batman...
Wednesday, July 09, 2008 7:17:32 PM (Mountain Standard Time, UTC-07:00)
In case you haven't you should read...
As a reminder, let's talk about a test smell described in the above mentioned book. It's called "Conditional Test Logic".
"Conditional Test Logic: A test contains code that may or may not be executed." xUnit Test Patterns
"A fully automated test is just code that verifies the behavior or other code. But if this code is complicated, how do we verify that it works properly?"
Warning bells should sound off in your head when you start to see looping or conditional constructs within a single unit test.
"Code that has only a single execution path always executes in exactly the same way. Code that has multiple execution paths presents much greater challenges and does not inspire as much confidence about its outcome."
For more information check this out...
Basically Ignore Logic... that could cause multiple execution paths within a single unit test.
In Depth With C#
Sunday, July 06, 2008 7:45:12 PM (Mountain Standard Time, UTC-07:00)
Tonight I finished reading...
This was an amazing book, and definitely offers a great in depth look at the C# language. Most importantly it answered a lot of my questions about elements introduced in C# 3.0, and taught me things I didn't know about C# 1.0. If you're looking for information on the following items, then this book is definitely for you.
- Expression
- IQueryable
- IQueryProvider
- Lamba's
- Type Inferencing
Thanks JP for recommending this book!
Here are a few gems that I picked from this book.
Delegates
"You rarely see an explicit call to Delegate.Combine in C# code - usually the + and += operators are used."
var x = new EventHandler(delegate { });
var y = new EventHandler(delegate { });
x += y;
x = x + y;// same as above
x = (EventHandler) Delegate.Combine(x, y);// same as above
Static vs Dynamic Typing
"C# is statically typed: each variable is of a particular type, and that type is known at compile time. The alternate to static typing is dynamic typing, which can take a variety of guises. "
Explicit vs. Implicit Typing
"The distinction between explicit typing and implicit typing is only relevant in statically typed languages. With explicitly typing, the type of every variable must be explicitly stated in the declaration. Implicit typing allows the compiler to infer the type of the variable based on its use."
Covariant vs. Incovariant
object[] stuff = new string[]{"blah"}; // valid and is an example of covariance
List<object> more_stuff = new List<string>();// invalid and is an example of incovariance
Fluent Interfaces
Jon, the author, mentions a blog post by Anders Noras on Planning a fluent interface
Here's an example of a fluent interface for building menu's that I've been playing with.
CreateA.MenuItem()
.Named("&Close")
.BelongsTo(MenuGroups.File)
.CanBeClickedWhen(m => task.IsThereAProtocolSelected())
.WhenClickedExecute(closeCommand)
.Build();
Readability
"When it comes to getting the broad sweep of code, what is required is 'readability of results' - I want to know what the code does, but I don't care how it does it right now."
There's a lot of information on IQueryables, Expression Trees, and other goodness in this book. This is a great book and definitely worth reading, especially if you're as interested in the C# language as I am.
Trying to be more effective
Sunday, July 06, 2008 6:50:38 PM (Mountain Standard Time, UTC-07:00)
Last week I finished reading...
I really enjoyed this book, it's definitely worth taking the time to sit down and read. I realized a lot about myself as I read it. Hopefully you will too! Here are a few excerpts from the book that had an impact on me.
"Management is a bottom line focus: How can I best accomplish certain things? Leadership deals with the top line: What are the things I want to accomplish?"
"... envision a group of producers cutting their way through the jungle with machetes. They're the producers, the problem solvers. They're cutting through the undergrowth, clearing it out.
The managers are behind them, sharpening their machetes, writing policy and procedure manuals, holding muscle development programs, bringing in improved technologies and setting up working schedules and compensation programs for machete wielders.
The leader is the one who climbs the tallest tree, surveys the entire situation, and yells, 'Wrong Jungle!'"
"Work Centeredness. Work-centered people may become 'workaholics,' driving themselves to produce at the sacrifice of health, relationships, and other important areas of their lives. Their fundamental identity comes from their work - 'I'm a doctor', 'I'm a writer', 'I'm an actor.'
Because their identity and sense of self-worth are wrapped up in their work, their security is vulnerable to anything that happens to prevent them from continuing in it. Their guidance is a function of the demands of the work. Their wisdom and power come in the limited areas of their work, rendering them ineffective in other areas of life."
"There are times when neither the teacher nor the student knows for sure what's going to happen. In the beginning, there's a safe environment that enables people to be really open and to learn and to listen to each other's ideas. Then comes brainstorming, where the spirit of evaluation is subordinated to the spirit of creativity, imagining, and intellectual networking. Then an absolutely unusual phenomenon begins to take place. The entire class is transformed with the excitement of a new thrust, a new idea, a new direction that's hard to define, yet it's almost palpable to the people involved."
"Suppose you were to come upon someone in the woods working feverishly to saw down a tree.
'What are you doing?' you ask.
'Can't you see?' comes the impatient reply. 'I'm sawing down this tree.'
'You look exhausted!' you exclaim. 'How long have you been at it?'
'Over five hours,' he returns, 'and I'm beat! This is hard work.'
'Well, why don't you take a break for a few minutes and sharpen that saw?' you inquire. 'I'm sure it would go a lot faster.'
'I don't have time to sharpen the saw,' then man says emphatically. 'I'm too busy sawing!'"
"Principles are natural laws that are external to us and that ultimately control the consequences of our actions. Values are internal and subjective and represent that which we feel strongest about in guiding our behavior."
Effective People
Thursday, June 19, 2008 5:07:35 AM (Mountain Standard Time, UTC-07:00)
I'm currently reading...
I came across a paragraph that stuck out for me, and just wanted to share it:
"If you don't let a teacher know at what level you are -- by asking a questions, or revealing your ignorance - you will not learn or grow. You cannot pretend for long, for you will eventually be found out. Admission of ignorance is often the first step in our education."
This was immediately followed by the next powerful statement.
"Thoreau taught, 'How can we remember our ignorance, which our growth requires, when we are using our knowledge all the time?'"
Note to self, "be more ignorant..." *giggle* Have a great day!
Studying Object Oriented Programming
Friday, May 30, 2008 8:02:04 AM (Mountain Standard Time, UTC-07:00)
I'm currently reading...
 | Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition) by Craig Larman Read more about this book... |
(I'm actually reading the 2nd edition)
This is a good book. It started off really boring... really boring! I picked up this book as an introduction to object oriented programming, and it started off with a lot of talk on UML, documentation and the Rational Unified Process. But then I got to chapter 16... "GRASP: Designing Objects with Responsibilities".
Here's an excerpt that I enjoyed!
"Perhaps the most common mistake when creating a domain model is to represent something as an attribute when it should have been a concept. A rule of thumb to help prevent this mistake is:
If we do not think of some conceptual class X as a number or text in the real world, X is probably a conceptual class, not an attribute."
Here's a definition for a Domain Model...
"The Domain Model provides a visual dictionary of the domain vocabulary and concepts from which to draw inspiration for the naming of some things in the software design."
Chapter 16 is great so far, it talks about how to decompose responsibilities for objects using an acronym (I'm not a fan of acronyms) called GRASP. GRASP stands for General Responsibility Assignment Software Patterns.
Craig goes on to talk about the five different patterns of GRASP. They are:
- Information Expert: the class that has the information necessary to fulfill the responsibility.
- Creator: a class that has the responsibility to create an instance of another class.
- High Cohesion: increase the measure of how strongly related and focused the responsibilities of an element are.
- Low Coupling: decrease the amount a class is connected to, has knowledge of, or relies on other elements.
- Controller: a class with the responsibility of receiving or handling a system event message.
Some More Refactorings...
Thursday, May 22, 2008 8:22:51 PM (Mountain Standard Time, UTC-07:00)
A great book to read is...
 | Refactoring: Improving the Design of Existing Code (The Addison-Wesley Object Technology Series) by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts Read more about this title... |
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
"The first time you do something, you just do it. The second time you something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor."
Introduce Local Extension: A server class you are using needs several additional methods, but you can't modify the class.
Create a new class that contains these extra methods. Make this extension class a subclass or a wrapper of the original.
E.g From this...
public interface IController{
void Execute();
}
public class Controller : IController {
protected void RenderView(string name, object data){
//... note that this is a protected method
}
public void Execute(){
//...
}
}
To this...
public interface IViewRenderer{
void Render<T>(string name, T data);
}
public class LocalExtensionController : Controller, IViewRenderer {
public void Render<T>(string name, T data){
RenderView(name, data);
}
}
Replace Conditional with Polymorphism: You have a conditional that chooses different behavior depending on the type of an object.
Move each leg of the conditional to an overriding method in a subclass. Make the original method abstract.
E.g From this...
public class Bird{
public Bird(BirdType type){
_type = type;
}
public double GetSpeed(){
switch(_type){
case BirdType.EUROPEAN:
return 5;
case BirdType.AFRICAN:
return 10;
case BirdType.NORWEGIAN_BLUE:
return 20;
}
throw new ArgumentException();
}
private BirdType _type;
}
public enum BirdType{
EUROPEAN,
AFRICAN,
NORWEGIAN_BLUE
}
To this...
public interface IBird{
double GetSpeed();
}
public class EuropeanBird : IBird {
public double GetSpeed(){
return 5;
}
}
public class AfricanBird : IBird {
public double GetSpeed() {
return 10;
}
}
public class NorwegianBlueBird : IBird {
public double GetSpeed() {
return 20;
}
}
Got Tests?
Wednesday, May 21, 2008 11:30:53 AM (Mountain Standard Time, UTC-07:00)
A couple of months ago I finished reading...
This was a thick book, that discusses unit test smells, unit test refactorings, unit test patterns... and just about anything else related to unit testing. Here's a little of what I've learned from this book...
Defect Localization
"Mistakes happen! Of course, some mistakes are much more expensive to prevent than to fix. Suppose a bug does slip through somehow and shows up in the Integration Build. If our unit test are fairly small (i.e., we test only a single behavior in each one), we should be able to pinpoint the bug quickly based on which test fails. This specificity is one of the major advantages that unit tests enjoy over customer tests. The customer tests tell us that some behavior expected by the customer isn't working; the unit tests tell us why. We call this phenomenon Defect Localization. If a customer test fails but no unit tests fail, it indicates a Missing Unit Test."
Tests as Documentation
"Without automated tests, we would need to pore over the SUT code trying to answer the question, 'What should be the result if ...?' With automated tests, we simply use the corresponding Tests as Documentation; they tell us what the result should be. If we want to know how the system does something, we can turn on the debugger, run the test, and single-step through the code to see how it works. In this sense, the automated tests act as a form of documentation for the SUT."
"When it is not important for something to be seen in the test method, it is important that it not be seen in the test method!"
Test Doubles
A test double is any object or component that we install in place of the real component for the express purpose of running a test. Depending on the reason why we are using it, a Test Double can behave in one of four ways.
- Dummy Object: a object that is passed to the SUT as an argument but is never actually used.
- Test Stub: an object that replaces a real component on that the SUT depends on so that different inputs can by applied against the SUT.
- Test Spy: an object that can act as an observation point for the indirect outputs of the SUT.
- Mock Object: an object that replaces a real component that the SUT depends on to test the and verify indirect outputs.
- Fake Object: an object that replaces the functionality of the real SUT dependency with an alternate implementation that provides the same functionality.
Strict vs Loose
Mock objects come in two basic flavors:
- Strict Mock: fails the test if incorrect calls are received.
- Loose (lenient) Mock: fails if expected calls are not received, but is lenient if additional calls are received.
Need-Driven Development
"This 'outside-in' approach to writing and testing software combines the conceptual elegance of the traditional 'top-down' approach to writing code with modern TDD techniques supported by Mock Objects. It allows us to build and test the software layer by layer, starting at the outermost layer before we have implemented the lower layers."
Test Smells
"Developers Not Writing Tests may be caused by an overly aggressive development schedule, supervisors who tell developers not to 'waste time writing tests,' or developers who do not have the skills to write tests. Other potential causes might include an imposed design that is not conducive to testing or a test environment that leads to Fragile Tests. Finally, this problem could result from Lost Tests - tests that exist but are not included in the All Tests Suite used by developers during check-in or by the automated build tool."
"Another productivity-sapping smell is Frequent Debugging. Automated unit tests should obviate the need to use a debugger in all but rare cases, because the set of tests that are failing should make it obvious why the failure is occurring. Frequent Debugging is a sign that the unit tests are lacking in coverage or are trying to test to much functionality at once."
Fragile Test: "A test fails to compile or run when the SUT is changed in ways that do not affect the part the is exercising... Fragile tests increase the cost of test maintenance by forcing us to visit many more tests each time we modify the functionality of the system or the fixture."
This headache is typical if you're working with strict mock objects. I experienced this pain when working on a project using NMock. I couldn't find a clean separation between strict and loose mocks using NMock. There was only the concept of Strict Mocks and Stubs.
Slow Tests: "The tests take too long to run... They reduce the productivity of the person running the test. Instead, the developers wait until the next coffee break or another interruption before running them. Or, whenever they run the tests, they walk around and chat with other team members..."
The main disadvantages of using Fit are described here:
- The test scenarios need to be very well understood before we can build the Fit Fixture. We then need to translate each test's logic into a tabular representation; this isn't always a good fit.
- The tests need to employ the same SUT interaction logic in each test. To run several different styles of tests, we would probably have to build one or more different fixtures for each style of test. Building a new fixture is typically more complex than writing a few Test Methods.
- Fit tests aren't normally integrated into developers' regression tests that are run via xUnit. Instead, these test must be run separately - which introduces the possibility that they will not be run at each check-in.
Pull
"A concept from lean manufacturing that states that things should be produced only once a real demand for them exists. In a 'pull system,' upstream assembly lines produce only enough products to replace the items withdrawn from the pool that buffers them from the downstream assembly lines. In software development, this idea can be translated as follows: 'We should only write methods that have already been called by other software and only handle those cases that the other software actually needs.' This approach avoids speculation and the writing of unnecessary software, which is one of software development's key forms of inventory (which is considered waste in lean systems)."
Spikin' Ruby on Rails
Wednesday, May 21, 2008 8:22:47 AM (Mountain Standard Time, UTC-07:00)
I'm just about finished reading...
 | Agile Web Development with Rails, 2nd Edition by Dave Thomas, David Hansson, Leon Breedt, Mike Clark, James Duncan Davidson, Justin Gehtland, Andreas Schwarz Read more about this book... |
This book focuses on the Ruby on Rails framework for developing web applications. It touches very lightly on the Ruby language itself, but mostly talks about things like Model View Controller, Active Record, Action Pack and how it's implemented in RoR's. The book starts off with a light primer on what MVC is, which I enjoyed, then moves on to how to install RoR, then jumps right into building a quick application using RoR. I enjoyed the discussion Testing and the concept of Migrations.
Before jumping right in to chapter one I quickly read through the first Appendix titled "Introduction to Ruby", which helped a little bit, but I probably would have done better if I had first read a book just on the Ruby language. I think I would have found it more interesting as well. There were times in the book where it got so deep into the nitty gritty details of the RoR framework that I just completely lost interest. I choose to read this book to get some high level ideas, but I wasn't as interested in the tiny details of the framework. There's tonnes of great ideas in this book, that I recognize being adopted quite a bit in the .NET community. Migrations and MVC being a couple of my favorites.
Here's a few excerpts that I enjoyed from this book...
Convention over Configuration
"Rails gives you lots of opportunities to override this basic workflow ... As it stands, our story illustrates convention over configuration, one of the fundamental parts of the philosophy of Rails. By providing convenient defaults and by applying certain conventions, Rails applications are typically written using little or no external configuration - things just knit themselves together in a natural way."
Migrations
"Over the years, developers have come up with ways of dealing with this issue. One scheme is to keep the Data Definition Language (DDL) statements that define the schema in source form under version control. Whenever you change the schema, you edit this file to reflect the changes. You then drop your development database and re-create the schema from scratch by applying your DDL. If you need to roll back a week, the application code and the DDL that you check out from the version control system are in step: when you re-create the schema from the DDL, your database will have gone back in time.
Except... because you drop the database every time you apply the DDL, you lose any data in your development database. Wouldn't it be more convenient to be able to apply only those changes that are necessary to move a database from version X to version Y? this is exactly what Rails migrations let you do."
E.g. 001_create_products.rb
class CreateProducts < ActiveRecord:Migration
def self.up
create_table :products do |t|
t.column :title, :string
t.column :description :text
t.column :image_url :string
end
end
def self.down
drop_table :products
end
end
Pragmatic Ajax-ification
"In the old days, browsers were treated as really dumb devices. When you wrote a browser-based application, you'd send stuff down to the browser and then forget about that session. At some point, the user would fill in some form fields or click a hyperlink, and your application would get woken up by an incoming request. It would render a complete page back to the user, and the whole tedious process would start afresh...
Whenever you work with AJAX, it's good to start with the non-AJAX version of the application and then gradually introduce AJAX features."
No REST For The Wicked
"REST stands for REpresentational State Transfer, which is basically meaningless. What it really means is that you use HTTP verbs (GET, POST, DELETE, and so on) to send requests and responses between applications."
Performance Testing
"Testing isn't just about whether something does what it should. We might also want to know whether it does it fast enough.
Before we get to deep into this, here's a warning. Most applications perform just fine most of the time, and when they do start to get slow, it's often in ways we would never have anticipated. For this reason, it's normally a bad idea to focus on performance early in development. Instead, we recommend using performance testing in two scenarios, both late in the development process."
Statement Modifiers
"Ruby statement modifiers are a useful shortcut if the body of an if or while statement is just a single expression. Simply write the expression, followed by if or while and the condition."
The following is valid Ruby syntax:
puts "Danger, Will Robinson" if radiation > 3000
I would love to express the following C# syntax....
public void AddLicense(ILicense license){
if(license.IsValid()){
licenseRepository.Add(license);
}
}
Like this...
public void AddLicense(ILicense license){
licenseRepository.Add(license).If(license.IsValid());
}
Stop Optimizing
Wednesday, April 23, 2008 8:06:55 AM (Mountain Standard Time, UTC-07:00)
I'm still reading...
Here's a few quotes from the book, that I found interesting:
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." - Donald E. Knuth
"Don't sacrifice sound architectural principles for performance. Strive to write good programs rather than fast ones. If a good program is not fast enough, its architecture will allow it to be optimized. Good programs embody the principle of information hiding: Where possible, they localize design decisions within individual modules, so individual decisions can be changed without affecting the remainder of the system."
A typical example of pre-mature optimization is thinking about "database calls" when working up in a UI layer. These are two completely separate architectural layers and should be developed without "optimization" constraints in mind.
For example:
"...we have to check if its a post back, to make sure we don't make another database hit. If we retrieve the contents of the page each time the page is requested that's going to be another database hit."
Relax... there are lots of techniques (lazy loading, identity map...) to improve performance if it's an issue. But optimizing the UI for database performance is weak, and will more than likely cause you to build a crippled UI layer before even hitting the lower layers.
"Often attempted optimizations have no measurable effect on performance; sometimes they make it worse."
If we take the above example, if you're constantly "optimizing" for database performance be weary of what it's costing you. E.g... ViewState, extra conditional code that's sooo freakin' impossible to understand, that no dev wants to come back and touch that code.
It can be pointless to try to find solutions to a problem that doesn't exist.
Inherently Undesirable
Wednesday, April 16, 2008 12:14:11 PM (Mountain Standard Time, UTC-07:00)
I'm currently reading...
I thought I would share en excerpt that I read this morning on the bus... it's about my favorite topic: Implementation Inheritance.
"Inheritance is a powerful way to achieve code reuse, but it is not always the best tool for the job. Used inappropriately, it leads to fragile software. It is safe to use inheritance within a package, where the subclass and the superclass implementation are under the control of the same programmers. It is also safe to use inheritance when extending classes specifically designed and documented for extension. Inheriting from ordinary concrete classes across package boundaries, however, is dangerous. As a reminder, this book uses the word 'inheritance' to mean 'implementation inheritance' (when one class extends another). The problems discussed in this item do not apply to interface inheritance (when a class implements an interface or where one interface extends another)."
"Unlike method invocation, inheritance breaks encapsulation. In other words, a subclass depends on the implementation details of its superclass for its proper function."
Sharpening My C
Saturday, March 15, 2008 1:35:43 PM (Mountain Standard Time, UTC-07:00)
I recently finished reading...
My desire to read this book was to understand what new language features C# 3.0 brings to the table. This book started to explain the C# language right from the very beginning up until now. So some of it was a great refresher and some of it was quite boring. It not only covers the new language features but covers several areas of the framework class libraries and new lib's that came with the .NET 3.5 stack.
I was hoping to find my coverage on the new language features to see different usages for things like extension methods and lambda's to try to get a sense for what I like and don't like. So far I'm not really a fan of the new query comprehension syntax. It's to SQL-ish for me... I prefer working directly against methods. But I might have to give it some time... enough ranting here's some of the things I've learned.
Lambda Expressions
There's tonnes, and tonnes of discussion on this topic right now. I love how it's so much cleaner, and less verbose then anonymous delegates, but I see potential room for abuse. IMHO seeing lambda's tossed around all over your code base is no better then over using anonymous delegates. I love the new ideas that lambda's bring though...
"A lambda expression is an unnamed method written in place of a delegate instance. The compiler immediately converts the lambda expression to either:
- A delegate instance.
- An expression tree, of type Expression<T>, representing the code inside the lambda expression in a traversable object model. This allows the lambda expression to be interpreted later at runtime..." - C# 3.0 in a Nutshell
I love the idea of building up an expression tree of delegates that chain together to solve an equation. One of the ideas I'm working on is understanding how to leverage an expression tree of lambdas to solve trivial mathematical equations. Then possible traversing through the structure with a visitor to build out a display friendly version of the equation.
WPF
"The benefits of WPF are as follows:
- It supports sophisticated graphics, such as arbitrary transformations, 3D rendering, and true transparency.
- Its primary measurement unit is not pixel-based, so applications display correctly in any DPI
- It has extensive dynamic layout support, which means you can localize any application without danger of elements overlapping.
- Rendering uses DirectX and is fast, taking good advantage of graphics hardware acceleration.
- User interfaces can be described declaratively in XAML files that can be maintained independently of the "code-behind" files - this helps to separate appearance from functionality." - C# 3.0 in a Nutshell
WCF
"WCF is the communication infrastructure new to Framework 3.0. WCF is flexible and configurable enough to make both of its predecessors - Remoting and (.ASMX) Web Services - mostly redundant." - C# 3.0 in a Nutshell
XML
"If you're dealing with data that's originated from or destined for an XML file, XmlConvert (the System.Xml namespace) provides the most suitable methods for formatting and parsing. The methods in XmlConvert handle the nuances of XML formatting without needing special format strings." - C# 3.0 in a Nutshell
Iterators
"The compiler, upon parsing the yield return statement, writes 'behind the scenes,' a hidden nested enumerator class, and then refactors GetEnumerator to instantiate and return that class. Iterators are powerful and simple" - C# 3.0 in a Nutshell
Hash Tables
"Its underlying hashtable works by converting each element' key into an integer hashcode - a pseudo unique value - and then applying an algorithm to convert the hashcode into a hash key. This hash key is used internally to determine which 'bucket' an entry belongs to. If the bucket contains more than one value, a linear search is performed on the bucket. A hashtable typically starts out maintaining a 1:1 ration of buckets to values, meaning that each bucket contains only one value. However, as more items are added to the hashtable, the load factor dynamically increases, in a manner designed to optimize insertion and retrieval performance as well as memory requirements." - C# 3.0 in a Nutshell
Serialization
"The data contract serializer is the newest and the most versatile of the three serializatoin engines and is used by WCF. The serializer is particularly strong in two scenarios:
- When exchanging information through standards-compliant messaging protocols
- When you need high-version tolerance plus the option of preserving object references."
C# 3.0 in a Nutshell
Threading
"A Mutex is like a C# lock, but it can work across multiple processes. In other words, Mutex can be computer-wide as well as application-wide" - C# 3.0 in a Nutshell
"A Semaphore is like a nightclub: it has a certain capacity, enforced by a bouncer. Once it's full, no more people can enter and a queue build up outside. Then, for each person that leaves, one person enters from the head of the queue." - C# 3.0 in a Nutshell
"The Thread class provides GetData and SetData methods for storing nontransient isolated data in 'slots' whose values persist between method calls." - C# 3.0 in a Nutshell
Hangin' Out With The Gang Of Four
Saturday, February 23, 2008 7:35:34 PM (Mountain Standard Time, UTC-07:00)
I just finished reading...
 | Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series) by Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides Read more about this title... |
It's about time I read this book... This catalog contains 23 patterns with examples in C++. I enjoyed reading this book. I found at times that my mind started to drift off, but then there were moments when I would forget where I was and miss my bus stop. (Ok one moment!)
I enjoyed reading the discussion on OO more then anything else in this book. The examples are a little dated but for it's time the catalog is awesome. Although I've been wanting to read this book for a while I preferred "Head First Design Patterns", mostly because it was easy to read. (I call it the comic book for dev's)
As usual, here are some quotes from the book that I really enjoyed.
"When an abstraction can have one of several possible implementations, the usual way to accommodate them is to use inheritance. An abstract class defines the interface to the abstraction, and concrete subclasses implement it in different ways. But this approach isn't always flexible enough. Inheritance binds an implementation to the abstraction permanently, which makes it difficult to modify, extend and reuse abstractions and implementations independently."
"Studies of expert programmers for conventional languages have shown that knowledge and experience isn't organized simply around syntax but in larger conceptual structures such as algorithms, data structures and idioms, and plans for fulfilling a particular goal. Designers probably don't think about the notation they're using for recording the design as much as they try to match the current design situation against plans, algorithms, data structures, and idioms they have learned in the past."
"These design patterns can also make you a better designer. They provide solutions to common problems. If you work with object-oriented systems long enough, you'll probably learn these design patters on your own. But reading the book will help you learn them much faster. Learning these patterns will help a novice act more like an expert."
"To continue to evolve, the software must be reorganized in a process known as refactoring. This is the phase in which frameworks often emerge. Refactoring involves tearing apart classes into special- and general-purpose components, moving operations up or down the class hierarchy, and rationalizing the interfaces of classes. This consolidation phase produces many new kinds of objects, often by decomposing existing objects and using object composition instead of inheritance. Hence black-box reuse replaces white-box reuse. The continual need to satisfy more requirements along with the need for more reuse propels object-oriented software through repeated phases of expansion and consolidation - expansion as new requirements are satisfied, and consolidation as the software becomes more general."
Replace Enum With Flyweights
Saturday, February 23, 2008 11:08:21 AM (Mountain Standard Time, UTC-07:00)
I've got a beef with enums. When I see them, I cringe... which is quite different from my days in C, where I couldn't live without enums and structs. That's another story...
"Flyweight: Use sharing to support large numbers of fine-grained objects efficiently" - Design Patterns
 | Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series) by Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides Read more about this title... |
Why do some of us quickly jump to enums? In procedural languages it makes sense. It's giving a type code a human readable meaning. So instead of having to stare at type code 1, everywhere you can use State.Acknowledgement, which is a lot easier to understand ... what does 1 mean again?
But in an OO language, I feel dirty when I see enums. The argument of using it for bitwise operations and the Flags attribute is weak. Create a composite!
[Flags]
public enum Digits {
Zero = 0x00,
One = 0x01,
Two = 0x02,
Three = 0x03,
Four = 0x04,
Five = 0x05,
Six = 0x06,
Seven = 0x07,
Eight = 0x08,
Nine = 0x09
}
[Test]
public void Should_be_equal_to_2_digits() {
Digits digits = Digits.Six | Digits.One;
Assert.IsTrue( Digits.Six == (digits & Digits.Six) );
Assert.IsTrue( Digits.One == (digits & Digits.One) );
}
Weak... do you really want to use a bitwise & to check if a certain digit is enabled. I don't. I'm going to use the following 2 tests to squash the enum into a first class component, with some smarts to it.
[Test]
public void should_be_able_to_add_a_single_digit() {
INumberBuilder builder = CreateSUT( );
builder.Add( Digits.One );
Assert.AreEqual( new Number( 1 ), builder.Build( ) );
}
[Test]
public void should_be_able_to_form_a_number_with_more_than_one_digit() {
INumberBuilder builder = CreateSUT( );
builder.Add( Digits.One );
builder.Add( Digits.Nine );
Assert.AreEqual( new Number( 19 ), builder.Build( ) );
}
My current NumberBuilder implementation looks like this (it sucks but it works):
public class NumberBuilder : INumberBuilder {
public void Add( Digits digit ) {
numberBeingBuilt += Convert.ToString( Convert.ToInt32( digit ) );
}
public INumber Build() {
return new Number( Convert.ToInt32( numberBeingBuilt ) );
}
private string numberBeingBuilt;
}
I'm going to start off by creating some Flyweights.
public class Digits {
public static readonly IDigit Eight = new Digit( 8 );
public static readonly IDigit Five = new Digit( 5 );
public static readonly IDigit Four = new Digit( 4 );
public static readonly IDigit Nine = new Digit( 9 );
public static readonly IDigit One = new Digit( 1 );
public static readonly IDigit Seven = new Digit( 7 );
public static readonly IDigit Six = new Digit( 6 );
public static readonly IDigit Three = new Digit( 3 );
public static readonly IDigit Two = new Digit( 2 );
public static readonly IDigit Zero = new Digit( 0 );
public class Digit : IDigit {
public Digit( int digitToRepresent ) {
_digitToRepresent = digitToRepresent;
}
public override string ToString() {
return _digitToRepresent.ToString( );
}
private readonly int _digitToRepresent;
}
}
My compiler is telling me that the Add method on my builder currently accepts a parameter of type "Digits", so I'm going to change the signature to accept a parameter of type IDigit.
public interface INumberBuilder {
void Add( Digits digit );
INumber Build();
}
To...
public interface INumberBuilder {
void Add( IDigit digit );
INumber Build();
}
Let's update the NumberBuilder implementation to:
public class NumberBuilder : INumberBuilder {
public NumberBuilder() {
_digitsOfNumberBeingBuilt = new List< IDigit >( );
}
public void Add( IDigit digit ) {
_digitsOfNumberBeingBuilt.Add( digit );
}
public INumber Build() {
return new Number( CreateIntegerFrom( _digitsOfNumberBeingBuilt ) );
}
private int CreateIntegerFrom( IEnumerable< IDigit > digitsOfNumberBeingBuilt ) {
StringBuilder builder = new StringBuilder( );
foreach ( IDigit digit in digitsOfNumberBeingBuilt ) {
builder.Append( digit );
}
return Convert.ToInt32( builder.ToString( ) );
}
private IList< IDigit > _digitsOfNumberBeingBuilt;
}
I run the tests and they pass, sweet. But I'm not happy with the current implementation, so I look for other potential refactorings. I decide to forward the digit to append right to the number, the number can take care of how to append the digit, rather then having the builder doing so. The builder now looks like:
public class NumberBuilder : INumberBuilder {
public NumberBuilder() {
_numberBeingBuilt = new Number( 0 );
}
public void Append( IDigit digit ) {
_numberBeingBuilt = _numberBeingBuilt.Append( digit );
}
public INumber Build() {
return _numberBeingBuilt;
}
private INumber _numberBeingBuilt;
}
And Number looks like:
public class Number : INumber, IEquatable< Number > {
public Number() : this( 0 ) {}
public Number( int numberToRepresent ) {
_numberToRepresent = numberToRepresent;
}
public INumber Append( IDigit digit ) {
return new Number( ( _numberToRepresent*10 ) + digit.Value( ) );
}
public bool Equals( Number number ) {
if ( number == null ) {
return false;
}
return _numberToRepresent == number._numberToRepresent;
}
public override string ToString() {
return _numberToRepresent.ToString( );
}
public override bool Equals( object obj ) {
if ( ReferenceEquals( this, obj ) ) {
return true;
}
return Equals( obj as Number );
}
public override int GetHashCode() {
return _numberToRepresent;
}
private readonly int _numberToRepresent;
}
To wrap this up, Number aggregates digits, the enum got dropped and was replaced by a class. There's still more refactorings that can occur, but the point is that a full blown component is much easier to extend then an enum...
For more info check out "Replace Type Code with Class" from...
 |
Refactoring: Improving the Design of Existing Code (The Addison-Wesley Object Technology Series)
by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts
Read more about this title... |
Soure:
Continuous Improvement
Monday, February 18, 2008 5:06:47 PM (Mountain Standard Time, UTC-07:00)
This month I read...
 | Refactoring: Improving the Design of Existing Code (The Addison-Wesley Object Technology Series) by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts Read more about this title... |
This book is awesome and a must read for anyone who enjoys the art of refactoring as much as I do. The examples are crystal clear and the way the refactorings are done step by step makes it so much more understandable.
Here are a few excerpts that I enjoyed from this book.
"The problem with copying and pasting code comes when you have to change it later. If you are writing a program that you don't expect to change, then cut and paste is fine. If the program is long lived and likely to change, then cut and paste is a menace."
I've got to agree and disagree with the above statement. I think anytime you find yourself copying and pasting is a clear sign of duplication which should be improved. Removing duplication should be something we all strive for, and remember that inheritance is not the only way to remove duplication. Proper object composition, delegation and generics are all great ways to remove duplicate code.
Replace conditional with Polymorphism has to be by far one of my favorite refactorings. If you're seeing if-else statements scattered throughout your code base that's a smell. Switch's are no better... (booo switches...)
"Is renaming worth the effort? Absolutely. Good code should communicate what it is doing clearly, and variable names are a key to clear code. Never be afraid to change the names of things to improve clarity."
Amen, brother! Thank goodness for tools like Resharper and Rhino.Mocks. On my current project we're using NMock2 and I got burned several times doing a Rename Method because of the string literals used in NMock tests... My advice is just use Rhino Mocks... please... for my sake!
"You write code that tells the computer what to do, and it responds by doing exactly what you tell it. In time you close the gap between what you want it to do and what you tell it to do. Programming in this mode is all about saying exactly what you want. But there is another use of your source code. Someone will try to read your code in a few months' time to make some changes. We easily forget that extra user of the code, yet that user is actually the most important."
"The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor."
I often heard the term "smell" used as a way to describe something funky in a code base or team but I had no idea where the term came from... until know!
"If it stinks, change it." - Gradma Beck, discussing child-rearing philosophy
The chapter on code smells is awesome, it's offers a catalog of code smells like:
- Duplicate Code
- Long Methods
- Large Classes
- Long Parameter Lists
- Divergent Changes
- Shotgun Surgery
- Feature Envy
- Data Clumps
- Primitive Obsession
- Switch Statements
- Parallel Inheritance Hierarchies
- Lazy Class
- Speculative Generality - "Oh, I think we need the ability to do this kind of thing someday."
- Temporary Fields
- Message Chains
- Middle Man
- Inappropriate Intimacy
- Alternative Classes with Different Interfaces
- Incomplete Library Classes
- Data Classes
- Refused Bequest - "Subclasses get to inherit the methods and data of their parents. But what if they don't want or need what they are given?"
- Comments
If you only read one chapter in this book, I suggest Chapter 3. "Bad Smells in Code". I really like how Resharper uses the same refactoring names as those mentioned in this book. Anyway's, what are you waiting for go read this book.
Hacking & Painting
Friday, February 01, 2008 4:06:01 PM (Mountain Standard Time, UTC-07:00)
This month I read...
This was not what I expected, but then again I wasn't really sure what I expected. But I liked it, the first chapter kind of caught me off guard, but some of the analogies and comparisons make a lot of sense. You can tell that Mr. Paul Graham sure is a thinker!
Here are a few excerpts from the book that I found enjoyable:
"Big companies win by sucking less than other big companies."
"You learn to paint mostly by doing it. Ditto for hacking. Most hackers don't learn to hack by taking college courses in programming. They learn by writing programs of their own at age thirteen. Even in college classes, you learn to hack mostly by hacking."
"Maybe it would be good for hackers to act more like painters, and regularly start over from scratch, instead of continuing to work for years on one project, and trying to incorporate all their later ideas as revisions."
"If I could get people to remember just one quote about programming, it would be the one at the beginning of Structure and Interpretation of Computer Programs.
Programs should be written for people to read, and only incidentally for machines to execute."
"When you catch bugs early, you also get fewer compound bugs. Compound bugs are two separate bugs that interact: you trip going downstairs, and when you reach for the handrail it comes off in your hand."
"Mistakes are natural. Instead of treating them as disasters, make them easy to acknowledge and easy to fix. Leonardo more or less invented the sketch, as a way to make drawing bear a greater weight of exploration. Open source software has fewer bugs because it admits the possibility of bugs."
"Of all tyrannies, a tyranny exercised for the good of its victims may be the most oppressive. - C.S. Lewis"
"One of my first drawing teachers told me: if you're bored when you're drawing something, the drawing will look boring."
"Indeed, there is even a saying among painters: 'A painting is never finished. You just stop working on it.'"
There is so much great content in this book that just provokes thought. I highly encourage you to go check it out, it's definitely worth reading and re-reading.
XP What?
Friday, February 01, 2008 4:01:41 PM (Mountain Standard Time, UTC-07:00)
One of the books I've read this month is....
I really enjoyed reading this book. It paints a picture of what an ideal XP team can look like and talks about the principals, practices and values of XP. I'd like to share some excerpts from the book that really stuck out and hand an impact on me.
"If you have six weeks to get a project done, the only thing you can control is your own behavior. Will you get six weeks' worth of work done or less? you can't control others' expectations. You can tell them what you know about the project so their expectations have a chance of matching reality. My terror of deadlines vanished when I learned this lesson. It's not my job to "manage" someone else's expectations. It's their job to manage their own expectations. It's my job to do my best and to communicate clearly."
One of the things I learned about myself is that I hate being late. This isn't a great trait to have in the world of software development. When I'm handed a deadline I become so eager to meet it that in the process of racing to the deadline quality is compromised. I can't control deadlines or others expectations but I can control my own behavior and if I work consistently as hard as I can without letting go of quality.
"I chose practices for XP because they meet both business and personal needs. There are other human needs; such as rest, exercise, and socialization; that don't need to be met in the work environment. Time away from the team gives each individual more energy and perspective to bring back to the team. Limiting work hours allows time for these other human needs and enhances each person's contributions while he is with the team."
It sucks how XP and Agile have become buzzwords in the industry that mean more to the marketing department then to the software developers. I've said it before and I'll say it again...
"You aren't doing Agile. YOU ARE AGILE!"
"Part of the challenge of team software development is balancing the needs of the individual with the needs of the team. The team's needs may meet your own long-term individual goals, so are worth some amount of sacrifice. Always sacrificing your own needs for the team's doesn't work. If I need privacy, I am responsible for find a ways to get my need met in a way that doesn't hurt the team. The magic of great teams is that after the team members develop trust they find that they are free to be more themselves as a result of their work together."
You've got to sacrifice something, regardless of context you're talking about, in order to succeed. What's important is deciding on what you're willing to sacrifice in order to get closer to your end goals. I have found that pushing the people outside of their comfort zone a little bit not only helped me in growing but also the team as a whole. I also learned that it's important to slow down and reflect. The up and down rhythm of an XP team is balanced by the different members of a team, and with trust it's much easier to maintain that balance.
E.G. Team member A might be a hardcore, heads down, must punch out code as efficiently as possible. Team member B may be more of a let's take it a little slower and sit back and think about the problem at hand kind of guy. With trust the two team members will be able to develop a rhythm that keeps the project going at a sustainable pace without sacrificing quality.
"I trust two metrics to measure the health of XP teams. The first is the number of defects found after development. An XP team should have dramatically fewer defects in its first deployment and make rapid progress from there. Some XP teams that have been on the path of improvement for several years see only a handful of defects per year. No defect is acceptable; each is an opportunity for the team to learn and improve."
Test-driven development/design rather then design in your head driven code. The test is a clear statement of truth. It documents the design that would otherwise be locked up in your head and is very black of white about whether or not the subject under test satisfies the test specification or behavior that is expected. If the team is not disciplined even the best of the best XP teams can forget about the principals behind the practices, and stop following the practices. One of the most important things about unit tests is the early feedback. I want to know as soon as possible when a component in the system is not behaving as expected. By waiting for QA to pick out bugs, then log a bug, then assign a developer to look at the bug does not deliver early feedback, I consider this waste! It's a vicious cycle that can be reduced greatly.
"The problem with reviews is that most reviews and raises are based on individual goals and achievements, but XP focuses on team performance. If a programmer spends half of his time pairing with others, how can you evaluate his individual performance? How much incentive does he have to help others if he will be evaluated on individual performance?"
Out of all the chapters in this book I think chapter 3 is my favorite. It's titled "Values, Principles, and Practices", and to me it speaks the loudest of what is XP and why would we want to consider using it as a methodology for building and delivering software.
I highly recommend this book!
Programming .NET Components
Tuesday, December 18, 2007 3:08:36 PM (Mountain Standard Time, UTC-07:00)
I just finished reading...
This was a pretty sweet read, I think this along with CLR via C# work well with one another. This book goes into a little more depth on threading and issues with concurrency. As well the chapters on remoting are long and full of tonnes of information. Way more then this guy could absorb after an initial read. I have so much to learn about remoting.
This book starts right fr gooom the beginning. What is a component?
".. a component is a .NET class. For example, this is a .NET component:
public class MyClass {
public string GetMessage() {
return "Hello";
}
}"
I think one of my favorite chapters in this book was on "Interface-Based Programming" and talks about the importance of separating interface from implementation.
"Interface Factoring: When you factor an interface, always think in terms of reusable elements. In a component-oriented application, the basic unit of reuse is the interface."
"... proper interface-factoring results in more specialized, loosely coupled, fine-tuned, and reusable interfaces, and subsequently, those benefits apply to the system as well. In general, interface factoring results in interfaces with fewer members."
Another benefit, in my opinion, to interfaces is for learning a system. By checking out the interfaces defined in a subsystem you can get a flavor for what services are offered by each component. It's much easier to look at the interface contract to see the operations it performs then having to scan through concrete types. I equate this to header files in C. If I look at the header file I can see what operations are available from each library. I don't need to know how it was implemented, just where to find it.
"Windows Forms base classes make extensive use of ISynchronizeInvoke. The control class relies on underlying Windows messages and a message-processing loop (the message pump) to process them. The message loop must have thread affinity, because messages to a window are delivered only to the thread that created that window."
Juval shares many different helper classes for getting around some of the more trickier areas of .NET development, like threading, events, remoting and even how to use a mutex to only allow a single instance of a class to run.
internal static class Program {
[STAThread]
private static void Main() {
if ( IsFirstInstance( ) ) {
Application.ApplicationExit += OnApplicationExit( );
Application.Run( new Form1( ) );
}
}
private static bool IsFirstInstance() {
_mutex = new Mutex( false, Assembly.GetEntryAssembly( ).FullName );
bool owned = _mutex.WaitOne( TimeSpan.Zero, false );
return owned;
}
private static EventHandler OnApplicationExit() {
return delegate {
_mutex.ReleaseMutex( );
_mutex.Close( );
};
}
private static Mutex _mutex;
}
The Event Aggregator
Tuesday, December 18, 2007 2:26:11 PM (Mountain Standard Time, UTC-07:00)
I'd like to talk to you for a moment about my man The Event Aggregator. (Homeboy's been tossin' events for years!)
Martin Fowler defines the Event Aggregator as:
"Channel events from multiple objects into a single object to simplify registration for clients." - Martin Fowler
But he's so much more then that! This pattern comes in handy in state-ful environments, so.. hello WinForms/WPF. Sorry ASP.NET!
What this guy does is creates a single channel to find out what's going on and to raise events. Through the event aggregator you can subscribe to known events in the system as well as raise known events in the system.
Some examples for system wide events are Save, Loading, Shutdown. You can also create concepts for layer specific event aggregators that target certain layers of a system. For example UI only.
public class ApplicationEvents {
private static readonly IEventAggregator aggregator;
public static readonly IEvent Save = new EventRaiser( "Save" );
public static readonly IEvent Loading = new EventRaiser( "Loading" );
static ApplicationEvents( ) {
aggregator = new EventAggregator( );
aggregator.Register( Save );
aggregator.Register( Loading );
}
public static void Raise( IEvent eventToRaise ) {
aggregator.RaiseEvent( eventToRaise );
}
public static void SubscribeTo( IEvent eventToSubscribeTo, EventHandler handler ) {
aggregator.AddHandler( eventToSubscribeTo.Name, handler );
}
}
The ApplicationEvents becomes the central point for raising and subscribing to known application wide events. Type can be coupled to the aggregator but not to each other.
Let's start with the concept of a named event. An event is really nothing more then a delegate. In .NET there are 2 delegate signatures that are used for all events. The generic and non generic version of the EventHandler delegate. (Read More... )
A named event is an event with a name. He might look something like this guy?
internal class EventRaiser : IEvent {
public EventRaiser( string name ) {
_name = name;
_handlers = new List< EventHandler >( );
}
public string Name {
get { return _name; }
}
public void Add( EventHandler handler ) {
_handlers.Add( handler );
}
public void Raise( ) {
Raise( null, null );
}
public void Raise( object sender, EventArgs data ) {
foreach ( EventHandler handler in _handlers ) {
if ( handler != null ) {
handler( sender, data );
}
}
}
private readonly string _name;
private readonly IList< EventHandler > _handlers;
}
Underneath the hood it's the aggregator that's maintaining references to all the types that have subscribed to events.
public class EventAggregator : IEventAggregator {
public EventAggregator( ) {
_events = new Dictionary< string, IEvent >( );
}
public void Register( string eventName ) {
Register( new EventRaiser( eventName ) );
}
public void Register( IEvent eventToAdd ) {
EnsureEventHasntBeenRegistered( eventToAdd );
_events.Add( eventToAdd.Name, eventToAdd );
}
public void AddHandler( string eventName, EventHandler handler ) {
RetrieveEvent( eventName ).Add( handler );
}
public void RaiseEvent( string withEventName ) {
RaiseEvent< EventArgs >( withEventName, null, EventArgs.Empty );
}
public void RaiseEvent( IEvent eventToRaise ) {
RaiseEvent< EventArgs >( eventToRaise.Name, null, EventArgs.Empty );
}
public void RaiseEvent< T >( string withEventName, object sender, T data ) where T : EventArgs {
RetrieveEvent( withEventName ).Raise( sender, data );
}
private IEvent RetrieveEvent( string eventName ) {
if ( _events.ContainsKey( eventName ) ) {
return _events[ eventName ];
}
throw new ArgumentNullException( eventName, "The Event Has Not Been Registered." );
}
private void EnsureEventHasntBeenRegistered( IEvent eventToAdd ) {
if ( _events.ContainsKey( eventToAdd.Name ) ) {
throw new ArgumentException( "Event name has already been registered", eventToAdd.Name );
}
}
private readonly IDictionary< string, IEvent > _events;
}
The concept is similar to Juval Lowy's EventHelper class defined in...
The Identity Map
Tuesday, December 18, 2007 12:21:21 PM (Mountain Standard Time, UTC-07:00)
This week while I'm at home on holidays, I've been reading...
This book is amazing, I could probably read it over and over again. The patterns that it presents makes a lot of sense, the actual implementations and examples could probably re-vamped but I'm finding that it's a great starter to trying to understand the concepts.
So today I'm trying to grok this concept of the "IDENTITY MAP". The book defines it as:
"Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them."
I put together a quick implementation that I'm using for an assignment I'm writing for school. I'm creating repositories that have 2 dependencies. First dependency is a Data Mapper (not to be confused with a Mapper) and the second is an Identity Map.
As objects are requested from the repository, the repository is checking the identity map to see if an instance has been loaded, if it has it's immediately returned to the caller. If the object is not in the map the repository leverages the data mapper to load the object, then adds it to the map and returns it to the caller.
The Data Mapper is defined as:
"A layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself." - PoEAA
I created a Layer Supertype to register objects in the map. The Domain Layer Super type demands that domain objects had an ID. The ID is what's getting used to load and register objects into the map.
The Layer Supertype is defined as:
"A type that acts as a the supertype for all types in it's layer." - PoEAA
The Domain Layer Super Type.
public interface IDomainObject {
long ID();
}
My actual implementation of the identity map looks like this...
public class IdentityMap< T > : IIdentityMap< T > where T : IDomainObject {
public IdentityMap() {
_items = new List< T >( );
}
public void Add( T domainObject ) {
EnsureObjectHasNotAlreadyBeenAdded( domainObject );
_items.Add( domainObject );
}
public T FindObjectWithIdOf( long idOfObjectToFind ) {
foreach ( T item in _items ) {
if ( item.ID( ).Equals( idOfObjectToFind ) ) {
return item;
}
}
return default( T );
}
private void EnsureObjectHasNotAlreadyBeenAdded( T domainObject ) {
if ( ContainsObjectWithIdOf( domainObject.ID( ) ) ) {
throw new ObjectAlreadyAddedToIdentityMapException( domainObject );
}
}
private readonly IList< T > _items;
}
One of the benefits I like about the Identity Map is that it acts as an in memory cache for objects loaded from the database. This reduces the number of trips to and from the persistence store.
Source Code
Strap It Into The Test Harness
Saturday, November 24, 2007 11:33:05 AM (Mountain Standard Time, UTC-07:00)
On Thursday I finished reading...
This was a pretty sweet read, but I think I would have gained more value from it if I were currently working on a legacy code base. (Please Don't read that as... "I want to work on a legacy code base.")
This book is loaded with a catalog of refactorings to improve the design of existing code and get it under a test harness. Below is a list of some of the quotes from the book that I stuck out for me...
"The Legacy Code Change Algorithm
- Identify change points.
- Find test points.
- Break dependencies
- Write tests.
- Make changes and refactor.
Over time, tested areas of the code base surface like islands rising out of the ocean."
"Mock objects are fakes that perform assertions internally."
"...it is better to depend on interfaces or abstract classes than it is to depend on concrete classes. When you depend on less volatile things, you minimize the chance that particular changes will trigger massive recompilation."
"The heuristics for identifying responsibilities can really help you dig in and find new abstractions in old classes, but they are just tricks. The way to really get better at identification is to read more. Read books about design patterns. More important, read other people's code. Look at open-source projects, and just take some time to browse and see how other people do things. Pay attention to how classes are named and the correspondence between class names and the names of methods. Over time, you'll get better at identifying hidden responsibilities, and you'll just start to see them when you browse unfamiliar code."
"... when I first thought about becoming a programmer, I was really captivated by stories about super-smart programmers, those guys and gals who could keep the state of an entire system in their heads, write correct code on the fly, and know immediately whether some change was right or wrong...
Holding on to a lot of state mentally can be useful, but it doesn't really make us better at decision-making. At this point in my career, I think I'm a much better programmer than I used to be, even though I know less about the details of each language I work in."
"When interfaces were first introduced in languages, some people started naming interfaces by placing and "I" before the name of the class they were gleaned from...
The advantage to this sort of naming is that you don't really have to think about the name when you the extraction. The disadvantage is that you end up with a lot of code that has to know whether it is dealing with an interface. Ideally, it shouldn't care one way or another."
Hosting DasBlog on GoDaddy for the young, fabulous and broke
Thursday, November 22, 2007 8:52:07 AM (Mountain Standard Time, UTC-07:00)
When I moved my DasBlog on to GoDaddy I found that my captcha controls (comment view and email view) were no longer showing. In the event log I was reading the following exception...
I'm paying for the cheapest possible plan i could find on GoDaddy which was the Economy Plan, I'm not sure if this following step is necessary if you're paying for a virtual dedicated host.
"System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'gdiplus.dll':"
DasBlog doesn't ship with "Gdiplus.dll" so you'll have to download it and drop it into the bin directory.

Thanks for your help, Mr. Justice!
While I'm at it, I should drop a plug for...
It's catered to an American audience, but I really enjoyed it. It was a fresh and funky take on finances.
Complexity Simplified
Saturday, October 27, 2007 12:47:17 AM (Mountain Standard Time, UTC-07:00)
I'm currently reading...
It's really as good as they say it is! And it's got me thinking... I really enjoy reading a book that makes me think, I sometimes prefer reading tech books that only give you concepts to think about. It's up to you to understand those concepts then find a way to implement them when you see their use is necessary. There's a lot of great concepts that came from this book, and after seeing them out in the wild in episodes of DNRTV and source code buried in svn repositories it's all starting to make sense...
- Entities: An object defined primarily by its identity is called an Entity.
- Value Objects: An object that describes some characteristic or attribute but carries no concept of identity.
- Aggregates: A cluster of associated objects that are treated as a unit for the purpose of data changes.
- Repositories: A mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects.
- Services: An operation offered as an interface that stands alone in the model, with no encapsulated state.
- Specifications: A predicate that determines if an object does or does not satisfy some criteria.
*Note: the definitions above are right out of the glossary.
The toughest part to grasp and seems to be the underlying theme of this book is "The Ubiquitous Language". The tough part is not grasping the "concept" but rather the implementation. The concept makes a lot of sense, but how you can practically apply it is a separate story. One that I think takes experience through trial and error. Time will tell...
Go buy this book, I know I will... until then thank you Mr. Adam! (just in case I can't I put it on my wish list for Santa, he always pulls through!)
After reading through some examples on specifications and reading through JP's example, this sparked some ideas in my mind. So I hacked together some code and came up with this. Let's say I've got a bank of questions, and that each question is part of a category, and I want to be able to search through the bank of questions...
[Test]
public void Should_Return_3_Questions_That_Are_Not_Math( ) {
IEnumerable< IQuestion > matches =
CreateSut( ).FindAllWhere( Question.IsIn( Any.Category ).But( Not.In( Category.Math ) ) );
Assert.AreEqual( 3, GetCountFor( matches ) );
}
Notice the use of "But", I wonder if this will catch on...
Basically I started looking into creating specification for boolean operations, with a slightly different take from what the book offered and inspired by JP and Ayende. I'm not sure it's the most elegant interface, but I really wanted to be able to make the client code as readable as possible.
What I ended up with was types like "Is", "Not", "And" & "Or". I'm not sure I'm completely happy with the end product, but I see potential for extending this further, and the best part is how readable the code seems to be. I think that excites me more then anything else... I think I'm just starting to understand this concept of the "fluent" interface. Not truly implementing it well, seems to be difficult, but fun!
Here's what my Question type turned in too...
public class Question : IQuestion {
public Question( ICategory category ) {
_category = category;
}
public ICategory Category {
get { return _category; }
}
public static ISpecification< IQuestion > IsIn( ICategory category ) {
return Is.In( category );
}
public static ISpecification< IQuestion > IsNotIn( ICategory category ) {
return Not.In( category );
}
private readonly ICategory _category;
}
The Is type looks like...
public class Is {
public static ISpecification< IQuestion > In( ICategory category ) {
return new Specification< IQuestion >(
delegate( IQuestion question ) { return category.Equals( question.Category ); }
);
}
}
And the "Not" type looks like...
public class Not {
public static ISpecification< IQuestion > In( ICategory category ) {
return new Specification< IQuestion >(
delegate( IQuestion question ) { return !category.Equals( question.Category ); }
);
}
}
To me it still seems that the "Not" and "Is" types shouldn't be responsible for returning the specification, and that responsibility should belong to the Question, but I'm just not sure... and it's getting rather late so I should head to bed.
Source is attached!
PlayingWithSpecifications.zip (2.17 MB)
Fast, slow, slower rhythm
Tuesday, October 02, 2007 7:18:46 PM (Mountain Standard Time, UTC-07:00)
1. You quickly deliver release 1.0 of a system, but with junky code.
2. You attempt to deliver release 2.0 of the system, but the junky code slows you down.
3. As you attempt to deliver future releases, you go slower and slower as the junky code multiplies, until people lose faith in the system, the programmers and even the process that got everyone into this position.
I read it from...
Conversing With Mahatma
Saturday, September 29, 2007 7:24:20 AM (Mountain Standard Time, UTC-07:00)
So recently I started reading...
 | Gandhi An Autobiography: The Story of My Experiments With Truth by Mohandas Karamchand (Mahatma) Gandhi, Mahadev H. Desai
Read more about this title... |
And I realized how little I knew about Mahatma Gandhi, although just about everyone knows the name. Very few know the story, and I was definitely one of those.
I can't really believe how much this man has endured in his life, I'm only about half way through the book, but he's experienced so much in his life. I really think that it's the experiences in life help shape who we become, and the more we experience the better we become.
Here's one quote from the book that stuck out for me... (so far)
"It has always been a mystery to me how men can feel themselves honoured by the humiliation of their fellow beings." - Mahatma Gandhi
CLeaRly Understanding C#
Monday, September 24, 2007 7:45:49 PM (Mountain Standard Time, UTC-07:00)
I finished reading CLR via C# about a week ago. If you haven't read this book and enjoy writing C#, you ought to go out right now and get yourself a copy. (I have yet to purchase a copy for myself, but lucky for me my good ol' pal Mr. Adam lent me his copy.) This book is amazing, I would have to say that my favorite chapters were on delegates and events. This is seriously a great book.
"When the C# compiler sees the delegate keyword used wherever a reference to a delegate object is expected, the compiler automatically defines a new private method in the class... This new method is called an anonymous method because the compiler creates the name of the method for you automatically, and normally, you wouldn't know it's name." - Jeffrey Richter, CLR via C#
So the below anonymous method would actually get compiled out to a full blown method, with a name given to it by the compiler.
return delegate(T x, T y) { return -comparison(x, y); };
Did you know that you can control event registration and un-registration?
public class EventAggregator< T > where T : EventArgs {
public EventAggregator( ) {
_lock = new object( );
}
public event EventHandler< T > NewEvent {
add {
lock ( _lock ) {
_newEvent += value;
}
}
remove {
lock ( _lock ) {
_newEvent -= value;
}
}
}
public void RaiseEvent( T data ) {
_newEvent.Invoke( this, data );
}
private readonly object _lock;
private EventHandler< T > _newEvent;
}
I don't know about you but the above code blew my mind! "add", "remove"... whoa! (poof... the sound of my mind blowing up!)
I am seriously looking forward the 3rd edition, where I hope Jeffrey Richter talks about the new additions to the C# compiler in the .NET Framework 3.5. My goodness what are you still doing sitting there... go by this book...
SALES TAXES
Monday, September 24, 2007 7:07:23 PM (Mountain Standard Time, UTC-07:00)
I recently came across a problem, and I thought I would try to flex some of my developer muscle to try to solve it. The problem reads as follows:
Basic sales tax is applicable at a rate of 10% on all goods, except books,
food, and medical products that are exempt. Import duty is an additional
sales tax applicable on all imported goods at a rate of 5%, with no
exemptions.
When I purchase items I receive a receipt which lists the name of all the
items and their price (including tax), finishing with the total cost of the
items, and the total amounts of sales taxes paid. The rounding rules for
sales tax are that for a tax rate of n%, a shelf price of p contains
(np/100 rounded up to the nearest 0.05) amount of sales tax.
Write an application that prints out the receipt details for these shopping
baskets...
INPUT:_
Input 1:
1 book at 12.49
1 music CD at 14.99
1 chocolate bar at 0.85
Input 2:
1 imported box of chocolates at 10.00
1 imported bottle of perfume at 47.50
Input 3:
1 imported bottle of perfume at 27.99
1 bottle of perfume at 18.99
1 packet of headache pills at 9.75
1 box of imported chocolates at 11.25
OUTPUT
Output 1:
1 book : 12.49
1 music CD: 16.49
1 chocolate bar: 0.85
Sales Taxes: 1.50
Total: 29.83
Output 2:
1 imported box of chocolates: 10.50
1 imported bottle of perfume: 54.65
Sales Taxes: 7.65
Total: 65.15
Output 3:
1 imported bottle of perfume: 32.19
1 bottle of perfume: 20.89
1 packet of headache pills: 9.75
1 imported box of chocolates: 11.85
Sales Taxes: 6.70
Total: 74.68
==========
To solve this problem I used a composite to calculate taxes. The "TaxComposite" type allows you to bundle several different taxes all in one type. So when calculating taxes, the calculation with iterate through all the taxes and add the calculated tax and return the total value.
public class TaxComposite : ITax {
public TaxComposite( params ITax[] taxes ) : this( new List< ITax >( taxes ) ) {}
public TaxComposite( IEnumerable< ITax > taxes ) {
_taxes = new List< ITax >( taxes );
_amount = CalculateAmount( );
_type = CalculateType( );
}
public double Amount {
get { return _amount; }
}
public TaxTypes Type {
get { return _type; }
}
public IMoney CalculateTaxFor( IMoney price ) {
return CalculateTaxFor( price, RoundingDelegateFactory.RoundToNearestTenCents );
}
public IMoney CalculateTaxFor( IMoney price, RoundingStrategy round ) {
IMoney total = new Money( );
Summary( delegate( ITax tax ) { total = total.Add( tax.CalculateTaxFor( price, round ) ); } );
return total;
}
private double CalculateAmount( ) {
double amount = 0d;
Summary( delegate( ITax tax ) { amount += tax.Amount; } );
return amount;
}
private TaxTypes CalculateType( ) {
TaxTypes type = TaxTypes.None;
Summary( delegate( ITax tax ) { type = type | tax.Type; } );
return type;
}
private void Summary( Action< ITax > toDo ) {
foreach ( ITax tax in _taxes ) {
toDo( tax );
}
}
private readonly IList< ITax > _taxes;
private readonly double _amount;
private readonly TaxTypes _type;
}
"The Composite Pattern allows you to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly." - Head First Design Patterns
I used a TaxFactory type to construct the TaxComposite type which gathers all the taxes that match a specified predicate and injects it into the TaxComposite constructor. It looks like...
public static class TaxFactory {
public static ITax Create( TaxTypes forTaxes ) {
return new TaxComposite(
Taxes.FindBy( delegate( ITax tax ) { return ( tax.Type & forTaxes ) == tax.Type; } ) );
}
The tax type is an enum that uses the flags attribute so that I can enable different bits for different taxes.
[Flags]
public enum TaxTypes {
None = 0x00,
Sales = 0x01,
Import = 0x02
}
Taxes is a static type that contains different types of taxes. The FindBy method allows for different strategies to be passed into to gather different types of taxes based on different critera. The above example returns all the taxes that are enabled in the "forTaxes" argument. FindBy is defined like...
public static IEnumerable< ITax > FindBy( Predicate< ITax > condition ) {
foreach ( ITax tax in taxes ) {
if ( condition( tax ) ) {
yield return tax;
}
}
}
I'm not sure if this is the most flexible design, but if i need to make changes to tax rates I can do that in one spot. The only catch is that it requires a re-compile to take a effect. In a full blown implementation I may want to consider using a "service" to retrieve the tax rates. Also, in this implementation in order to add new taxes I have to added it too 2 different locations. The first is the TaxTypes enum and the second is the Taxes static holder class. This leaves a bit of a smell...
Keeping It Real With Delegates
Tuesday, September 11, 2007 11:46:21 AM (Mountain Standard Time, UTC-07:00)
If you take a look at the following line, you will probably recognize it as the signature for an event handler.
public void Handler( object sender, EventArgs e ) {
The reason why event handlers are defined with this signature is because it matches the signature of the EventHandler delegate which looks like this:
public delegate void EventHandler(object sender, EventArgs e);
So when you're registering an event handler to an event. You're adding a delegate to the internal list of delegates. (Think of a type safe array of function pointers.) So when the event is raised, each method in the list of delegates is raised, in the same order as they were registered in.
The following line:
container.MyEvent += new PlayingWithEventHandlers( Console.Out.WriteLine ).Handler;
Expands out to something like this...
PlayingWithEventHandlers handlers = new PlayingWithEventHandlers( Console.Out.WriteLine );
MulticastDelegate multicastDelegate = new MulticastDelegate( handlers, "Handler" );
You'll find that the MulticastDelegate constructor is protected so this code wont actually compile. Also, the event delegate is combining the newly added delegate that is registering for the event.
The following example uses 3 different delegates defined in the .NET Framework.
//public delegate void EventHandler(object sender, EventArgs e);
//public delegate void TimerCallback(object state);
//public delegate void Action<T>(T obj);
public class PlayingWithEventHandlers {
private readonly Action< string > _action;
public PlayingWithEventHandlers( Action< string > action ) {
_action = action;
}
public void Handler( object sender, EventArgs e ) {
_action( ( string )sender );
}
}
public class MyEventContainer {
private Timer _timer;
public MyEventContainer( ) {
_timer = new Timer( delegate( object state ) { MyEvent.Invoke( state, EventArgs.Empty ); }, "Tick", 0, 5000 );
}
public event EventHandler MyEvent;
}
public class Bootstrap {
public static void Main( ) {
MyEventContainer container = new MyEventContainer( );
container.MyEvent += new PlayingWithEventHandlers( Console.Out.WriteLine ).Handler;
Console.In.ReadLine( );
}
}
One of the benefits of using delegates that you can inline an anonymous delegate. The above line where the an instance of the Timer class is constructed could be re-written like...
_timer = new Timer( delegate { MyEvent.Invoke( "Tick", EventArgs.Empty ); }, null, 0, 5000 );
The TimerCallBack's input parameter "state" is still passed to the delegate but the C# compiler allows for this shorthand which ignores the input parameter. The same code could also be re-written as...
public MyEventContainer( ) {
_timer = new Timer( TimerClickHandler, "Tick", 0, 5000 );
}
public void TimerClickHandler( object state ) {
MyEvent.Invoke( state, EventArgs.Empty );
}
This version creates a new method called "TimerClickHandler" that matches the "TimerCallback" delegate signature. Delegates can be quite fun... almost as fun as tables of function pointers in C.
For more information check out...
EventHandler.txt (1.22 KB)
Design Principles
Sunday, September 09, 2007 4:12:54 PM (Mountain Standard Time, UTC-07:00)
The Open-Closed Principle (OCP): Classes should be open for extension, and closed for modification.
The Don't Repeat Yourself Principle (DRY): Avoid duplicate code by abstracting out things that are common and placing those things in a single location.
The Single Responsibility Principle (SRP): Every object in your system should have a single responsibility, and all the objects services should be focused carrying out that single responsibility.
The Liskov Substitution Principle (LSP): Subtypes must be substitutable for their base types. (The LSP is all about well-designed inheritance.)
The Hollywood Principle: Don't call us, we'll call you.
The Law of Demeter (The principle of least knowledge): Only talk to your immediate friends.
Delegation is when you hand over the responsibility for a particular task to another class or method.
Composition allows you to use behavior from a family of other classes, and to change that behavior at runtime.
Aggregation is when one class is used as part of another class, but still exists outside of that other class.
Encapsulate what varies.
Favor composition over inheritance.
Program to interfaces, not implementations.
Strive for loosely coupled designs between objects that interact.
Depend on abstractions. Do not depend on concrete classes.
 | Head First Object-Oriented Analysis and Design: A Brain Friendly Guide to OOA&D (Head First) by Brett D. McLaughlin, Gary Pollice, Dave West
Read more about this title... |
Bringer Of Light
Sunday, September 09, 2007 3:47:03 PM (Mountain Standard Time, UTC-07:00)
On my ride home from work Friday evening I finished reading...
This was an excellent read! I just couldn't put it down after I first cracked it open. My boss at work popped by my desk on Wednesday, and handed me the book. She said that I would probably enjoy it! I did! Thanks Leanne!
The chapters are short and sweet, which makes it so easy to just pick up and read a chapter here and there. I wanted to share some of the insights from this book, but I highly encourage you to go out and read it yourself.
When I was growing up my father once told me: "Cut back on your rent or cut back on what you spend on food but never worry about investing money in a good book."
I really enjoy reading books. It really is like having a conversation with all sorts of great minds and views of the world! I'm really looking forward to one day being able to look back and think about all the wonderful books I've studied. I've learned so much from such a simple act, and teaching someone to read truly is precious.
"Not one of the uber-successful people I've worked with as a leadership coach got there without outworking everyone around them."
One of the other things that Robin mentioned in his book was that the price of discipline is not as painful as the price of regret. It's absolutely important to work heard to get ahead and for a sense of accomplishment. Feeling good about where you are, because of how hard you've worked is great!
"Faced an uphill battle: an aggressive enemy, brutal disease and scarce resources. As they marched inland to do battle, Cortes ordered one of his lieutenants back to the beach with a single instruction: "Burn our boats.""
Don't allow failure to be an option. Sometimes when dealing with all to difficult situations it's to easy to look for the backdoor out. But by changing your thinking so that you don't allow failure to be an option, you allow yourself to succeed. I also think this applied to being faithful and loyal to those you care about. It seems these days, it's so normal for partners to cheat on one another. Think ahead and don't allow yourself to be caught up in the moment.
"You need to practice to get to your greatness. Athletes know this so very well. Why does it seem so foreign to the rest of us?"
Duh! So schedule time to practice! In Jr. High and High School I had a friend who was a super athlete, he had accomplished more before 7 am then the regular teenager, including myself. He got it!
"If you eat three times a day you'll be fed. But if you read three times a day you'll be wise." - Shimon Peres
For some reason this quote spoke to me. It was silly how straight forward and simple this thought is, but it makes darn good sense!
"Study hip hop artists... You'll learn all you need to learn about taking a brand to the top of the mountain."
I'm a fan of hip hop, so any plug for it makes me smile!
I've downloaded every episode of Robin's podcast and found time each morning to listen to one episode each morning. I found that it's been a great way to start my day. I just hope he continues to publish more episodes.
This Wednesday, September, 12, 2007 I will be attending a private presentation by Robin Sharma here in Calgary. I'm really looking forward to the presentation!
The Factory Pattern
Monday, September 03, 2007 2:42:39 PM (Mountain Standard Time, UTC-07:00)
To demo how the Factory Method and Abstract Factory patterns work I've put together an example in C#. For this example I've got 2 different Banks, CIBC, and Royal Bank. Each bank offers a chequing and savings account. Through the use of the Factory Method and Abstract Factory, the sample shows you how to create different types of bank accounts.
"The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses." - Head First Design Patterns
IBank has a single method called "GetAccountFactory()" that returns a IBankAccountFactory. This allows types that implement the interface to specify what type of bank account factory to construct and return.
public interface IBank {
string Name { get; }
IBankAccountFactory GetAccountFactory( );
}
So CIBC implementation of IBank will return a CIBCBankAccountFactory.
public class CibcBank : Bank, IBank {
public CibcBank( ) : base( "CIBC" ) {}
public override IBankAccountFactory GetAccountFactory( ) {
return new CibcBankAccountFactory( );
}
}
"The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes." - Head First Design Patterns
IBankAccountFactory is an abstract factory for creating different types of bank accounts. In my provided example you'll see that the IBankAccountFactory has two methods defined in it, both of which return an IBankAccount:
- CreateChequingAccount()
- CreateSavingsAccount()
public interface IBankAccountFactory {
IBankAccount CreateChequingAccount( );
IBankAccount CreateSavingsAccount( );
}
To create a CIBC chequing account, the client code might look something like this:
IBank bank = new CibcBank( );
IBankAccountFactory factory = bank.GetAccountFactory( );
IBankAccount chequingAccount = factory.CreateChequingAccount( );
To create a Royal Bank chequing account, the client code might look something like this:
IBank bank = new RoyalBank( );
IBankAccountFactory factory = bank.GetAccountFactory( );
IBankAccount chequingAccount = factory.CreateChequingAccount( );
DesignPatterns.Factory.zip (9.16 KB)
The Principles and Values of XP
Friday, August 31, 2007 5:40:47 AM (Mountain Standard Time, UTC-07:00)
The XP Values
- Communication: Most desirable is face to face communication where we can talk, respond, gesture and draw on a whiteboard. Talking = good, documents = bad!
- Simplicity: Focus on creating a solution to the problem faced today, not the problem anticipated tomorrow.
- Feedback: Developers give and get feedback from pair programming, from automated tests, continuous integration. Customers are part of the team even sitting in the same space with the developers, and provide feedback through constant interaction with the team, and through acceptance tests.
- Courage: They have courage to refactor their code, proceed with an overall master architecture.
The Principles of XP
- Rapid Feedback: Constantly sending and receiving feedback, and responding to it.
- Assuming Simplicity: Favor simplicity and attempt to create a simple solution before evolving to a complex one.
- Incremental Change: Improve the software through small, incremental changes.
- Embracing Change: Developers are able to adapt and accommodate change.
- Doing Quality Work: Insist that the software consistently exhibits the highest level of quality workmanship.
Learning To Become More XP
Thursday, August 30, 2007 6:04:17 AM (Mountain Standard Time, UTC-07:00)
I'm still fascinated by the Agile XP methodology. So when I came across the overview of XP in the Appendix of...
I had to read on. Here's what I learned:
Roles
- The XP customer role is responsible for writing stories, prioritizing stories, and writing and executing tests that demonstrate that stories were developed as expected.
- The XP programmer role encompasses a broad range of technical skills. XP projects tend not to draw distinctions between programmers, designers, DBA's and so on.
- XP teams benefit for the use of an XP coach and possibly a project manager. The coach is responsible for monitoring the team's use of the XP practices and gently nudging them back on track when they stray.
The 12 Practices
Small Releases
Project progress in a series of iterations, which are typically 1 to 3 weeks long. Features are fully delivered within a single iteration.
The Planning Game
- This is the name for release and iteration planning where developers and customers collaborate to make predictions about the future.
- Prior to planning, the customer has written user stories on note cards and developers have estimated the cost of magnitude of each story and have written the estimate on the story card.
Refactoring
- Refers to the restructuring or rewriting of code so as to improve the code without changing its external behavior.
- XP advocates constant attention to refactoring. Whenever a programmer makes a change to code that should be refactored, she is required to refactor it.
- She's not encouraged to refactor it; she's required to refactor it.
- Instead of spending time upfront thinking through a system in advance of coding it, and therefore taking guesses at some aspects of its behavior, XP systems are refactored and kept in a state that perfectly meets known, implemented requirements.
Testing
- The developers write automated unit tests.
- The customers write acceptance tests.
- In test-driven development, tests are written before the code. Developers follow a short cycle of test-code-test-code... No operational code may be written except in response to a failing test.
Pair Programming
- Refers to 2 programmers sharing one computer and 2 brains to write code. One programmer types the code, the second is watching the code develop and thinking more broadly about the code.
- This leads to lower defect counts, less code is written to solve the same problem, problems being solved more quickly, more people understand each piece of code, an increase in developer satisfaction.
- It requires discipline to refactor every time you notice poorly structured code.
Sustainable Pace
- The believe is that an XP team moving at a consistent but brisk pace will achieve more over a period of time than will a team working at a pace they cannot sustain over a long period of time.
- It is up to the team to determine their sustained pace.
- A team will typically devote around 6 hours per day to pairing and spend the remainder of the day in other activities.
- An XP coach is responsible for monitoring the team for burnout.
Team Code Ownership
- It's common in non-XP teams for individuals to "own" portions of a systems code. This leads to comments like "We can't change the billing source code until Eli gets back from vacation."
- All code is owned by everyone.
- Pairs are expected to change code they didn't write.
- A strong suite of unit tests ensures that changes do not introduce unanticipated side effects.
Coding Standard
- XP teams collectively own their source code, so it's important to follow a coding standard.
- A small, close-knit team may be able to get by without a written, formalized coding standard.
Simple Design
- Pursue a goal of having the simplest possible design that delivers the features a customer needs.
- The operational code and the test code fully convey the programmers intent.
- There is no duplicate code.
- The system uses the least number of classes.
- The system uses the least number of methods.
Metaphor
- Quest for simple design by finding a metaphor that can be used for the whole system. The metaphor describes how they think about the system.
- E.g. "The system is like a chalkboard and various parts of the system can write on the chalkboard. When a user is done with the system she can either save the contents of the chalkboard or erase them."
Continuous Integration
- Code is integrated continuously.
- A developer completes a small change, he checks the change into source control, where the CI box initiates a full build. When the build is finished a full set of unit tests are run. If any tests fail, the developer is notified by email and told about the failure.
- Integration problems are fixed one at a time in extremely small batches as soon as they occur.
On-Site Customer
- The customer is expected to sit with and be part of the development team. The customer writes the stories and the acceptance tests and is also available to answer questions as they arise.
- If the customer is not on site, delays will disrupt the predictable progress of the XP team.
It's Story Time
Wednesday, August 29, 2007 5:35:02 AM (Mountain Standard Time, UTC-07:00)
Last night I finished reading...
It was a nice quick and dirty read, to get my feet wet in the world of applying user stories. I really prefer working with user stories as opposed to full blown system requirements specifications. Although, a typical SRS is much thicker then a set of user stories, I think more information is delivered through user stories because it done so piece by piece. As you require the information, it's your responsibility to gather it.
I want to share some of my favorite quotes from the book.
"Pay attention to who is contributing during a story writing workshop. Occasionally a participant will remain silent through much or all of the meeting. If this is the case, talk to the participant during one of the breaks and make sure she's comfortable with the process. Some participants are reluctant to speak up in front of their peers or supervisors, which is why it is important that story ideas not be judged during these sessions. Once participants become comfortable that their ideas will simply be noted, not debated, at this point they will contribute more readily."
I have to admit that at my first story writing workshop I didn't say much. It was kind of a foreign concept to me and I worried about getting shot down by the other developers if I mentioned a story idea. I felt like there was a good chance that would occur because the rest of the team felt they had a similar vision of how the product would look and feel before and discussion had even begun. I later realized that they did indeed want to hear my story ideas, but it just took some time getting used to the culture of the team.
"When you cannot find, or get access to, a real user, avoid falling into the trap of thinking you know your users' minds and do not need or can ignore your user proxy. While each type of user proxy has some type of shortcoming that makes her less desirable than a real user, most developers come with even more shortcomings for pretending to be a real user. In general, developers do not have marketing backgrounds that allow them to understand the relative value of features, they do not have the same amount of customer contact as salespeople, they are not domain experts, and so on."
I know as a developer that there are many times where I know how I would like a piece of software to work. Because it would work well for me, but ultimately that's not always going to work best for the end user. It's difficult to put yourselves in someone else's shoe to try to think like they would. It's much easier to just ask, instead of making a design decision, implementing it then later having them tell you that's not what they wanted.
"Ideally the customer writes the stories. On many projects the developers help out, either by doing the actual writing during an initial story writing workshop or by suggesting new stories to the customer. But, responsibility for writing stories resides with the customer and cannot be passed to the developers."
Wow... I had no idea. Right now we're writing the user stories...
"In a blame-filled organization there are always some individuals who have learned that their best decision is to avoid all responsibility. If you're not responsible for something you can't be blamed for it when it fails, yet there's usually a way to lay claim to at least some of the success. Individuals in this type of culture will want nothing to do with hard decisions like prioritizing features into and out of releases. They'll fall back on statements such as "It's not my problem that you can't complete everything by the deadline, figure out a way to do it."
This seems to happen more often then not. I think when someone because slightly hostile, it's usually because of their own insecurities. But reading the above statement just helped me to realize to think about what they're going through. Who's grilling them, and how can I help so that they're are happy with the software but it also makes them look good to their peers.
The State Pattern
Sunday, August 26, 2007 2:35:59 PM (Mountain Standard Time, UTC-07:00)
"The State Pattern allows an object to alter its behavior when its internal state changes. The object will appear to change it's class." - Head First Design Pattern
Let's say I've got a point of sale terminal used for processing financial transactions. Let's say that at any given time the terminal can be in 1 of 6 states. Those states are:
- Idle State: During this state an idle message is displayed on the screen of the POS terminal.
- Card Swiped State: The terminal enters this state when a card is swiped.
- Amount Entered State: The terminal enters this state when the transaction amount is entered.
- PIN Entered State: The terminal enters this state when the customer enters their PIN.
- Processing Transaction State: The terminal enters this state when it connects to a financial processor to process the transaction.
- Transaction Approved State: The terminal enters this state when the transaction has been process and has been approved.
- Transaction Rejected State: The terminal enters this state when the transaction was processed but was rejected.
Let's pretend the following is the client code that will use the point of sale terminal to process transactions.
IPosTerminal terminal = new PosTerminal( );
terminal.SwipeCard( "6278080000008205" );
terminal.EnterAmount( 99.99 );
terminal.EnterPin( "8012" );
terminal.ProcessTransaction( );
terminal.PrintReceipt( );
When the PosTerminal is first constructed it is immediate put into an Idle State which displays an idle message to screen. The PosTerminal has a property of type IState that all the concrete state types implement.
As actions are performed against the PosTerminal, they are delegated to the current state.
public void SwipeCard( string cardNumber ) {
_currentState.SwipeCard( cardNumber );
}
public void EnterAmount( double amount ) {
_currentState.EnterAmount( amount );
}
public void EnterPin( string pin ) {
_currentState.EnterPin( pin );
}
public void AuthorizeTransaction( ) {
_currentState.ProcessTransaction( );
}
public void PrintReceipt( ) {
_currentState.PrintReceipt( );
}
public void ProcessTransaction( ) {
_currentState.ProcessTransaction( );
}In this implementation I've made it the concrete state types responsibility to transition to the next state. For example the IdleState might look like:
public void SwipeCard( string cardNumber ) {
_terminal.Transaction = new PosTransaction( );
_terminal.Transaction.Date = DateTime.Now;
_terminal.Transaction.CardNumber = cardNumber;
_terminal.CurrentState = new CardSwipedState( _terminal );
}
public void EnterAmount( double amount ) {
Console.Out.WriteLine( "Please swipe a card first." );
}
...
With the state pattern you can re-order states and alter the implementation of a state with out having to change the subject of the state.
DesignPatterns.State.zip (7.13 KB)
The Adapter Pattern
Sunday, August 26, 2007 1:39:14 PM (Mountain Standard Time, UTC-07:00)
"The Adapter Pattern converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces." - Head First Design Patterns
If you're trying to build a presentation layer that is platform agnostic, you might turn to adapters for simple UI controls. For example in ASP.NET there is a drop down list control, and in Win Forms there is the Combo Box control.
A quick an easy adapter to the two controls might look like:
public interface IDropDownListAdapter {
void BindTo( IEnumerable< IDropDownListItem > pairs );
IDropDownListItem SelectedItem { get; }
}
Each drop down list item might look like:
public interface IDropDownListItem {
string Text { get; }
string Value { get; }
}
A concrete implementation for a Win Forms application might look like:
public class DesktopDropDownList : IDropDownListAdapter {
public DesktopDropDownList( ComboBox dropDown ) {
_dropDown = dropDown;
_pairs = new Dictionary< string, IDropDownListItem >( );
}
public void BindTo( IEnumerable< IDropDownListItem > pairs ) {
if ( pairs != null ) {
_pairs = new Dictionary< string, IDropDownListItem >( );
foreach ( IDropDownListItem pair in pairs ) {
_dropDown.Items.Add( pair.Text );
_pairs.Add( pair.Text, pair );
}
_dropDown.SelectedIndex = 0;
}
}
public IDropDownListItem SelectedItem {
get { return !string.IsNullOrEmpty( _dropDown.Text ) ? _pairs[ _dropDown.Text ] : null; }
}
private ComboBox _dropDown;
private IDictionary< string, IDropDownListItem > _pairs;
}
A concrete implementation for a ASP.NET application might look like:
public class WebDropDownList : IDropDownListAdapter {
public WebDropDownList( DropDownList dropDown ) {
_dropDown = dropDown;
}
public void BindTo( IEnumerable< IDropDownListItem > pairs ) {
if ( pairs != null ) {
foreach ( IDropDownListItem pair in pairs ) {
_dropDown.Items.Add( new ListItem( pair.Text, pair.Value ) );
}
}
}
public IDropDownListItem SelectedItem {
get { return new DropDownListItem( _dropDown.SelectedItem.Text, _dropDown.SelectedItem.Value ); }
}
private DropDownList _dropDown;
}
And voila... we can write a presentation layer that binds data to an IDropDownListAdapter, without having to be specific to WinForms, ASP.NET, WPF, Silverlight etc.
public Presenter( IView view ) {
_view = view;
}
public void Initialize( ) {
IList< IDropDownListItem > items = new List< IDropDownListItem >( );
items.Add( new DropDownListItem( "Yes", "1" ) );
items.Add( new DropDownListItem( "No", "2" ) );
_view.AreYouHappy.BindTo( items );
}DesignPatterns.Adapter.zip (4.56 KB)
Good Quality Tools
Thursday, August 23, 2007 6:29:00 AM (Mountain Standard Time, UTC-07:00)
"Every craftsman starts his or her journey with a basic set of good-quality tools. A woodworker might need rules, gauges, a couple of saws, some good planes, fine chisels, drills and braces, mallets, and clamps. These tools will be lovingly chosen, will be built to last, will perform specific jobs with little overlap with other tools, and, perhaps most importantly, will feel right in the budding woodworker's hands."
I read the above paragraph from the pragmatic programmer, and thought it made a lot of sense. My appreciation for tools continues to grow, and grow. And as I learn to use different tools, I find different sorts of productivity gains.
Some of the tools I use:
The Difference Between SVN and Visual Source Safe
Wednesday, August 22, 2007 12:11:45 PM (Mountain Standard Time, UTC-07:00)
I think Martin Fowlers description of optimistic and pessimistic locking is excellent. So excellent that I had to share...
"Let's suppose that Martin and David both want to edit the Customer file at the same time. With optimistic locking both of them can make a copy of the file and edit it freely. If David is the first to finish, he can check in his work without trouble. The concurrency control kicks in when Martin tries to commit his changes. At this point the source code control system detects a conflict between Martin's changes and David's changes. Martin's commit is rejected and it's up to him to figure out how to deal with the situation. With pessimistic locking whoever checks out the file first prevents anyone else from editing it. So if Martin is first to check out, David can't work with the file until Martin is finished with it and commits his changes." - Martin Fowler : PoEAA
SVN of course uses optimistic locking and Microsoft Visual Source Safe uses pessimistic locking. I've become a huge fan of SVN recently, and since we started using it here at work, I feel like I've become more productive. Gone are the days when I would hear "Can you check in the project, I need to add a file.", "Where's <enter name>? He's not in today? But he's got a file checked out that I need."
Processes and Threads
Wednesday, August 22, 2007 11:51:57 AM (Mountain Standard Time, UTC-07:00)
"A process is a, usually heavyweight, execution context that provides a lot of isolation for the internal data it works on. A thread is a lighter-weight active agent that's set up so that multiple threads can operate in a single process. " - Martin Fowler : PoEAA
What is Orthogonality?
Wednesday, August 22, 2007 11:42:09 AM (Mountain Standard Time, UTC-07:00)
In geometry, when two lines are orthogonal if they meet at right angles, such as the axes on a Cartesian plain. Move along one of the axes, and your position projected onto the other doesn't change.
In computing, the term has come to signify a kind of independence or decoupling. Two or more things are orthogonal if changes in one do not affect any of the others.
In a well-designed system, the database code will be orthogonal to the user interface; you can change the interface without affecting the database, and swap databases without changing the interface.
What do you mean you test first?
Friday, August 03, 2007 1:14:39 AM (Mountain Standard Time, UTC-07:00)
So I recently finished reading...
This was an awesome read! It started off with some a great example written in Java on Money. It was great to start right from the beginning and drive out the design with tests. Over the course of the book you see the design evolve and grow in to something, some might call "SEXY"!
Part 2 of the book starts to drive out an xUnit framework using TDD. It was pretty cool, and definitely gave me some insight as to how unit test frameworks like NUnit, and MbUnit work.
Part 3 of the book discusses Patterns for Test Driven Development and how to drive out good OO design in your application and tests. I had a bit of trouble getting over the Python syntax used in parts 2 and 3 of the book, but it's definitely good to get some exposure to different languages. (Those crazy python guys!)
Anyway's, this book is definitely worth checking out! I cant wait to read XP Explained by Beck!
What Does Pragmatic Mean?
Friday, July 27, 2007 1:27:14 PM (Mountain Standard Time, UTC-07:00)
Good Morning! So this week during my dead time on the bus I have been reading...
This book is great! It's a short one, but I seem to be taking my time with this one. It speaks at a much higher level, not so specific to a certain technology or language. However, the code samples in this book are mostly in C, Java and Perl. It's pretty cool to get some exposure to other languages, especially Perl!
Things I really like most about this book are the quotes and analogies. The analogies and stories seem to make it so much easier to understand and relate to different concepts. Stone soup and boiled frogs are great examples!
The bus ride was nice today, I managed to scoop a seat in the far back next to the window which offers me a little more privacy and great lighting for reading.
Did I mention that it's Friday?
GET BACK TO WORK!
The Complete Code Book
Friday, July 13, 2007 7:47:31 PM (Mountain Standard Time, UTC-07:00)
Earlier this week I finished reading "Code Complete" by Steve McConnell. I have to admin that everyone who has ever recommended reading this book, was absolutely correct for doing so. It's about 860 pages long, and it's worth reading every word. What I found this book did for me was help me to reflect on my last 3 years of software development.
Early in my software construction career, a wise programmer handed me his copy of "Code Complete" and told me I might be interested in reading it. I thumbed through the pages but didn't really give it a fair try. I just wasn't interested in a book that talked about programming but showed very little source code. (At that time it was all about C programming for me). Man, I was a silly kid, if I had just listened to the wise programmer who handed me the book!
As I was read through the book, there were many times where I felt like "I remember being in a situation like that", or "That's so true, I never thought about it like that." It was excellent and I recommend it to anyone who is currently involved in software construction.
Here's a list of some of my favorite quotes from the book.
"Programmers like Global Gary, who litter their code with defects and "complete" their programs quickly, are rewarded more than programmers like High-Quality Henry, who write excellent programs and make sure that they are usable before releasing them."
"Testing's goal runs counter to the goals of other development activities. The goal is to find errors. A successful test is one that breaks the software. The goal of every other development activity is to prevent errors and keep the software from breaking."
"Developers sometimes wonder whether it's better to write test cases after the code has been written of beforehand (Beck 2003). The defect-cost increase graph suggests that writing test cases first will minimize the amount of time between when a defect is inserted into the code and when the defect is detected and removed. This turns out to be one of many reasons to write test cases first:"
"... confirm another version of the General Principle of Software Quality: it's cheaper to build high-quality software than it is to build and fix low-quality software."
"The term 'scaffolding' comes from building construction. Scaffolding is built so that workers can reach parts of a building they couldn't reach otherwise. Software scaffolding is built for the sole purpose of making it easy to exercise code."
"Before you fix a problem, make sure you understand it to the core. Triangulate the defect both with cases that should reproduce the error and with cases that shouldn't reproduce the error. Keep at it until you understand the problem well enough to predict its occurrence correctly every time."
"A class has poor cohesion: If you find a class that takes ownership for a hodgepodge of unrelated responsibilities, that class should be broken up into multiple classes, each of which has responsibility for a cohesive set of responsibilities."
"Requirements for the 'design ahead' code haven't been fully developed, which means the programmer will likely guess wrong about those future requirements. The 'code ahead' work will ultimately be thrown away."
"Return as soon as you known the answer instead of assigning a return value within nested if-then-else statements: Code is often easiest to read and least error-prone if you exit a routine as soon as you know the return value. The alternative of setting a return value and then unwinding your way through a lot of logic can be harder to follow."
"One of my former roommates was a great procrastinator. He justified his laziness by saying that many of the things people feel rushed to do simply don't need to be done. If he waited long enough, he claimed, the things that weren't important would be procrastinated into oblivion and he wouldn't waste his time doing them... Lazy evaluation is similar to just-in-time strategies that do the work closest to when it's needed."
"Code that receives an award should be exceptionally good. If you give an award to a programmer everyone else knows does bad work, you look like Homer Simpson trying to run a nuclear reactor."
"If you implement each change as it occurs to you, you'll soon find yourself walking on a software treadmill - for all that the system will be changing, it won't be moving closer to completion."
"A significant percentage of the projects that are perceived to be late would actually be on time if they accounted for the impact of untracked but agreed-upon changes. Poor change control allows changes to accumulate off the books, which undermines status visibility, long-range predictability, project planning, risk management specifically, and project management generally."
"The implication for recruiting and hiring is clear. If you have to pay more to get a top-10-percent programmer rather than a bottom-10-percent programmer, jump at the chance. You'll get an immediate payoff in the quality and productivity of the programmer you hire, and you'll get a residual effect in the quality and productivity of the other programmers your organization is able to retain because good programmers tend to cluster."
"If you construct and integrate software in the wrong order, it's harder to code, harder to test, and harder to debug. If none of it will work until all of it works, it can seem as though it will never be finished."
"When code is integrated and running, even if the system isn't usable, it's apparent that it soon will be. With incremental integration, programmers see early results from their work, so their morale is better than when they suspect that their project will never draw its first breath."
"The visual and intellectual enjoyment of well-formatted code is a pleasure that few nonprogrammer's can appreciate. But programmers who take pride in their work derive great artistic satisfaction from polishing the visual structure of their code."
"When someone says, 'This is really tricky code," I hear them say, "This is really bad code." If something seems tricky to you, it will be incomprehensible to someone else. Even something that doesn't seem all that tricky to you can seem impossibly convoluted to another person who hasn't seen the trick before."
"Your employer can't force you to be a good programmer; a lot of times your employer isn't even in a position to judge whether you're good. If you want to be great, you're responsible for making yourself great. It's a matter of your personal character."
"The people who are best at programming are the people who realize how small their brains are. They are humble. The people who are the worst at programming are the people who refuse to accept the fact that their brains aren't equal to the task. Their egos keep them from being great programmers."
"... humble programmers who compensate for their fallibilities write code that's easier for themselves and others to understand and that has fewer errors."
"Adherence to a single method is also harmful in that it makes you force-fit the problem to the solution. If you decide on the solution method before you fully understand the problem, you act prematurely. Over-constrain the set of possible solutions, and you might rule out the most effective solution."
Do You Have Style?
Sunday, July 08, 2007 7:28:20 PM (Mountain Standard Time, UTC-07:00)
For anyone who currently writes C#, or is looking to start I highly recommend you pick up a copy of...
This book offers great suggestions for programming style in the C# language. It covers things like:
- Formatting
- Naming Conventions
- Documentation
- General Principles
The book contains a series of rules to abide by, most of the rules are quite flexible. The main premise of the book is to maintain consistency but offers variations that a C# developer can follow.
Here are a few example's taken from the book:
43. Use Came Case for Variable and Method Parameter Names
Use lowercase for the first word and capitalize each subsequent word that appears in a variable name to provide a visual cue for separating the individual words within each name.
public class Customer {
public string firstName_;
public string lastName_;
public string ToString(){
return lastName_ + ", " + firstName_;
}
}
49. Use an Organization Name for the Root Namespace, and Narrow by Project, Product or Group
namespace Company.Group.Project{
// ...
}
This book is an extremely quick read, but well worth the price. It comes in handy as an excellent reference manual!
The Observer Pattern
Friday, July 06, 2007 8:14:45 AM (Mountain Standard Time, UTC-07:00)
"The observer pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically." - Head First Design Patterns
What this means is that if you have objects that are interested in changes in another object, you allow the "observers" to register or subscribe to the subject. In the example provided, my wife and mother in law want to be notified whenever i look at cute girls. Each time i look at a cute girl they should be notified and then they can take whatever action they want.
Typically, you would push or pull the data from the subject (that's me), to the observers (that's my wife and her mom). Mo (that's me) contains an internal list of relatives that want to know what he's up to. Anytime one of his relatives wants to check in on him, the add themselves to Mo's interal list. If they're no longer interested, they can remove themselves for the internal list.
public Mo( IList< IObserver > concernedRelatives ) {
_concernedRelatives = concernedRelatives;
LookAtCuteGirl += delegate { OnLookedAtCuteGirl( ); };
}
public event EventHandler LookAtCuteGirl;
public void Add( IObserver observer ) {
_concernedRelatives.Add( observer );
}
public void Remove( IObserver observer ) {
_concernedRelatives.Remove( observer );
}
private IList< IObserver > _concernedRelatives;
private void OnLookedAtCuteGirl( ) {
foreach ( IObserver relative in _concernedRelatives ) {
relative.Update( );
}
}
Let's say my wife is concerned and wants to check up on me, here's how she would do it.
public MosWife( ISubject husband ) {
_husband = husband;
_husband.Add( this );
}
public void Update( ) {
Console.Out.WriteLine( "Why is my husband looking at cute girls?" );
}
private ISubject _husband;
She's decided to always add her self to my internal list to see what I'm doing. If I should happen to check out a cute girl, she will be immediately notified. Lucky for me, my wife is pretty laid back, and asks herself "Why is my husband looking at cute girls?"...
Hopefully, this helps to demonstrate the observer pattern. I realize that it is rather contrived example, and the source could could be refactored. But hopefully it's clear.
For a better explanation, you should read...
P.S. My wife does not check up on me, she's awesome!
DesignPatterns.Observer.zip (4.01 KB)
Understanding HTTP
Monday, July 02, 2007 4:27:51 PM (Mountain Standard Time, UTC-07:00)
HTTP is used for so many different reasons. While working in the wold of point of sale terminals, I spent some time sending raw HTTP packets and parsing them in C. Lot's of fun!
Here's a quick little exercise on playing with HTTP, that i found in "Microsoft .NET Framework 2.0 Web-Based Client Development"
1. Open up a command prompt: Start->Run->cmd
2. type "telnet", and press enter
3. type "o mokhan.ca 80"
4. type
"GET / HTTP/1.1
Host: mokhan.ca"
Then press enter twice
But do it quickly, before my server closes the connection due to a timeout!
 | MCTS Self-Paced Training Kit (Exam 70-528): Microsoft .NET Framework 2.0 Web-Based Client Development (Pro Certification) by Glenn Johnson, Tony Northrup
Read more about this title... |
The Complete Code
Monday, July 02, 2007 4:14:21 PM (Mountain Standard Time, UTC-07:00)
Last weekend I started reading Code Complete by Steve McConnel. I'm loving it, I just started chapter 22, but I wanted to take a moment and share some of the tidbits of information and quotes from this book that I found quite interesting. If you haven't already, I recommend you give it a try!
"Avoid creating omniscient classes that are all-knowing and all-powerful. If a class spends its time retrieving data from other classes using Get() and Set() routines ( that is, digging into their business and telling them what to do), ask whether that functionality might better be organized into those other classes rather than into the god class ..."
This paragraph immediately struck home to me. Have you ever stepped into a new team, and found that there are classes in some project that are over 500 lines long? How about 1000? How about 3000? When I saw this, it screamed... REFACTORING to me! When I asked one of the authors to describe to me what this class did, he listed off a list of responsibilities. (On a side note... I can't wait to read Refactoring by Martin Fowler! It was way to scary to try to change that 3000+ line class because no one knew what would happen if we did. Enter... unit tests!)
I pulled out a pad of paper and a pen and listed off the responsibilities, and read them back to the author. 1... 2... 3... 4... This subtle activity helped the author see, that "hey, this class should probably broken out into smaller pieces". Bingo! Even as a junior my code smell was tingling...
"Avoid empty catch blocks... either the code within the try block is wrong because it raises an exception for no reason, or the code within the catch block is wrong because it doesn't handle a valid exception. Determine which is the root cause of the problem, and then fix either the try block of the catch block."
I've got a bit of a pet peeve when it comes to code that swallows exceptions.. check out my previous post on this.
"... C++ uses short-circuit evaluation: if the first operand of the and is false, the second isn't evaluated because the whole expression would be false anyway. In other words, in C++ the only part of
if( SomethingFalse && SomeCondition )
that's evaluated is SomethingFalse. Evaluation stops as soon as SomethingFalse is identified as false."
This is also true in C#, if you have a case where you need both statements to execute regardless of whether it fails or passes, use a single & character. This is dangerous however, if your second condition depends on the first condition to be true.
For example...
if ( !string.IsNullOrEmpty( name ) & name == "mo" ) {}
In this scenario regardless of if the first condition is true or false, the second condition will be executed. This could raise a null reference exception if name is not initialized.
"One measure of ' programming complexity' is the number of mental objects you have to keep in mind simultaneously in order to understand a program. This mental juggling act is one of the most difficult aspects of programming and is the reason programming requires more concentration than other activities. It's the reason programmers get upset about ' quick interruptions' - such interruptions are tantamount to asking a juggler to keep three balls in the air and hold your groceries at the same time."
Enough said... I like to call it "being in the zone". When you're in and hammering away at the problem, the slightest interruption makes it so difficult to get back into "the zone" at the same speed. It's so important to find a good work area, where distractions are at a minimal. It shows in your work!
"The surprising implication is that people actually do what you ask them to do. Programmers have a high achievement motivation: They will work to the objectives specified, but they must be told what the objectives are."
I think this paragraph could be interrupted in many ways. When I first read it, my interpretation was about leadership. Having a good leader to direct and the team. It might be fun to watch chickens running around with their heads cut off, but it sure isn't fun being one of the chickens. Finding a good mentor or experienced leader to guide the team sure isn't easy to find.
The Strategy Pattern
Monday, July 02, 2007 3:32:53 PM (Mountain Standard Time, UTC-07:00)
"The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it." - Head First Design Patterns
This means that at runtime you can switch the algorithm being used by a particular object. In the example attached, there are a set of characters. Each characters has a weapon that they yield! At runtime, you can switch the type of weapon that a particular character is using.
For instance if the character king was constructed to use a default weapon, at runtime you could switch out the weapon that the king uses when he is fighting. This adheres to the open/closed principle, where the king object is open for extension but closed for modification.
In the future if we wanted to add new weapons, we can add them without having to change the implementation of the king object. This allows us to switch the type of weapon the king object is using at runtime!
King king = new King( );
king.Fight( );
king.Weapon = new Axe( );
king.Fight( );
king.Weapon = new BowAndArrow( );
king.Fight( );
For more information check out...
DesignPatterns.Strategy.zip (5.29 KB)
Domain Models
Tuesday, June 26, 2007 1:53:08 PM (Mountain Standard Time, UTC-07:00)
"A domain model is a static model of the structure of a problem domain. It models real-world concepts rather than software units." - Object-Oriented Systems Analysis and Design with UML
Domain models make it easy to see relationships between different components. A domain model is like a class diagram, it does not include concepts related to the UI, such as screens or grids.
Domain concepts are abstractions of things, persons or ideas.
E.g.
Department, Student, Course
Lot's to do...
Tuesday, June 12, 2007 11:15:52 AM (Mountain Standard Time, UTC-07:00)
Good Morning! It just so happens to be Tuesday, which means I've got a long day of work and school. My favorite!
Right now I am trying to read "Introduction to the theory of Computation", and it is hard. I can honestly say that as I'm reading it I am not absorbing everything, or that much at all. Probably having a background in discrete mathematics would come in handy. Either way, in between all the math are little gems of information that make it worth trying to push on through the book. It is regarded highly so I ought to push through!
I ordered "Head First Design Patterns" from Amazon, in early May. I'm still waiting for it to arrive, and I can't wait to read that. After that I want to gobble up "CLR via C#", "Domain Driven Design" and "Test Driven Development: By Example".
Lot's to read, so little time!
A couple of weeks ago I had my first performance review with my manager. He asked me if I was going to burn out? With a full time job, a wife and young daughter, school, and projects on the side.
Nahhh... I'll be fine, tired is for the weak! In fact... maybe I'll add more! hehe
Deadlock
Wednesday, May 30, 2007 7:20:18 PM (Mountain Standard Time, UTC-07:00)
A deadlock occurs when two or more threads are trying to access the same data but are blocking each other from getting at the resources necessary to continue.
internal class Program {
private static void Main( ) {
Deadlocker deadlock = new Deadlocker( );
Thread first = new Thread( new ThreadStart( deadlock.First ) );
Thread second = new Thread( new ThreadStart( deadlock.Second ) );
first.Start( );
second.Start( );
first.Join( );
second.Join( );
}
}
/// <summary>
/// 1. First thread starts and locks resourceA
/// 2. Second thread starts and locks resourceB
/// 3. First thread blocks waiting for resourceB to be freed.
/// 4. Second thread blocks waiting for resourceA to be freed.
/// 5. The application stops in it's tracks.
/// </summary>
internal class Deadlocker {
#region Public Methods
public void First( ) {
lock ( _resourceA ) {
lock ( ( _resourceB ) ) {
Console.WriteLine( "First" );
}
}
}
public void Second( ) {
lock ( _resourceB ) {
lock ( ( _resourceA ) ) {
Console.WriteLine( "Second" );
}
}
}
#endregion
#region Private Fields
private object _resourceA = new object( );
private object _resourceB = new object( );
#endregion
}
Remember that lock implicitly translates too...
lock ( _resourceB ) {
}
// translates too
Monitor.Enter( _resourceB);
try {
}
finally {
Monitor.Exit( _resourceB );
}
Instead of using Monitor.Enter(), you can use Monitor.TryEnter();
if ( !Monitor.TryEnter( _resourceB, TimeSpan.FromSeconds( 5 ) ) ) {
throw new TimeoutException( );
}
try {
}
finally {
Monitor.Exit( _resourceB );
}
For more info check out...
 |
MCTS Self-Paced Training Kit (Exam 70-536): Microsoft .NET Framework 2.0 Application Development Foundation by Tony Northrup, Shawn Wildermuth, Bill Ryan
Read more about this title... |
Assignment11.zip (9.12 KB)
Responding to change
Monday, May 28, 2007 11:59:58 AM (Mountain Standard Time, UTC-07:00)
The Agile Manifesto
Individuals and interactions... over processes and tools.
Working software... over comprehensive documentation.
Customer collaboration... over contract negotiation.
Responding to change... over following a plan.
I'm reading a book called.
I kept hearing this buzz word, I'm sure you've heard it. "Agile"! What does it really mean? If you scour Monster or Workopolis and search for .NET development jobs, just about everyone is asking for some sort of experience working with an Agile methodology. So what does this really mean to be Agile? The first thing that I have learned is this simple rule...
"You are not doing Agile, You are AGILE!"
I did a quick "define:agile" in Google and came across this definition:
"moving quickly and lightly;"
So what does this mean? Well... that I couldn't find a good definition on Google. What I'm learning is that there are many different processes that you can follow that are under this umbrella call the "Agile Methodology". Some of the most popular ones are "Scrum" and "XP".
Scrum:
"Scrum's distinctive emphasis among the methods is its strong promotion of self-organizing teams, daily team measurement, and avoidance of following predefined steps. Some key practices include a daily stand-up meeting (the Scrum meeting) with special questions, 30-day calendar iterations, and a demo to external stakeholders at the end of each iteration." - Agile and Iterative Development: A Manager's Guide
I think a lot of company's take some of the processes they like and mash them up together. I think stand-up meetings would work better, but I have never experienced one. (Try and convince a group of developers that you should stand up for the meeting, instead of sit like they have been... oh boy! ) I think that people tend to get comfortable in their seats and get off topic and a short meeting turns into a un productive time. Now if that happens every day, I wonder how much time is actually lost in a year.
XP:
"XP is probably the most well known agile method; it emphasizes collaboration, quick and early software creation, and skillful development practices. It is founded on four values: communication, simplicity, feedback, and courage. It includes 12 core practices, including the whole team working together in a common room, pair programming, constant refactoring, and test-driven development." - Agile and Iterative Development: A Manager's Guide
I instantly became a fan of the "XP" methodology after reading the above statement. I have begun to start trying to develop in a test-driven style and cannot turn back now. The ability to refactor, refactor and refactor without breaking changes and feel confident in my changes makes me a happy, productive programmer. When you win X number of little battles every day with test driven, or just state driven testing it makes you feel good every night that you go home. You can say... yes the code I've written is working, and working pretty darn well. So what if it's only a small component of the big picture.
So far this is my take on Agile... I have more to read, and learn.
Interface Based Programming
Monday, May 21, 2007 8:24:19 PM (Mountain Standard Time, UTC-07:00)
"By using the interface, I allow myself the advantage of making it easier to change implementations later on if I need to. Another implementation may provide performance improvements, some database interaction features, or other benefits. By programming to the interface rather than to the implementation, I avoid having to change all the code should I need a different implementation... You should always try to program to an interface like this; always use the most general type you can." - Martin Fowler -
Let's take a look at the following code as an example:
1 [Test]
2 public void GetStudents_ShouldReturnAllStudents( ) {
3 List< Student > students = _store.GetStudents( );
4 Assert.IsNotNull( students );
5 foreach ( Student student in students ) {
6 Console.WriteLine( student.FirstName + student.LastName );
7 }
8 }
The code above is tightly bound to a specialized type of collection, List<T>. If we crack open Lutz Reflector and take a look at the List<T> type we can see that it implements IList<T> and ICollection<T>.
If we wanted to code to an abstraction, in this case we have two options, IList<T>, ICollection<T>. (For the above test it would probably be best to use IEnumerable<T>, but let's assume we need to add items to the collection in client code.)
If we take a look at IList<T>...
As you can see IList<T> implements ICollection<T>. ICollection<T> does not implement IList<T>, it would be safe to say that ICollection<T> is the most generalized form of List<T> or IList<T>, which gives us the greatest flexibility to change the underlying implementation of "GetStudents()" in the future.
The final code looks more like this:
1 [Test]
2 public void GetStudents_ShouldReturnAllStudents( ) {
3 ICollection< Student > students = _store.GetStudents( );
4 Assert.IsNotNull( students );
5 foreach( Student student in students ) {
6 Console.WriteLine( student.FirstName + student.LastName );
7 }
8 }
As a side note, for this particular contrived example since ICollection<T> also implements IEnumerable<T> the above can be re-written as follows (without any changes to the implementation of GetStudents())
1 [Test]
2 public void GetStudents_ShouldReturnAllStudents( ) {
3 IEnumerable< Student > students = _store.GetStudents( );
4 Assert.IsNotNull( students );
5 foreach( Student student in students ) {
6 Console.WriteLine( student.FirstName + student.LastName );
7 }
8 }
Additional Resources:
- C# Interface Based Development
- The Interface Construct in C#
The Dispose Pattern
Thursday, May 17, 2007 7:48:42 PM (Mountain Standard Time, UTC-07:00)
Implementing the IDisposable interface can be a good idea, if done correctly! It allows you to clean up a lot of try... finally code and replace it with the fancy "using" blocks, because the "using" block implicitly invokes the dispose method and only works on types that implement IDisposable....
Lets say I define a type... (with a very poor name!)
1 public class Disposable : IDisposable
2 {
3 public void Dispose( )
4 {
5 throw new NotImplementedException( );
6 }
7 }
I could use the type like this....
1 public void Using( )
2 {
3 using ( Disposable myType = new Disposable( ) ) {
4 Console.WriteLine( myType );
5 }
6 }
Which is actually doing something like this...
1 public void TryFinally( )
2 {
3 IDisposable myType = null;
4 try {
5 myType = new Disposable( );
6 Console.WriteLine( myType );
7 }
8 finally {
9 if ( myType != null ) {
10 myType.Dispose( );
11 }
12 }
13 }
The proper implementation of the Dispose pattern looks like this block of code...
1 public class Disposable : IDisposable {
2 public Disposable( IDbConnection connection ) {
3 _connection = connection;
4 }
5
6 public void Dispose( ) {
7 Dispose( true );
8 GC.SuppressFinalize( this );
9 }
10
11 protected virtual void Dispose( Boolean disposing ) {
12 if ( disposing ) {
13 if ( _connection != null ) {
14 _connection.Close( );
15 }
16 }
17 }
18
19 private IDbConnection _connection;
20 }
So why do we need a protected virtual method named Dispose that takes in a boolean paramater, when the IDisposable interface only demands a method with a signature of public void Dispose()?
The boolean paramter tells if the method was invoked from the finalizer (aka destructor, which can be called at some unknown point in time by the garbage collector, which may be well after the resource has already been cleaned up by it's finalizer) or from client code explicitly calling the IDisposable.Dispose method. If the method is called from the finalizer, then disposing is false and it's not safe to touch any resources or other objects. (You don't want to raise exceptions in your finalizer!)
This makes sure that any resources used by your type does not get touched within the finalizer, since you can't tell if that resource has already been finalized by it's finalizer!
Since it's expected that your dispose will be cleaning up any resources used by your time, there is no sense in allowing your type to be finalized AGAIN! By calling GC.SuppressFinalize, you're telling the garbage collector not to finalize this type, because it has already been cleaned up. This should only be called if no exceptions are raised from your cleanup! (Which is why SuppressFinalize, should be called after the call to Dispose( true ) and not before!
For more information check out...
 |
Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (Microsoft .NET Development Series) by Krzysztof Cwalina, Brad Abrams
Read more about this title... |
http://msdn2.microsoft.com/en-us/library/system.gc.suppressfinalize(VS.71).aspx
http://msdn2.microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx
http://msdn2.microsoft.com/en-us/library/12afb1ea-3a17-4a3f-a1f0-fcdb853e2359(vs.80).aspx
Unsafe C#
Monday, May 14, 2007 11:46:24 AM (Mountain Standard Time, UTC-07:00)
Can you spot the overflow...?
1: using System;
2:
3: namespace UnsafeCode
4: { 5: public class Program
6: { 7: public static unsafe void Main( )
8: { 9: Int32[] array = new int[4];
10: for( int i = 0; i < 4; i++ ) { 11: array[ i ] = i * i;
12: }
13: Console.WriteLine( "Display 6 items (oops!)" );
14:
15: fixed( Int32* ptr = array ) { 16: for( int j = 0; j < 6; j++ ) { 17: Console.WriteLine( *( ptr + j ) );
18: }
19: }
20: Console.WriteLine( "Display all items" );
21: foreach( int k in array ) { 22: Console.WriteLine( k );
23: }
24: }
25: }
26: }
Pretty cool hey... you can use pointer in C#. You have to do a couple things though, in order to get it to work.
1. You have declare the block of code as unsafe
unsafe ... {
}
2. You have to tell the C# compiler to allow unsafe code. You can do this with the /unsafe switch or check the checkbox in the project settings.
3. You will also have to pin the objects you are pointing to, so that the garbage collector does not reclaim that memory. Use the fixed keyword. The following will pin the array so that it does not get reclaimed by the garbage collector.
fixed( Int32* ptr = array ) {
}
 |
Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (Microsoft .NET Development Series) by Krzysztof Cwalina, Brad Abrams
Read more about this title... |
So what's the big red fez
Tuesday, May 08, 2007 4:31:31 AM (Mountain Standard Time, UTC-07:00)
The Big Red Fez...
So I borrowed this book and it took me about an hour to read. The book is called
"The Big Red Fez: How to make any website better"It was a great read, very straight to the point and made a lot of sense... There were a lot of interesting points, the jist of it (as i understood it) was that engineers suck! Well maybe that wasn't the point but he really didn't seem to like engineers.
He basically said that building a web site is a lot like leading a monkey. If you want the monkey to follow you, you have to dangle a banana in front of him. If you don't give him a reason to follow you, he wont! If you confuse him or make it to difficult to get to the banana, he will give up.
The monkey translates to the average person who browses the web. The banana is a what is used to lead the user to follow you.. this doesn't mean flashy, sparkly stuff. The example he gave was the Amazon site.... If I go to the Amazon site right now... They want me to buy a gift for mothers day... pretty good banana!
Other items in the book that I thought was important was to have better ways of dealing with errors. Having a search yield 0 results, doesn't help anyone. If you go to a shoe store and ask them for something they don't have, does the salesperson say "Sorry your search yielded no results!". Rather the salesperson is probably going to try to find you something similar to try to get you buy in to... another banana!
Lot's of good stuff in this book. If you have an hour to read, it's worth it. It would probably take me longer to sum up the book then to actually read it!
Using the Google AJAX Search API
Friday, June 30, 2006 9:29:27 PM (Mountain Standard Time, UTC-07:00)
Google just released a brand new experimental API that lets you integrate dynamic search right in to your own web site. They have made this API so easy to use it really takes only a few minutes to implement, and the results can look professional and polished.
One of the greatest things so far about this API is the CSS control that it offers. This allows you to render your search control in the manner in which you would like it displayed. I also really like the tabbed search views offered and being able to create custom tabs. This allows you to add a "Site Search" tab to your search.
I would like to be able to control the number of search results returned, and add the ability to navigate back and forth through search results, similar to Google's own search page.
My original implementation was based on the example HTML page given when you generate a new AJAX search API key.
Lets take a look at the "OnLoad" function. This function is called as soon as the page loads, because the "onload" event is added to the <body> element . (<body onload="OnLoad()">")
"CDATA sections - A CDATA section is a block of text in which you can freely insert any characters except the string ]]>. Here's an example of a CDATA section in an element:" - sourced from "Step by Step XML" by Michael J. Young
- sourced from "Step by Step XML" by Michael J. Young
The "OnLoad" function then instantiates a "GSearchControl" object. This object is a container for the Google Search interface. Next you must add "searcher children" to the "GSearchControl" object. In the above example we have added 4 children. The local search, web search, video search and blog search "children".
For the local search child we set our center point or local reference to the city we wish to reference. In my case it is Calgary, Alberta. Next, we bind the "searchControl" to an html container using the "draw()" function. For more help visit Google AJAX Search API Class Reference.
In the above "OnLoad" function the "searchControl" binds to an HTML container titled "searchControl". In the body of our HTML page we created a simple div tag with an ID of "searchControl". When the search control renders it will update the content of this div element.
It is very simple to implement, and now you can customize your search control using CSS and the other API classes available. Check out my working example!