<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-36756501</id><updated>2024-11-18T10:54:28.607-08:00</updated><category term="Exception Exceptions  Java .NET Best Practice"/><category term="NHibernate XML Remember .NET"/><category term="Scrum Venture Capital Jeff Sutherland"/><category term="database model entity primary key development"/><title type='text'>OO Software Development</title><subtitle type='html'>Take a look if you are interested in finding spike solutions to solve programmers problems. It is also a place to debate impressions and opinions.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>36</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-36756501.post-1127881313208585516</id><published>2016-01-26T17:24:00.001-08:00</published><updated>2016-01-26T17:24:34.889-08:00</updated><title type='text'>Express business language in your code with use cases</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;h2&gt;
&lt;b&gt;Brief Introduction to Use Cases&lt;/b&gt;&lt;/h2&gt;
Use cases are a very important element in UML that addresses the functional aspect of a software. The use case diagram shows how the different system functionalities are associated to the different users in a system which are referred as actors.&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcKojPFNWxdQw4UYMhHD6RSlz-DCghJU2uU_QD1LHfv6GaAJsT3COeRlTEVQ8HTloQ6UUrW-5RN5NAHsBjqV1gF8fcJZ0j9CeJEo5xVmoVPNNPzUHXR52rpodypjWG1ow-HmNcEQ/s1600/use_case_tracebility.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcKojPFNWxdQw4UYMhHD6RSlz-DCghJU2uU_QD1LHfv6GaAJsT3COeRlTEVQ8HTloQ6UUrW-5RN5NAHsBjqV1gF8fcJZ0j9CeJEo5xVmoVPNNPzUHXR52rpodypjWG1ow-HmNcEQ/s400/use_case_tracebility.png&quot; width=&quot;378&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The specific user kind is referred in UML as an actor. Note in the diagram above that a system can have several kinds of actors and an actor can be specialized from an existing one. For instance both Student and Teacher are specialized from School Member. This means they can also execute the same use cases from School Member which can serve to group common functionalities.&lt;br /&gt;
&lt;br /&gt;
Also the objective of a use case is not just to describe a feature but to describe a business flow using a high level language that can be understood by the business expert on how a specific kind of user can achieve his goals.
&lt;br /&gt;
&lt;br /&gt;
For instance the &quot;Enroll in Subject&quot; use case can be described as follows:&lt;br /&gt;
&lt;br /&gt;
====================================================&lt;br /&gt;
&lt;b&gt;Project:&lt;/b&gt; My School System&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Subdomain:&lt;/b&gt; Enrollment&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Title:&lt;/b&gt; &amp;nbsp;Enroll in Subject&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Description:&lt;/b&gt; Describes how a subject can be enrolled to a student.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Precondition:&lt;/b&gt; student must be authenticated by the system.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Normal Flow:&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;(n1) System lists all available subjects which were not enrolled or completed by this student&lt;/li&gt;
&lt;li&gt;(n2) Student selects a subject&lt;/li&gt;
&lt;li&gt;(n3) System verifies if the subject is open for enrollment&lt;/li&gt;
&lt;li&gt;(n4) if subject is still open system enrolls student to it [a1]&lt;/li&gt;
&lt;li&gt;(n5) System sends a message to the student stating that the enrollment was successful&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;Alternative Flows:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;[a1] Subject is not open for enrollments:&lt;/u&gt; System sends a message to the user stating that the subject is not open for enrollment.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Integrity Constraints:&lt;/b&gt;&lt;br /&gt;
Student should not enroll in a subject he/she completed before.&lt;br /&gt;
&lt;br /&gt;
====================================================&lt;br /&gt;
&lt;br /&gt;
Use cases popular in the 90s and begining of 2000s almost disappeared after that and recently there has been some interest in it perhaps because software engineers have identified a need to better understand the business flow in more details than what can be found in use cases.&lt;br /&gt;
&lt;br /&gt;
However use cases present many advantages such as:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;u&gt;Common language for engineers and domain experts&lt;/u&gt;&amp;nbsp;- document can be the bridge between engineers and domain experts since it talks the language of the business in a structured way.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;u&gt;Technology independence&lt;/u&gt; - uses cases should not refer to specific technology in their descriptions such as web, http, button, dropdown, etc. - this way the contents continue to be useful even if those decisions change.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;&lt;u&gt;Enforces business flow&lt;/u&gt; - as described before the flow structure of use cases drive domain experts to think in a structured way and capture different situations helped also by engineers.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
More details and better explanation can be found the links at the end in the References section.&lt;br /&gt;
&lt;br /&gt;
However the point of this article is how to organize the software architecture and code style to reflect the business flow description provided by use cases.&lt;br /&gt;
&lt;h2&gt;
Organizing Code Around Use Cases&lt;/h2&gt;
The following practices can be taken to clearly express use cases in your code:&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;1)&amp;nbsp;Represent each use case as a class&lt;/b&gt;&lt;br /&gt;
The use case diagram above can be translated with the following class diagram:&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3RX7v7tYF17K2cTkZiv9xjkMZdh6dc6ajk4YhKGIMtS9zJzgE-4IWMcQK1ksaFWjhjhEcyQOH_ppS-EJ8ctoKzgaju5lsAuS_3rxbAYJyIm_NKFYdU0astHUM_17Vas-O-rTDpA/s1600/class_diagram.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;64&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3RX7v7tYF17K2cTkZiv9xjkMZdh6dc6ajk4YhKGIMtS9zJzgE-4IWMcQK1ksaFWjhjhEcyQOH_ppS-EJ8ctoKzgaju5lsAuS_3rxbAYJyIm_NKFYdU0astHUM_17Vas-O-rTDpA/s640/class_diagram.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Each class represent a function in the system. Note that sometimes a use case may describe more than one scenario what can happen in CRUD functionalities such as Student Registration (which is not listed in our example diagram).&lt;br /&gt;
&lt;br /&gt;
Note that the name of the class should match the use case.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2) Represent each use case flow step as a line of code&lt;/b&gt;&lt;br /&gt;
Code expression inside use case classes should reflect as much as possible the business flow description so to make it simpler and easier to correlate the documentation and code.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-ruby&quot;&gt;class UseCaseSubjectEnrollment
  def list_subjects(student)
    Subject.list_available_for_student(student) # (n1)
  end
  def enroll(student, subject)
    if subject.available_for_enrollment? # (n3) 
      student.enrolls(subject)           # (n4)
      { &quot;type&quot; =&amp;gt; &quot;success&quot;, &quot;message&quot; =&amp;gt; &quot;enrollment successful&quot; } # (n5)
    else
      { &quot;type&quot; =&amp;gt; &quot;failure&quot;, &quot;message&quot; =&amp;gt; &quot;failed enrollment&quot; } # (a1)
    end
  end
end&lt;/pre&gt;
&lt;br /&gt;
Note that the use case method is broken in two parts since one of the steps describes a user interaction: &quot;Student selects a subject&quot;. The numbers in the use case and in the code above is optional and merely to make it clear for the reader to see the relation between them.&lt;br /&gt;
&lt;br /&gt;
Before the user selection with list_subjects method and after the user selection with the enroll method. Due technological restrictions in web applications (at least in Ruby web applications) the user subject selection step is not represented in the use-case class but in the application layer presentation.&lt;br /&gt;
&lt;h2&gt;
Pros and Cons of Use Case Mapping to Code&lt;/h2&gt;
After some time using this approach for some years here are the positive and negative points:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pros:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;A change in a use case document can be easily implemented by software engineers&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Newcomers quickly understand how and where to do code modifications with little or no help&lt;/li&gt;
&lt;li&gt;Engineers start work from the beginning with the business goal what reduces common misunderstanding in &quot;what&quot; the feature of functionality should be and its goals&lt;/li&gt;
&lt;li&gt;Sometimes engineers can understand the business goal to the point of helping optimizing the business flow described by non-technical domain experts&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;Cons:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Includes one more step before engineers start developing software&lt;/li&gt;
&lt;li&gt;There is a considerable effort to keep use cases updated&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Doesn&#39;t pay off for highly dynamic and small websites where the business flow is simple and already known by engineers&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
In general it seems to me that the more complex a system is in term of business steps the better it is to start using use cases.&lt;/div&gt;
&lt;br /&gt;
&lt;h2&gt;
References&lt;/h2&gt;
[1] Writing effective use cases - Alistair Cockburn - http://alistair.cockburn.us/get/2465&lt;br /&gt;
&lt;br /&gt;
[2] The art of writing use cases - Rebecca Wirfs-Brock - http://www.wirfs-brock.com/PDFs/Art_of_Writing_Use_Cases.pdf&lt;br /&gt;
&lt;br /&gt;
[3] Domain driven design quickly - Abel Avram - Floyd Marinescu -&amp;nbsp;http://www.infoq.com/minibooks/domain-driven-design-quickly&lt;br /&gt;
&lt;br /&gt;
[4] &amp;nbsp; &amp;nbsp;http://www.artima.com/articles/dci_vision.html - Trygve Reenskaug and James O. Coplien - The DCI Architecture: A New Vision of Object-Oriented Programming&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/1127881313208585516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/1127881313208585516' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/1127881313208585516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/1127881313208585516'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2016/01/express-business-language-in-your-code.html' title='Express business language in your code with use cases'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcKojPFNWxdQw4UYMhHD6RSlz-DCghJU2uU_QD1LHfv6GaAJsT3COeRlTEVQ8HTloQ6UUrW-5RN5NAHsBjqV1gF8fcJZ0j9CeJEo5xVmoVPNNPzUHXR52rpodypjWG1ow-HmNcEQ/s72-c/use_case_tracebility.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-5221127951159924546</id><published>2015-07-26T18:09:00.000-07:00</published><updated>2015-07-26T18:09:12.132-07:00</updated><title type='text'>From static-language style API to Ruby style API</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;

It has passed some time since I published a &lt;a href=&quot;https://github.com/hcmarchezi/naive_bayes&quot;&gt;Naive_Bayes&lt;/a&gt; for text-classifier written in Ruby. At that time the API was designed very much influenced in way I have written a similar classifier in C++. However it was after a looked at the gem &lt;a href=&quot;https://github.com/danielsdeleo/Decider&quot;&gt;Decider&lt;/a&gt; that I realized how it was not taking advantage over the dynamic characteristics of Ruby to make Domain-Specific-Language APIs.

&lt;h2&gt;Static characteristics of my original Ruby classifier interface&lt;/h2&gt;

The following are the methods that called my attention:

&lt;h3&gt;Category declaration&lt;/h3&gt;

Use of &lt;i&gt;add_category&lt;/i&gt; method to declare new categories expects a category name and an array of strings as an example.

&lt;pre class=&quot;prettyprint lang-rb&quot;&gt;
classifier.add_category(name: :not_spam, training_set: [ &#39;Hi&#39;, &#39;Joe&#39;, &#39;how&#39;, &#39;are&#39;, &#39;you&#39; ])
&lt;/pre&gt;

&lt;h3&gt;Input classification&lt;/h3&gt;

The &lt;i&gt;classify&lt;/i&gt; method makes use of an array of string as input for classification.

&lt;pre class=&quot;prettyprint lang-rb&quot;&gt;
category = classifier.classify([&#39;Hi&#39;,&#39;James&#39;,&#39;are&#39;,&#39;you&#39;, &#39;going&#39;])
category.to_s # not_spam
&lt;/pre&gt;

&lt;h2&gt;Refactoring to new style&lt;/h2&gt;

&lt;h3&gt;Category declaration through method missing and string&lt;/h3&gt;

Instead of adding categories with a training set the user should only be required to provide examples to its desired with a dynamically created method which corresponds to a category name.

&lt;pre class=&quot;prettyprint lang-rb&quot;&gt;
classifier.not_spam &lt;&lt; &quot;Hi Joe, how are you&quot;
&lt;/pre&gt;

&lt;h3&gt;Input classification from string&lt;/h3&gt;

Instead of requiring the user to break the string in an array the entire string can be classified. The classifier should also take the responsibility of breaking the string in words.

&lt;pre class=&quot;prettyprint lang-rb&quot;&gt;
category = classifier.classify &quot;Hi James,are you going ?&quot;
category.to_s # not_spam
&lt;/pre&gt;


&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/5221127951159924546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/5221127951159924546' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/5221127951159924546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/5221127951159924546'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2015/07/from-static-language-style-api-to-ruby.html' title='From static-language style API to Ruby style API'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-8222901862830268327</id><published>2015-01-26T19:21:00.002-08:00</published><updated>2015-01-29T19:31:20.594-08:00</updated><title type='text'>Create an Agnostic Vendor Infrastructure in Ruby</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Depending how the code was written adding new services to it can be difficult.&lt;br /&gt;
For instance, let&#39;s say we are building a rails application that gets integrated to cloud storage vendors.&lt;br /&gt;
A naive implementation would be to directly integrate to a cloud storage specific APIs.&lt;br /&gt;
In this case when new cloud storage vendors are added it is very probable that several nasty &lt;b&gt;case... when ... end&lt;/b&gt;&amp;nbsp;statements would be inserted in code.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/hcmarchezi/4e46cee7cca60d46075b.js&quot;&gt;&lt;/script&gt;

When a new cloud storage service is added the developer must remember all places where those growing case-like statements are inserted. This makes the system more susceptible to errors due to &amp;nbsp;changes in several parts of the code. This problem is explained in detail by the shotgun surgery anti-pattern (&lt;a href=&quot;http://en.wikipedia.org/wiki/Shotgun_surgery&quot;&gt;http://en.wikipedia.org/wiki/Shotgun_surgery&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
The rest of the system shouldn&#39;t be aware that a new cloudstorage service was added. That is where a combination of design patterns come in handy:&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;a facade to provide a simple interface for cloud storage operations&amp;nbsp;&lt;/li&gt;
&lt;li&gt;a service locator to find the right cloud storage adapter&lt;/li&gt;
&lt;li&gt;a cloud storage adapters that make each vendor API compliant to a single defined interface that can be understood by the facade&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;img src=&quot;https://docs.google.com/drawings/d/1KjeuJpOAId3tUyO41OAfSVL-9rFSNxDCIbnOY--dBaA/pub?w=590&amp;amp;h=561&quot; /&gt;
&lt;br /&gt;
&lt;b&gt;1) Cloud Storage Facade&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/hcmarchezi/33bc4cc7653a7e6dc843.js&quot;&gt;&lt;/script&gt;

&lt;b&gt;2) Cloud Storage Adapter Locator&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/hcmarchezi/508024a6baff045c09c2.js&quot;&gt;&lt;/script&gt;

&lt;b&gt;3) Cloud Storage Adapters&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/hcmarchezi/3d668d7ad9ff851a7420.js&quot;&gt;&lt;/script&gt;

Note that this combination of patterns can be used to abstract many other types of services. Cloud storage service was just an example used here.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/8222901862830268327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/8222901862830268327' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8222901862830268327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8222901862830268327'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2015/01/create-agnostic-vendor-infrastructure.html' title='Create an Agnostic Vendor Infrastructure in Ruby'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-8107068882033330649</id><published>2013-12-18T17:17:00.001-08:00</published><updated>2013-12-19T04:29:08.888-08:00</updated><title type='text'>Rails: New Framework - Old Design Problems</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
I have been&amp;nbsp;programming&amp;nbsp;for Rails for about 2-3 years now. As I came from a C# background it was a bit&amp;nbsp;awkward for me to see some design principles I took as good practices being unashamedly broken such as:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;data-driven models mixed with persistence logic instead of plain old domain objects&lt;/li&gt;
&lt;li&gt;controllers being used as application scenarios instead of coordinators between my actual application object and the view ( that was my understanding of MVC )&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
At that time I just thought it was the &lt;i&gt;ruby-on-rails&lt;/i&gt; way of doing things and as a good newcomer in the ruby developer community I decided I should learn and listen more from other rails developers and forums than telling what the best practices should be.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
However after some years of work experience I realized some of those design problems were not sufficiently addressed for some anti-patterns: ( At least not until this year - some problems are still not addressed )&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;fat controllers / skinny models&lt;/li&gt;
&lt;li&gt;skinny controllers / fat models&lt;/li&gt;
&lt;li&gt;god models&lt;/li&gt;
&lt;li&gt;transparent polyglot persistence in domain models ( SQL, NoSQL, Graph, etc ... )&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Note that these design problems were solved in other programming environments long ago.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Now with the maturity of rails developer&amp;nbsp;community&amp;nbsp;and the increasing adoption of rails in many enterprises I see design patterns and ideas being presented more often.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
The objective of these ideas seems to be the same: keep active record models focused only on data and extracting out logic of any kind ( business, view, etc.. ) to other classes or modules.&lt;/div&gt;
&lt;div&gt;
Some ideas that called my attention are:&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;Use of service objects that orchestrate rails models in handling complex&amp;nbsp;scenarios&lt;/li&gt;
&lt;li&gt;Use of rails concerns (modules) to extract behavior or methods that do not belong to the model responsibility (which in rails means data persistence and validation)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Some oppose to rails concerns because it can lead your rails model class to have many roles instead of one-role. ( This is a popular clean code principle: one class, one role )&lt;/div&gt;
&lt;div&gt;
However in his article DHH gave good reasons for doing it what actually made me open an exception for this clean code principle for this particular ruby case. ( I am a clean code fan and exceptions are rare)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In this case this clean code principle of one-role-class became a bit different for me after reading DHH article (see reference below in chubby models):&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;one class should have one &lt;b&gt;IMPLEMENTATIONAL&lt;/b&gt;&amp;nbsp;role.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
In Ruby a &lt;b&gt;rails model should implement only ONE role&lt;/b&gt; while it can be injected by many others.&lt;/div&gt;
&lt;div&gt;
For instance it is not a problem that your class contain many roles since they come from mixins.&lt;/div&gt;
&lt;div&gt;
However mixins (or Rails concerns) should augment the rails model features and not make your class implementation dependent on them. It is not forbidden to be dependent on mixins such as by active record or mongoid since they are part of the &lt;b&gt;one implementational role&amp;nbsp;defined for the class&lt;/b&gt; but some caution is needed.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In the other hand the idea of using a service object can make it clear that some complex business concepts are executed separately. Scenarios include payment process, authentication and many others. Its benefit is very clear to me.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Both ideas are of great help to keep both controllers and models on a diet ( skinny controller / skinny models ) but other design problems such as transparent polyglot persistence and possible many others remain unanswered.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I hope to see what the ruby community will have to say about that in the future.&lt;/div&gt;
&lt;div&gt;
Maybe I can answer some of those questions, who knows ?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
References:&lt;/div&gt;
&lt;div&gt;
&lt;a href=&quot;http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/&quot;&gt;http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href=&quot;http://37signals.com/svn/posts/3372-put-chubby-models-on-a-diet-with-concerns&quot;&gt;http://37signals.com/svn/posts/3372-put-chubby-models-on-a-diet-with-concerns&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/8107068882033330649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/8107068882033330649' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8107068882033330649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8107068882033330649'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2013/12/rails-new-framework-old-design-problems.html' title='Rails: New Framework - Old Design Problems'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-7879897147609267993</id><published>2012-12-06T19:10:00.001-08:00</published><updated>2012-12-06T19:10:54.492-08:00</updated><title type='text'>RORM - Ruby Domain Objects with Persistence</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
After some time using ActiveRecord and MongoId, I decided it was time to create a ruby ORM for domain objects as my first github project.&lt;br /&gt;
https://github.com/hcmarchezi/rorm/blob/master/README.md&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/7879897147609267993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/7879897147609267993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/7879897147609267993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/7879897147609267993'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2012/12/rorm-ruby-domain-objects-with.html' title='RORM - Ruby Domain Objects with Persistence'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-7045150221460318855</id><published>2012-11-12T17:48:00.000-08:00</published><updated>2012-11-12T17:48:11.989-08:00</updated><title type='text'>Separated Interface Design Pattern</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;b id=&quot;internal-source-marker_0.3536250675097108&quot; style=&quot;font-weight: normal; text-align: -webkit-auto;&quot;&gt;&lt;/b&gt;&lt;br /&gt;
&lt;h1 dir=&quot;ltr&quot;&gt;
&lt;b id=&quot;internal-source-marker_0.3536250675097108&quot; style=&quot;font-weight: normal; text-align: -webkit-auto;&quot;&gt;&lt;b id=&quot;internal-source-marker_0.3536250675097108&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;When developing a system in many cases it is possible to identify dependencies among different layers whose responsibilities are well defined in the system.&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;b id=&quot;internal-source-marker_0.3536250675097108&quot; style=&quot;font-weight: normal; text-align: -webkit-auto;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Some examples of layer dependencies are:&lt;/span&gt;&lt;br /&gt;&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Controller layer dependency and UI layer&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Domain logic layer and persistence layer&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;One strategy to remove dependencies between layers is to use the separated interface design pattern. This pattern consists of defining an interface from the bottom layer that is going to be used by the top layer. See diagram below &amp;nbsp;to understand how it works for controller and UI layer:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;img height=&quot;468px;&quot; src=&quot;https://docs.google.com/drawings/image?id=sCc_ncfu15Z_cXf4Jx28UdQ&amp;amp;w=589&amp;amp;h=468&amp;amp;rev=316&amp;amp;ac=1&quot; width=&quot;589px;&quot; /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;The controllers in the example above only reference interface views and never know which view implementation they are actually working with.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;This design pattern is recommended for a system when:&lt;/span&gt;&lt;br /&gt;&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;One layer (such as a controller) will be reused to be plugged into different versions of the other layer (such as HTML5 and native view layer implementations)&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Layers are easier to be tested in isolation&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;It is not desired that one layer has API dependencies from the other layer&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;References:&lt;/span&gt;&lt;br /&gt;&lt;ul style=&quot;margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;
&lt;li style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Martin Fowler, Patterns of Enterprise Application Architecture, Separated Interface, Pages 475-479&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Separated Interface, &lt;/span&gt;&lt;a href=&quot;http://martinfowler.com/eaaCatalog/separatedInterface.html&quot;&gt;&lt;span style=&quot;color: #1155cc; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;http://martinfowler.com/eaaCatalog/separatedInterface.html&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;font-family: Arial; font-size: 15px; list-style-type: disc; vertical-align: baseline;&quot;&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Developing Software for Multi Mobile Devices, &lt;/span&gt;&lt;a href=&quot;http://martinfowler.com/articles/multiMobile/&quot;&gt;&lt;span style=&quot;color: #1155cc; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;http://martinfowler.com/articles/multiMobile/&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/7045150221460318855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/7045150221460318855' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/7045150221460318855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/7045150221460318855'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2012/11/separated-interface-design-pattern.html' title='Separated Interface Design Pattern'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-4742082580846265882</id><published>2011-08-28T20:18:00.000-07:00</published><updated>2015-07-16T16:41:36.487-07:00</updated><title type='text'>JavaScript: Object Oriented Programming</title><content type='html'>By using functions and the structures above it is possible to a function object which syntax works just like a C++/Java class. See examples below.


&lt;h2&gt;Classes&lt;/h2&gt;


In JavaScript classes are declared as functions.

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
function Task(name,dueDate)
{
    this.name = name;
    this.dueDate = dueDate;
};
var myTask = new Task(&quot;Clean house&quot;,&quot;2011-07-01&quot;);
myTask.name = &quot;some new name&quot;;
&lt;/pre&gt;


&lt;h2&gt;Methods&lt;/h2&gt;


Methods are declared by extending the function prototype. 

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
var User = function(email,password) {
    this.email = &quot;&quot;; // public field
    this.password = &quot;&quot;;
};
User.prototype.generatePassword = function() {  // public method
    this.password = &quot;generatedpass&quot;;
}
var user = new User(&quot;you@email.com&quot;,&quot;mypassword&quot;);
user.generatePassword(); // password is generatedpass
&lt;/pre&gt;

Alternatively methods can be declared inside the function declaration.

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
var User = function(email,password) {
    this.email = &quot;&quot;;
    this.password = &quot;&quot;;
    this.generatePassword = function() { 
        this.password = &quot;generatedpass&quot;;
    };
};
&lt;/pre&gt;


&lt;h2&gt;Inheritance&lt;/h2&gt;


In order to make a class inherit from another class, the subclass prototype must be set to the desired parent object. It is also necessary to set the constructor as the current class which is a little od. See example below.

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
function Person() {
    this.firstname = &quot;James&quot;;
};
Person.prototype.generateName = function() {
    this.firstname = &quot;generatedname&quot;;
};

function Student() {
    this.school = &quot;Rahway School&quot;;
};
Student.prototype = new Person();
Student.prototype.constructor = Student;
Student.prototype.setBestSchool = function() {
    this.school = &quot;Best school in town&quot;;
};
&lt;/pre&gt;


&lt;h2&gt;Polymorphism&lt;/h2&gt;


Polymorphism can be achieved by simply declaring methods with the same name.
Consider the hierarchy of figures as an example below.

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
function Photo() {    
}
Photo.prototype.getDestinationPath = function() { 
    return &quot;./photos/common&quot;;
};
function PartyPhoto() {
}
PartyPhoto.prototype = new Photo();
PartyPhoto.prototype.constructor = PartyPhoto;
PartyPhoto.prototype.getDestinationPath = function() {
    return &quot;./photos/parties&quot;;
};

photo = new Photo();
photo.getDestinationPath(); // path for common photos

partyPhoto = new PartyPhoto();
partyPhoto.getDestinationPath(); // path for party photos
&lt;/pre&gt;


&lt;h2&gt;Encapsulation&lt;/h2&gt;


In the examples above all attributes and methods were public. In order to declare private attributes or methods one solution is to follow the template code below: (taken from http://www.codeproject.com/KB/scripting/jsoops.aspx )

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
function MyClass(){    
    //Private members
    return{
        //Public members
    }}
&lt;/pre&gt;

An App class can be implemented as:

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
function App(appname,description) {
    var _name = appname;
    var _description = description
    return {
        getName: function() { return _name; },
        getDescription: function() { return _description; },
        setName: function(appname) { _name = appname; },
        setDescription: function(description) { _description = description; }
    };    
}
var myApp = new App(&quot;voila&quot;,&quot;my game&quot;);
var.setName(&quot;other game&quot;);
&lt;/pre&gt;

Please note that this approach does not offer a way to have encapsulation and inheritance at the same time. Read next section to know one way to achieve this.


&lt;h2&gt;Inheritance with Encapsulation&lt;/h2&gt;


By experimenting with the approach above, I found out a different way that made it possible to have both encapsulation and inheritance in JavaScript. The idea is to declare private members as function variables as above and then augment the parent object with the desired public functions. Thus it is not necessary to work with prototypes.
Take the generic Person class as an example:

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
function Person(name) {
    // Private Members
    var _name = &quot;&quot;;
    // Public Members (accesses private members)
    var obj = new Object();
    obj.setName = function(name) { _name = name; };
    obj.getName = function() { return _name;  };  
    // Constructor
    obj.setName(name);
    return obj;
};
&lt;/pre&gt;

A person instance will have access to getName and SetName but not _name attribute and therefore we have encapsulation.
For a Student class that inherits from Person, the code would be:

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
function Student(name,school) {
    // Private Members
    var _school = &quot;&quot;;
    // Creating parent object: Studen inherits from Person
    var parent = new Person(name);
    // Augmenting parent object with Student methods
    parent.setSchool = function(school) { _school = school; };
    parent.getSchool = function() { return _school; };
    // Constructor Logic (Initialization)
    parent.setSchool(school);
    return parent;
};
&lt;/pre&gt;


These functions can be used just like normal classes:

&lt;pre class=&#39;prettyprint lang-js&#39;&gt;
var person = new Person(&quot;James&quot;);
person._name; // undefined
person.getName(); // James

var student = new Student(&quot;Jack&quot;,&quot;Orange City School&quot;);
student._name;        // undefined
student.getName();  // Jack
student._school;       // undefined
student.getSchool(); // Orange City School
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/4742082580846265882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/4742082580846265882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/4742082580846265882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/4742082580846265882'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2011/08/javascript-object-oriented-programming.html' title='JavaScript: Object Oriented Programming'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-6444516802475935421</id><published>2011-02-27T12:40:00.000-08:00</published><updated>2011-02-27T17:49:43.329-08:00</updated><title type='text'>iPhone Development: to Objective-C or not to Objective-C ?</title><content type='html'>When I think of Objective-C, what comes to my mind is a niche programming language for the MacOS and Apple related products. Thus as far as I know this is the only officially supported language to develop products for iPhones, iPods, iPads and so on ....&lt;br /&gt;
On the other hand I really what to develop apps that will work in Windows, Linux and MacOS, and for this purpose I see two options:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1) Develop in C/C++ and try to find tools that translate this code to Objective-C and/or MacOS&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2) Use Objective-C to develop any kind of application (at least desktop and mobile apps)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Developing portable iPhone apps outside Objective-C&lt;/h2&gt;&lt;br /&gt;
&lt;h3&gt;Swig&lt;/h3&gt;For the first option, there is swig ( http://www.swig.org/ ) which is a wrapper for C++ to export its classes and/or functions to several languages (Objective-C is a work in progress).&lt;br /&gt;
However it doesn´t really solve the problem because there are libraries.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Mono Touch&lt;/h3&gt;The Mono Touch ( http://monotouch.net/ ) is probably one of the most interesting project to develop apps for the iPhone without Objective-C. It makes it possible to develop apps with C#.NET. The same Mono project also make it possible to develop apps for Linux. As a consequence, C#.NET could be seriously considered to develop apps for a wide range of platforms. However unlike Mono one must pay to start using it which may not be a problem if you are familiarized with C#.NET.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;PhoneGap&lt;/h3&gt;Another options is PhoneGap ( http://www.phonegap.com ) which is an open-source framework whose objective is to let developers to write apps with HTML5+CSS+JavaScript and execute it to the different mobile platforms including iOS. &lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Objective-C as a portable programming language&lt;/h2&gt;&lt;br /&gt;
I recently read about he mechanics and philosophy of Objective-C language and I got quite impressed by its features. It is not just C with classes as I heard before, it is actually a powerful dynamic language. Everything is an object including the classes itself what reminds me of Smalltalk, LISP and Python.&lt;br /&gt;
&lt;br /&gt;
There are also some options to use Objective-C outside of the Apple ecosystem:&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;GNU Step&lt;/h3&gt;As stated in their website ( http://www.gnustep.org/ ) the objective is to create an open version of Cocoa (former NextStep) for several platforms including Linux and Windows.&lt;br /&gt;
&lt;br /&gt;
Besides porting the API this project also comes with several developer tools such as an IDE named &lt;b&gt;ProjectCenter&lt;/b&gt; and a GUI code generator called &lt;b&gt;Gorm&lt;/b&gt;.</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/6444516802475935421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/6444516802475935421' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/6444516802475935421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/6444516802475935421'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2011/02/iphone-developtment-to-objective-c-or.html' title='iPhone Development: to Objective-C or not to Objective-C ?'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-5204040479067409846</id><published>2011-02-27T09:23:00.000-08:00</published><updated>2015-07-15T09:04:28.895-07:00</updated><title type='text'>Publishing ClickOnce winforms applications with command-line MSBuild</title><content type='html'>One of the most interesting characteristics of tools such as CCNet and Nant is the automated deploy.
I found many examples of how to publish an application with pre-configured projects with click-one but I wanted to do it different.
In order to make the project file cleaner the approach was to remove all click-once configurations from the project(*.csproj) so that command-line MSBuild will take care of publication configuration in a NAnt script.
After some full-days of research, I found the solution below. I hope it helps in your project.

&lt;pre class=&#39;prettyprint lang-xml&#39;&gt;
&amp;lt;exec program=&amp;quot;${dotnetFrameworkDir}\MSBuild.exe&amp;quot;&amp;gt;
  &amp;lt;arg value=&amp;quot;${basePath}\MyProject\MyProject.csproj&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/target:publish&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:IsWebBootstrapper=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:SignManifests=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:ManifestKeyFile=${basePath}\MyProject\MyCertificate.pfx&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:TargetZone=LocalIntranet&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:GenerateManifests=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:PublishUrl=${clickOnceDir}&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:Install=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:InstallFrom=Web&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:UpdateEnabled=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:UpdateRequired=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:InstallUrl=http://myPublishUrlAddress&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:TargetCulture=pt-BR&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:ProductName=MyProject&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:PublisherName=MyCompany&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:MinimumRequiredVersion=${CCNetLabel}&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:CreateWebPageOnPublish=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:WebPage=${webPage}&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:OpenBrowserOnPublish=false&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:ApplicationRevision=17&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:ApplicationVersion=${CCNetLabel}&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:CreateDesktopShortcut=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:PublishWizardCompleted=true&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:BootstrapperComponentsLocation=Absolute&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:BootstrapperComponentsUrl=${bootstrapperUrl}&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:GenerateBootstrapperSdkPath=${pathBootStrapper}&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
  &amp;lt;arg value=&amp;quot;/p:UpdateUrlEnabled=false&amp;quot;&amp;gt;&amp;lt;/arg&amp;gt;
&amp;lt;/exec&amp;gt;
&lt;/pre&gt;

&lt;!--
&lt;pre class=&#39;prettyprint&#39;&gt;
&lt;exec program=&quot;${dotnetFrameworkDir}\MSBuild.exe&quot;&gt;
  &lt;arg value=&quot;${basePath}\MyProject\MyProject.csproj&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/target:publish&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:IsWebBootstrapper=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:SignManifests=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:ManifestKeyFile=${basePath}\MyProject\MyCertificate.pfx&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:TargetZone=LocalIntranet&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:GenerateManifests=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:PublishUrl=${clickOnceDir}&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:Install=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:InstallFrom=Web&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:UpdateEnabled=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:UpdateRequired=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:InstallUrl=http://myPublishUrlAddress&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:TargetCulture=pt-BR&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:ProductName=MyProject&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:PublisherName=MyCompany&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:MinimumRequiredVersion=${CCNetLabel}&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:CreateWebPageOnPublish=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:WebPage=${webPage}&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:OpenBrowserOnPublish=false&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:ApplicationRevision=17&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:ApplicationVersion=${CCNetLabel}&quot;&gt;&lt;/arg&gt;

  &lt;arg value=&quot;/p:CreateDesktopShortcut=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:PublishWizardCompleted=true&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:BootstrapperComponentsLocation=Absolute&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:BootstrapperComponentsUrl=${bootstrapperUrl}&quot;&gt;&lt;/arg&gt;

  &lt;arg value=&quot;/p:GenerateBootstrapperSdkPath=${pathBootStrapper}&quot;&gt;&lt;/arg&gt;
  &lt;arg value=&quot;/p:UpdateUrlEnabled=false&quot;&gt;&lt;/arg&gt;
&lt;/exec&gt;
&lt;/pre&gt;
--&gt;</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/5204040479067409846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/5204040479067409846' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/5204040479067409846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/5204040479067409846'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2011/02/publishing-clickonce-winforms.html' title='Publishing ClickOnce winforms applications with command-line MSBuild'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-1231348666562030155</id><published>2010-06-03T11:50:00.000-07:00</published><updated>2010-06-03T11:50:38.300-07:00</updated><title type='text'>Tools and Utilities for the .NET Developer</title><content type='html'>Here is a list I got from the internet that might be useful (at least for a while):&lt;br /&gt;
&lt;br /&gt;
http://geekswithblogs.net/mbcrump/archive/2010/05/25/tools-and-utilities-for-the-.net-developer.aspx</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/1231348666562030155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/1231348666562030155' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/1231348666562030155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/1231348666562030155'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2010/06/tools-and-utilities-for-net-developer.html' title='Tools and Utilities for the .NET Developer'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-4559241205275067502</id><published>2010-05-09T19:08:00.000-07:00</published><updated>2015-07-14T20:12:36.418-07:00</updated><title type='text'>Using Fluent Builder Pattern to Configure Test Objects</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Depending on the complexity of the domain model, configuring mock objects for specific cenarios can make the resulting test code to get messy.  &lt;br /&gt;
&lt;br /&gt;
Consider the situation below with C#, NUnit and Moq framework&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;[Test]
[ExpectedException(InvalidPaymentAgreementException)]
public void PaymentAgreementMustNotBeCreatedWhenThePaymentOptionIsNotValidForTheDebtType()
{
  Mock&lt;PaymentOption&gt; somePaymentOptionMock = new Mock&lt;PaymentOption&gt;();
  Mock&lt;DebtType&gt; debTypeMock = new Mock&lt;DebtType&gt;();
  debtTypeMock
    .Setup(debtType.GetPaymentOptions())
    .Returns(new List&lt;PaymentOption&gt;(){somePaymentOptionMock.Object});

  Mock&lt;PaymentOption&gt; anotherPaymentOptionMock = new Mock&lt;PaymentOption&gt;();

  Mock&lt;Debt&gt; debtMock = new Mock&lt;Debt&gt;();
  debtMock.Setup(debt.DebtType).Returns(debTypeMock.Object);            

  PaymentAgreement paymentAgreement = new PaymentAgreement(
    new PaymentAgreementCreationParameter()
    {
      AgreementYear = SystemDate.Get().Value.Year,
      AgreementNumber = 1,
      AgreementCreationDate = SystemDate.Get().Value.Date,
      NumberOfInstallments = 1,
      AgreementValue = 100.0m,
      Debts = new List&lt;Debt&gt;() { debtMock.Object },
      SelectedPaymentOption =  anotherPaymentOptionMock.Object
    });
}
&lt;/pre&gt;
&lt;br /&gt;
A developer who reads the unit test can take a consirable amount of time to understand what is actually being tested even if a well-designed mock framework such as Moq is in use. Most of this work is about configuring mock objects. Besides the code size, the unit test doesn´t speak the language of the domain (business) and thus it becomes a mass of meaningless mock configuration. &lt;br /&gt;
I am on my way to learn how to apply TDD effectvely in software development and I quickly realized that the quality of unit tests are very important in order to this kind of methodology to succeed. &lt;br /&gt;
&lt;br /&gt;
Accidentally some days I read an interesting post from Andrian about Rich Domain Tests at http://adrianhummel.wordpress.com/ and I decided to apply his idea.&lt;br /&gt;
After reading his post I got to the conclusion that one way to solve or at least minimize this unit-test-messy-code-problem was by using a fluent builder pattern to configure mock objects by using a builder whose interface could be describe how I am configuring a mock object with an interface closer to domain language.&lt;br /&gt;
&lt;br /&gt;
The unit test below is a rewritten from the example above with the concepts described here:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;[Test]
[ExpectedException(InvalidPaymentAgreementException)]
public void PaymentAgreementMustNotBeCreatedWhenThePaymentOptionIsNotValidForTheDebtType()
{
  PaymentOption somePaymentOption = PaymentOptionMockBuilder
                                    .Begin()
                                    .BuildPaymentOption();

  DebtType debtType = DebtTypeMockBuilder
                      .Begin()  
                      .AddPaymentOptionOf(somePaymentOption)
                      .BuildDebtType();
            
  PaymentOption anotherPaymentOption = PaymentOptionMockBuilder
                                       .Begin()
                                       .BuildPaymentOption();          
            
  Debt debt = DebtMockBuilder
              .Begin()
              .WithDebtTypeOf(debtType)
              .BuildDebt();

  PaymentAgreement paymentAgreement = new PaymentAgreement(
    new PaymentAgreementCreationParameter()
    {
      AgreementYear = SystemDate.Get().Value.Year,
      AgreementNumber = 1,
      AgreementCreationDate = SystemDate.Get().Value.Date,
      NumberOfInstallments = 1,
      AgreementValue = 100.0m,
      Debts = new List &amp;amp;lt Debt &amp;amp;gt () { debt},
      SelectedPaymentOption =  anotherPaymentOption
    });

}
&lt;/pre&gt;
&lt;br /&gt;
The fluent builder for Debt is DebtMockBuilder and can be programmed as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;
    public class DebtMockBuilder
    {
        private Mock&lt;Debt&gt; _debtMock;

        public static DebtMockBuilder Begin()
        {
            DebtMockBuilder builder = new DebtMockBuilder();
            builder._debtMock = new Mock&lt;Debt&gt;();
            return builder;
        }

        public Debt BuildDebt()
        {
            return _debtMock.Object;
        }

        public DebtMockBuilder WithDebtTypeOf(DebtType debtType)
        {
            this._debtMock.Setup(debt =&gt; debt.DebtType).Returns(debtType);
            return this;
        }
    }
&lt;/pre&gt;
&lt;br /&gt;
PaymentOptionMockBuilder follows the same idea.&lt;br /&gt;
&lt;br /&gt;
Although I see that some improvements are needed I could see the following advantages from fluent mock builders:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The test code was easier to understand because domain terms were applied instead of specific API language.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Specific mock framework calls were encapsulated which theoretically can let programmers to use another mock framework in other projects or using more than one mock framework in the same test (I dont know why someone would do such a thing...).&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Finally mock configuration becomes more flexible since existing methods don´t have to be modified to include new configuration but only a new configuration method is needed. Thus mock configuration can evolve as needed without loosing the domain interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/4559241205275067502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/4559241205275067502' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/4559241205275067502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/4559241205275067502'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2010/05/using-fluent-builder-pattern-to.html' title='Using Fluent Builder Pattern to Configure Test Objects'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-7805844662808811783</id><published>2010-05-08T15:54:00.000-07:00</published><updated>2010-05-08T15:57:49.449-07:00</updated><title type='text'>Test-Driven-Development Best Practices</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;I recently read a very intersting conversation in StackOverflow.com about test-driven development.&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;I found it very instersting and the principles can be summarized as follows: (not ordered by importance)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;1. &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Write the test first, then the code.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Reason: This ensures that you write testable code and that every line of code gets tests written for it.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;2. &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Design classes using dependency injection.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Reason: You cannot mock or test what cannot be seen.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;3. &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Separate UI code from its behavior using Model-View-Controller or Model-View-Presenter.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Reason: Allows the business logic to be tested while the parts that can&#39;t be tested (the UI) is minimized.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;4. &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Do not write static methods or classes.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Reason: Static methods are difficult or impossible to isolate and Rhino Mocks is unable to mock them.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;5. &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Program off interfaces, not classes.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Reason: Using interfaces clarifies the relationships between objects. An interface should define a service that an object needs from its environment. Also, interfaces can be easily mocked using Rhino Mocks and other mocking frameworks.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;6. &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Isolate external dependencies.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Reason: Unresolved external dependencies cannot be tested.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;7. &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Mark as virtual the methods you intend to mock.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Reason: Rhino Mocks is unable to mock non-virtual methods.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;8. Use creational design patterns.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;This will assist with DI, but it also allows you to isolate that code and test it independently of other logic.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;9. Write tests using&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;a href=&quot;http://weblogs.java.net/blog/wwake/archive/2003/12/tools_especiall.html&quot; style=&quot;color: #114170;&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Bill Wake&#39;s Arrange/Act/Assert technique&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;This technique makes it very clear what configuration is necessary, what is actually being tested, and what is expected.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;10. Don&#39;t be afraid to roll your own mocks/stubs.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Often, you&#39;ll find that using mock object frameworks makes your tests incredibly hard to read. By rolling your own, you&#39;ll have complete control over your mocks/stubs, and you&#39;ll be able to keep your tests readable. (Refer back to previous point.)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;11. Avoid the temptation to refactor duplication out of your unit tests into abstract base classes, or setup/teardown methods.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Doing so hides configuration/clean-up code from the developer trying to grok the unit test. In this case, the clarity of each individual test is more important than refactoring out duplication.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;12. Implement Continuous Integration.&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Check-in your code on every &quot;green bar.&quot; Build your software and run your full suite of unit tests on every check-in. (Sure, this isn&#39;t a coding practice, per se; but it is an incredible tool for keeping your software clean and fully integrated.)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Reference:&lt;/span&gt;&lt;/b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://stackoverflow.com/questions/124210/best-practices-of-test-driven-development-using-c-and-rhinomocks&quot; style=&quot;color: #114170;&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;http://stackoverflow.com/&lt;wbr&gt;&lt;/wbr&gt;questions/124210/best-&lt;wbr&gt;&lt;/wbr&gt;practices-of-test-driven-&lt;wbr&gt;&lt;/wbr&gt;development-using-c-and-&lt;wbr&gt;&lt;/wbr&gt;rhinomocks&lt;/span&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/7805844662808811783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/7805844662808811783' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/7805844662808811783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/7805844662808811783'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2010/05/test-driven-development-best-practices.html' title='Test-Driven-Development Best Practices'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-8509143538553537895</id><published>2010-02-24T17:38:00.000-08:00</published><updated>2010-04-01T19:03:53.298-07:00</updated><title type='text'>Name Convention for Object Oriented Apps</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Georgia; font-size: 13px;&quot;&gt;Some time ago I came across with a question about naming conventions for different parts of the software: UI, Service, Entities, etc. I decided to share some of the conventions I have been using.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Georgia; font-size: small;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 13px;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;br /&gt;
&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Georgia; font-size: 13px;&quot;&gt;&lt;u&gt;&lt;b&gt;Naming Convention: ( Most used ):&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
-&amp;nbsp;&lt;b&gt;Entities&lt;/b&gt;: As it is part of the domain package, no prefixes or suffixes here:&amp;nbsp;&lt;u&gt;Ex:&lt;/u&gt;&amp;nbsp;Car, Client, etc.&lt;br /&gt;
&lt;br /&gt;
-&amp;nbsp;&lt;b&gt;Repository&lt;/b&gt;: Usually a suffix &lt;class&gt;Repository.&amp;nbsp;&lt;u&gt;Ex:&lt;/u&gt;&amp;nbsp;ClientRepository, CarRepository, etc.&lt;br /&gt;
&lt;br /&gt;
-&amp;nbsp;&lt;b&gt;ValueObject&lt;/b&gt;: Value objects are part of the domain so it follows entity´s convention.&amp;nbsp;&lt;u&gt;Ex:&lt;/u&gt;&amp;nbsp;Money, Address, etc.&lt;br /&gt;
&lt;br /&gt;
-&amp;nbsp;&lt;b&gt;DTO&lt;/b&gt;: Usually a suffix &lt;class&gt;DTO.&amp;nbsp;&lt;u&gt;Ex:&lt;/u&gt;&amp;nbsp;ClientRegistrationDTO, CarRentDTO, AddressDTO, etc.&lt;br /&gt;
&lt;br /&gt;
-&amp;nbsp;&lt;b&gt;Service&lt;/b&gt;: Usually a suffix &lt;class&gt;Service.&amp;nbsp;&lt;u&gt;Ex:&lt;/u&gt;&amp;nbsp;ClientRegistrationService, CarRentService, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Namespace Convention:&lt;/b&gt;&lt;/u&gt;&amp;nbsp;(My Suggestion)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Entities,&amp;nbsp;&lt;/b&gt;&lt;b&gt;ValueObjects, Repositories Interfaces, Domain Services&lt;/b&gt;&amp;nbsp;&lt;b&gt;(Domain Layer)&lt;/b&gt;&lt;br /&gt;
&lt;my company=&quot;&quot;&gt;.&lt;my domain=&quot;&quot;&gt;.Domain.&lt;my class=&quot;&quot;&gt;&lt;br /&gt;
&lt;u&gt;Ex:&lt;/u&gt;&amp;nbsp;Acme.Finantial.Domain.Debt,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Acme.HR.Domain.CheckOvertimeService,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; Acme.Core.Domain.IPersonRepository &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Application Services&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;my company=&quot;&quot;&gt;.&lt;my domain=&quot;&quot;&gt;.Service.&lt;my class=&quot;&quot;&gt;&lt;br /&gt;
&lt;u&gt;Ex:&lt;/u&gt;&amp;nbsp;Acme.Sales.Service.ClientRegistrationService&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Presentation Layer&lt;/b&gt;&lt;br /&gt;
&lt;my company=&quot;&quot;&gt;.&lt;my domain=&quot;&quot;&gt;.Presentation.&lt;my class=&quot;&quot;&gt;&lt;br /&gt;
Ex: Acme.HR.Presentation.IClientRegistrationView, Acme.HR.Presentation.WebClientRegistration&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Persistence Layer&lt;/b&gt;&lt;br /&gt;
&lt;my company=&quot;&quot;&gt;.&lt;my domain=&quot;&quot;&gt;.Persistence.&lt;my class=&quot;&quot;&gt;&lt;br /&gt;
Ex: Acme.Core.Persistence.PersonRepositoryImpl (&amp;lt;--- implementation in NH, for example)&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/my&gt;&lt;/class&gt;&lt;/class&gt;&lt;/class&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/8509143538553537895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/8509143538553537895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8509143538553537895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8509143538553537895'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2010/02/name-convention-for-object-oriented.html' title='Name Convention for Object Oriented Apps'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-4151743441454581906</id><published>2010-02-22T16:16:00.000-08:00</published><updated>2015-07-14T20:34:10.379-07:00</updated><title type='text'>Unit Testing Linq Queries in Moq</title><content type='html'>After some google research and experimentation I found that it was not worth to mock methods that return IQueryable or IQueryable because in order to use it programmers have to make use of extension methods. And this kind of methods are not supported by Moq ( a minimalistic mock framework ).

This is the DAO interface I want to test.
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
public interface IDAOFactory
{
  public abstract IQueryable&lt;T&gt; Query&lt;T&gt;();
}
&lt;/pre&gt;

This is the moq unit test that fails, since I can´t use Linq directly.
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
[Test]
public void LinqQueryTest()
{ 
  // This moq configuration will trigger an exception – Can´t make use of extension methods
  daoFactoryMock.Setup(d =&gt; (from o in d.Query&lt;Order&gt;()
    where o.Id &gt;= 0
    select o.Id).ToList())
    .Returns( new List&lt;long&gt;() { 1, 2 } );
}
&lt;/pre&gt;

It turns out that the solution is easily solved by using a collection as a data source.
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
[Test]
public void LinqQueryTest()
{
  // Creates a IQueryable from a Collection
  IList&lt;Order&gt; lstOrders = new List&lt;Order&gt;() { 
    orderMock1.Object, 
    orderMock2.Object, 
    orderMock3.Object };
  IQueryable&lt;Order&gt; orderQuery = lstOrders.AsQueryable&lt;Order&gt;();

  // Configures the Query&lt;Order&gt; to return IQueryable&lt;Order&gt; implementation
  daoFactoryMock.Setup(d =&gt; d.Query&lt;Order&gt;()).Returns(orderQuery);

  // Now the linq queries can be used naturally 
  IList&lt;Order&gt; lstResult = (from o in daoFactoryMock.Object.Query&lt;Order&gt;() where o.Id &gt;= 0 Select o).ToList();

  // Checking output results
  Assert.AreEqual(3, lstResult.Count);
}
&lt;/pre&gt;

It is important to notice that the collection elements that should also be mock objects must contain all the necessary data in order to make the correct test.</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/4151743441454581906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/4151743441454581906' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/4151743441454581906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/4151743441454581906'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2010/02/unit-testing-linq-queries-in-moq.html' title='Unit Testing Linq Queries in Moq'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-2062802732618331107</id><published>2009-12-26T10:56:00.000-08:00</published><updated>2015-07-14T20:17:39.571-07:00</updated><title type='text'>Model View Controller with Events in .NET</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div&gt;
This is often a confused design pattern and its main purpose is to separate objects that assume different roles in a software.&lt;br /&gt;
These roles are:&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;models - objects that actual execute the system tasks&lt;/li&gt;
&lt;li&gt;views - objects that display the system data&lt;/li&gt;
&lt;li&gt;controllers - objects that capture the user intentions from the view and route to the right actions&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Usually Views have a reference to the controller however another approach below shows how to decouple the views from the controllers.&lt;br /&gt;
Views can be implemented in several ways depending on the UI library. For that reason, views are better represented as interfaces. However in order to reduce coupling between views and controllers, &lt;span style=&quot;font-weight: bold;&quot;&gt;events &lt;/span&gt;can be used in the interface views.&lt;/div&gt;
The example below shows a client registration view:&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;using System;
namespace MyController
{
  public interface IClientRegistrationView
  {
    public long Id { get; set; }
    public string Name { get; set; }
    public string Registration { get; set; }
    public event ClientEventHandler InsertRequested;
    public event ClientEventHandler UpdateRequested;
    public event ObjectIdEventHandler &amp;amp;lt long &amp;amp;gt RemoveRequested;
    public event ObjectIdEventHandler &amp;amp;lt long &amp;amp;gt RetrieveRequested;
  }
}
&lt;/pre&gt;
Specific event arguments were also created for the Client Registration View:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ClientEventArgs &lt;/span&gt;- contains client fields so that it can be sent to the underlying layer.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ObjectIdEventArgs &lt;/span&gt;- contains a generic object id for deletion and queries purposes.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div&gt;
See event argument classes below:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot; name=&quot;code&quot;&gt;using System;
namespace MyController
{
  public delegate void ClientEventHandler(object sender, ClientEventArgs e);
  public class ClientEventArgs : EventArgs
  {
  public long Id { get; set; }
  public string Name { get; set; }
  public string Registration { get; set; }
  }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot; name=&quot;code&quot;&gt;using System;
namespace MyController
{
  public delegate void ObjectIdEventHandler &amp;amp;lt T &amp;amp;gt (object sender, ObjectIdEventArgs &amp;amp;lt T &amp;amp;gt e);
  public class ObjectIdEventArgs &amp;amp;lt T &amp;amp;gt : EventArgs
  {
    public T Id { get; set; }
  }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
The controller will have a reference to a view (an interface) and it will access the view´s data fields for the client which is Id, Name and Registration.&lt;br /&gt;
Besides that, the controller will also be told to trigger actions by listening to the view´s events.&lt;br /&gt;
In this example, the service acts as if it was the model of the system.&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot; name=&quot;code&quot;&gt;using System;
using MyService;
namespace MyController
{
  public class ClientRegistrationController
  {
    private IClientRegistrationView View { get; set; }
    private ClientRegistrationService Service { get; set; }
    public ClientRegistrationController(IClientRegistrationView view)
    {
      View = view;
      View.InsertRequested += new ClientEventHandler(View_InsertRequested);
      View.UpdateRequested += new ClientEventHandler(View_UpdateRequested);
      View.RemoveRequested += new ObjectIdEventHandler &amp;amp;lt long &amp;amp;gt (View_RemoveRequested);
      View.RetrieveRequested += new ObjectIdEventHandler &amp;amp;lt long &amp;amp;gt (View_RetrieveRequested);
      Service = new ClientRegistrationService();   
    }
    void View_InsertRequested(object sender, ClientEventArgs e)
    {
      ClientDTO dto = new ClientDTO() { Id = e.Id, Name = e.Name, Registration = e.Registration };
      Service.Insert(dto);
      this.View.Id = dto.Id;
    }
    void View_UpdateRequested(object sender, ClientEventArgs e)
    {
      Service.Update(new ClientDTO() { Id = e.Id, Name = e.Name, Registration = e.Registration });
    }
    void View_RemoveRequested(object sender, ObjectIdEventArgs &amp;amp;lt long &amp;amp;gt e)
    {
      Service.Remove(e.Id);
    }
    void View_RetrieveRequested(object sender, ObjectIdEventArgs &amp;amp;lt long &amp;amp;gt e)
    {
      ClientDTO dto = Service.Retrieve(e.Id);
      this.View.Id = dto.Id;
      this.View.Name = dto.Name;
      this.View.Registration = dto.Registration;
    }
  }
}
&lt;/pre&gt;
As it can be seen above, the View doesn´t need to have a reference to the Controller. The view is totally decoupled form the controller but it can communicate with it by listening to the events.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/2062802732618331107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/2062802732618331107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/2062802732618331107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/2062802732618331107'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2009/12/model-view-controller-with-events-in.html' title='Model View Controller with Events in .NET'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-2019315421038352809</id><published>2009-09-27T15:04:00.000-07:00</published><updated>2009-09-27T15:20:51.161-07:00</updated><title type='text'>Extreme Programming Impressions</title><content type='html'>Whe I first read about XP Programming in 2002 ( http://www.extremeprogramming.org/ ) which is one of the agile methodologies for software development I didn&#39;t take it seriously.&lt;br /&gt;At that time the authors of this methodology were saying that software didn´t need to be documented, models were not necessary or useful at all, people should be the documentation of the software, etc.&lt;br /&gt;Immediately it came to my mind that it couldn´t work for many small (and big) software companies due to several problems:&lt;br /&gt;&lt;br /&gt;–        Software companies are constantly loosing and hiring workforce so how can they work if they keep loosing “documentation” which is on people´s minds ?&lt;br /&gt;&lt;br /&gt;–        How can they know the &quot;what&quot;, &quot;where&quot; and &quot;how&quot; in the source code ?&lt;br /&gt;&lt;br /&gt;Some years have passed and this methodology has matured and besides that other good methodologies of the same family like Scrum have come up too.&lt;br /&gt;It called my attention that many state-of-art tech companies like Google and Yahoo! were working with Scrum and I started to get curious to know what it is about.&lt;br /&gt;&lt;br /&gt;Five years later I decided to attend to a presentation about XP Programming in order to get a broader picture about it. It helped me to remove some miths I had such as the lack of documentation. Actually the Agile Methodology do not remove the activity of producing documentation but it just gave a different meaning for the documentation. The documentation should be provided if relevant for developers.  It doesn´t have to include fancy diagrams but only the necessary information such as what is the system about, how to compile source-code, or other information that it is not self-explained in the system.&lt;br /&gt;&lt;br /&gt;After reading &quot;The Toyota Way&quot; I noticed that agile methodologies was greatly inspired by this administration model. This model is basically driven to reduce waste, in other words, we should do only the necessary to accomplish our objectives, no more or no less. By reducing waste we are also reducing unnecessary work what can mean different things depending on our project such as no documentation, few documentation, no models, etc.&lt;br /&gt;&lt;br /&gt;Therefore to be lean (and consequently agile), one must think on what tasks are been carried out and what tasks in the process should be eliminated if they have no value. Read the book above to have a good idea of the process.</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/2019315421038352809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/2019315421038352809' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/2019315421038352809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/2019315421038352809'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2009/09/extreme-programming-impressions.html' title='Extreme Programming Impressions'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-5138799917245985469</id><published>2009-08-27T16:05:00.000-07:00</published><updated>2016-01-18T18:02:36.526-08:00</updated><title type='text'>DynamicProxy: An Elegant Solution for Session/Transaction/Exception Management in NHibernate (or any other ORM)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Session management is a well solved problem for web applications and many detailed solutions can be found in the internet. The same is not true for winforms applications. Although there are solutions available in the internet, many of them are theoretical or just “complicated” for the medium programmer. Besides that it was difficult to find a solution (I have never found one) that could work for both web and winforms applications.&lt;br /&gt;
&lt;br /&gt;
After a while (days), it came up to me the idea of using service proxies with &lt;b&gt;Castle Dynamic Proxies&lt;/b&gt;. It turned out to be the easiest and cleanest approach I could think of because it has the ability to inject (aspects) behaviour around the service methods.&lt;br /&gt;
&lt;br /&gt;
The idea can be coded in the following way:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Service classes with standard namespace and virtual methods&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;
namespace Sample.Service
{
  public class SystemLogRegistrationService
  {
    public virtual void Modify(long codLogSistema)
    {
      SystemLog systemLog = Repository.Get&lt;logsistema&gt;().Load(codLogSistema);            
      systemLog.SetMachine = &quot;MAQUINA&quot; + DateTime.Now;
      systemLog.SetUserName = &quot;PESSOA&quot; + DateTime.Now;            
      systemLog.SetSystemName = &quot;SISTEMA&quot; + DateTime.Now;
      Repository.Get&lt;logsistema&gt;().Save(systemLog);            
    }
  }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Do not get distracted with the service code. The important thing to notice above is that the service does not contain anything else other than processing the domain classes (in this case, SystemLog). Also note that &lt;b&gt;all service methods must be virtual&lt;/b&gt;. Without that, dynamic proxy won&#39;t work for these methods. The details of Repository implementation are out of the scope of this article and this subject is covered in enough details in several articles throughout the internet. (You can also send me a comment or email if you need information about that)&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Usage Example&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
In order to make use of proxified services, one must create some kind of generator  whose creation will be explained next. The ProxyGenerator below is a simple static class for didactic purposes that is responsible for dynamically generate proxies from a given type injecting the necessary aspects such as session/transaction management and exception handling or any other aspect you might think about.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;SomeService serv = ProxyGenerator.InjectSessionTransactionExceptionAspects &amp;amp;lt SomeService &amp;amp;gt ();
serv.Modify(12048); // &amp;lt;= Modify method has session/transaction/exception management
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Creating a proxy service factory&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
The proxy generator can be implemented using Castle Dynamic Proxy API.

&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;
using System;
using Castle.DynamicProxy;

namespace Sample.Persistence
{
  public static class ProxyGenerator 
  {
    private static ProxyGenerator _generator = new ProxyGenerator();        
    public static TService InjectSessionTransactionExceptionAspects &amp;amp;lt TService &amp;amp;gt ()
    {
      return (TService)_generator.CreateClassProxy(
        typeof(TService),
        new SessionTransactionExceptionAspect());    
    }
  }
}
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;An interceptor for the service class methods&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;using System;
using Castle.DynamicProxy;
using NHibernate;
using NHibernate.Context;

namespace Sample.Persistence
{
  /// &lt;summary&gt;
  /// Intercepts service methods (must be virtual) and inject
  /// session / transaction and exception aspects
  /// &lt;/summary&gt;
  public class SessionTransactionExceptionAspect: IInterceptor
  {
    /// &lt;summary&gt;
    /// Intercepts service methods and adds the following behaviors
    /// &amp;gt;&amp;gt;&amp;gt; Before executing a method:
    ///     * opens session
    ///     * begins transaction
    /// &amp;gt;&amp;gt;&amp;gt; After executing method:
    ///     * Commits transaction
    /// &amp;gt;&amp;gt;&amp;gt; In case there is exception
    ///     * Rollbacks transaction
    ///     * Handles exception
    /// &amp;gt;&amp;gt;&amp;gt; At the end
    ///     * Closes session
    /// &lt;/summary&gt;
    public object Intercept(IInvocation invocation, params object[] args)
    {
      object retorno = null;
      ITransaction tx = null;
      try
      {          
        CurrentSessionContext.Bind(SessionFactory.Instance.OpenSession());
        tx = SessionFactory.Instance.GetCurrentSession().BeginTransaction();
        retorno = invocation.Proceed(args);
        tx.Commit();
      }
      catch (Exception exception)
      {
        if (tx != null) { tx.Rollback(); }
          throw exception;
      }
      finally
      {
        ISession s = SessionFactory.Instance.GetCurrentSession();
        s.Close();
        CurrentSessionContext.Unbind(s.SessionFactory);
      }
      return retorno;
    }
  }
}
&lt;/pre&gt;
Above is the center of the whole idea. The interceptor class above captures only the service methods and ignores the rest. The following tasks are executed inside a try-catch-finally: (when it is a service method)
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Session is created&lt;/li&gt;
&lt;li&gt;Transaction is initialized&lt;/li&gt;
&lt;li&gt;The method itself is executed&lt;/li&gt;
&lt;li&gt;if method is ok, transaction is confirmed&lt;/li&gt;
&lt;li&gt;if there is exception, transaction is cancelled and exception is handled&lt;/li&gt;
&lt;li&gt;Finally session is  closed &lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;br /&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=oosofdev00-20&amp;marketplace=amazon&amp;region=US&amp;placement=1784393568&amp;asins=1784393568&amp;linkId=TYFK5S4CTW7TXJBB&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=oosofdev00-20&amp;marketplace=amazon&amp;region=US&amp;placement=1932394923&amp;asins=1932394923&amp;linkId=MBQDGSQVZ53GNHC5&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=oosofdev00-20&amp;marketplace=amazon&amp;region=US&amp;placement=184951304X&amp;asins=184951304X&amp;linkId=SPXSRVI4UEN657W5&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=oosofdev00-20&amp;marketplace=amazon&amp;region=US&amp;placement=1849516022&amp;asins=1849516022&amp;linkId=RDUGIAAS2P2HWSCC&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/5138799917245985469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/5138799917245985469' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/5138799917245985469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/5138799917245985469'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2009/08/dynamicproxy-elegant-solution-for.html' title='DynamicProxy: An Elegant Solution for Session/Transaction/Exception Management in NHibernate (or any other ORM)'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-8832126547532467560</id><published>2009-08-21T19:27:00.000-07:00</published><updated>2015-07-14T20:18:30.007-07:00</updated><title type='text'>Avoid &quot;Tall&quot; DAO Factories</title><content type='html'>A &quot;tall&quot; DAO factory can be defined as a big class that contains too much methods for each business class that compounds your domain model.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;
public class DAOFactory
{
IClass1DAO GetClass1DAO() { ... }
IClass2DAO GetClass2DAO() { ... }
IClass3DAO GetClass3DAO() { ... }
IClass4DAO GetClass4DAO() { ... }
IClass5DAO GetClass5DAO() { ... }
IClass6DAO GetClass6DAO() { ... }
IClass7DAO GetClass7DAO() { ... }
IClass8DAO GetClass8DAO() { ... }
IClass9DAO GetClass9DAO() { ... }
IClass10DAO GetClass10DAO() { ... }
: : : :
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Besides big, these kind of class should be modified every time a new domain class is added to your system.&lt;br /&gt;
In order to avoid that to happen, one good option is to use a generic method for all DAO interfaces.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-cs&quot;&gt;
public class DAOFactory
{
ICommonDAO GetDAO &amp;lt; I &amp;gt; ( ) where I : ICommonDAO { ... }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The action of searching the corresponding DAO interface implementation can be easily achieved by using .NET reflection support for Assemblies and Types.</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/8832126547532467560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/8832126547532467560' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8832126547532467560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8832126547532467560'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2009/08/avoid-tall-dao-factories.html' title='Avoid &quot;Tall&quot; DAO Factories'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-6394661598185996990</id><published>2009-06-13T12:55:00.000-07:00</published><updated>2009-06-29T19:50:07.240-07:00</updated><title type='text'>Agile Modeling in Software Projects</title><content type='html'>Recently Jeff Sutherland mentioned another certification for software programmers since Scrum does not include software engineer techniques but very present in XP (extreme programming) management. That is probably the reason why many software developers work with Scrum and XP methodologies together.&lt;br /&gt;&lt;br /&gt;However although XP is very software-programming oriented it is still not enough to have a good software design in large systems projects. Additionally in many organizations it is very difficult to find a product owner that fully understand the business rules and can manage the software functionalities.&lt;br /&gt;&lt;br /&gt;In order to efficiently use Scrum, there must be someone responsible for understanding the business. If there is no product owner, one employee must be chosen to study and logically model the business. That is exactly why a good business modeling is imperative before any large software development.&lt;br /&gt;&lt;br /&gt;Good software design and business understanding prevents or reduces significantly re-work tasks. It is considered wasted work since these tasks do not devliver anything useful to the client and often happens when developers did not captured well the business rules.&lt;br /&gt;&lt;br /&gt;Thus the following software development process is proposed to match DDD and agile approach. In this software process, there can be product owners, developers and scrum masters just like original Scrum the difference is that before the sprints (see Scrum reference) can start, a long DDD session is necessary in order to produce a good business model.&lt;br /&gt;&lt;br /&gt;Briefly describing the following steps should be taken:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A selected person assumes the role of Product Owner&lt;/li&gt;&lt;li&gt;Product Owner becomes responsible for studying and building a business model&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Product Owner writes all the system features using User Stories (from XP)&lt;/li&gt;&lt;li&gt;Product Owner schedules a Planning Meeting with the Scrum Master and Developers to present User Stories and the Business Model&lt;/li&gt;&lt;li&gt;Scrum Master schedules a Sprint Meeting with developers to plan the Next Sprint based on the Stories&lt;/li&gt;&lt;li&gt;Developers begin the Sprint  (from 1 to 2 weeks)&lt;/li&gt;&lt;li&gt;Scrum Master Organizes Daily Meetings with Developers (just like Scrum)&lt;/li&gt;&lt;li&gt;At the end of the Spring, Scrum Master schedules a Weekly Meeting to present the system to the Product Owner but it also includes the developers of the project who makes considerations about the system presented&lt;/li&gt;&lt;li&gt;Scrum Master organized a Retrospective Meeting with the developers to discuss what went wrong or right with the Sprint and then they start planning the next Sprint.&lt;/li&gt;&lt;li&gt;Go to Step 6 until Product Owner gets satisfied&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/6394661598185996990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/6394661598185996990' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/6394661598185996990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/6394661598185996990'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2009/06/domain-driven-design-and-agile-project.html' title='Agile Modeling in Software Projects'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-3102517400544391123</id><published>2009-06-10T17:34:00.000-07:00</published><updated>2009-06-29T19:54:13.605-07:00</updated><title type='text'>How the repository pattern works ?</title><content type='html'>The classes that represent the elements of a domain must contain all the business logic inside it such as tax calculation, name validation, etc. However in many circumstances it is also necessary to access data in order to complete the business logic inside these classes.&lt;br /&gt;&lt;br /&gt;Take the example below:&lt;br /&gt;&lt;br /&gt;Suppose I want to create an instance from the &lt;span style=&quot;font-style: italic;&quot;&gt;Client class&lt;/span&gt; and that clients must have a name and an address (there may be more information but lets stay with those two data for simplification purposes).&lt;br /&gt;So, this could be instantiated like: (C# code)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Open database connection (and Begin Transaction)&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;SessionManager&lt;/span&gt;.Open( );&lt;br /&gt;: : :&lt;br /&gt;// Parameters are: name, zipcode, adress number, address complement, country&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Client&lt;/span&gt; client = new &lt;span style=&quot;font-weight: bold;&quot;&gt;Client&lt;/span&gt;(“New Client”,”12500”,12,“Room 14”,&lt;span style=&quot;font-weight: bold;&quot;&gt;Country&lt;/span&gt;.US);&lt;br /&gt;: : :&lt;br /&gt;// Close database connection (and Commit Transaction)&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;SessionManager&lt;/span&gt;.Close( );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Although simple, the line above hides many steps such as:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Check if client name is valid &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Check if zipcode exists in the county US&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Check if address number is correct&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Check if addres complement id correct&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Check if there are clients with the same name and address&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Proceed with the client creation&lt;/li&gt;&lt;/ul&gt;However in order to complete some of this steps, the &lt;span style=&quot;font-style: italic;&quot;&gt;Client&lt;/span&gt; object should be able to access the data layer and that is the responsibility of the repositories. According to Martin Fowler&#39;s website: &lt;span style=&quot;font-style: italic;&quot;&gt;Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Reference&lt;/span&gt;: http://www.martinfowler.com/eaaCatalog/repository.html&lt;br /&gt;&lt;br /&gt;In order to make it possible the code line above, an &lt;span style=&quot;font-style: italic;&quot;&gt;Address&lt;/span&gt; and &lt;span style=&quot;font-style: italic;&quot;&gt;Client clas&lt;/span&gt;s must be implemented.&lt;br /&gt;&lt;br /&gt;See full code listing below:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Address is a value object used by Client class&lt;br /&gt;public class &lt;span style=&quot;font-weight: bold;&quot;&gt;Address&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;     public &lt;span style=&quot;font-weight: bold;&quot;&gt;Address&lt;/span&gt;(string zipCodeNumber,int number,string addrComplement)&lt;br /&gt;     {&lt;br /&gt;            // Check if zipcode number exists in the country  (ZipCode Repository uses SessionManager inside it)&lt;br /&gt;            &lt;span style=&quot;font-weight: bold;&quot;&gt;IZipCodeRepository&lt;/span&gt; zipCodeRepository = &lt;span style=&quot;font-weight: bold;&quot;&gt;RepositoryManager&lt;/span&gt;.GetRepository&lt;zipcode&gt;( );&lt;br /&gt;            &lt;span style=&quot;font-weight: bold;&quot;&gt;ZipCode&lt;/span&gt; zipCode = zipCodeRepository.Get(zipCodeNumber,country);&lt;br /&gt;            if (zipCode == null) { throw new &lt;span style=&quot;font-weight: bold;&quot;&gt;NonExistentZipCodeException&lt;/span&gt;(zipCodeNumber,country);&lt;br /&gt;            // Check if address number is correct&lt;br /&gt;            if  (number &lt;= 0) { throw new &lt;span style=&quot;font-weight: bold;&quot;&gt;InvalidAddressNumberException&lt;/span&gt;(number); }               &lt;br /&gt;            // Check if address complement is correct&lt;br /&gt;            if (complement.Trim( ) == string.Empty) { throw new  &lt;span style=&quot;font-weight: bold;&quot;&gt;InvalidAddressComplementException&lt;/span&gt;(addrComplement)); }&lt;br /&gt;            // Sets values&lt;br /&gt;       this._zipCode = zipCode;&lt;br /&gt;       this._number = number;&lt;br /&gt;            this._complement = complement;&lt;br /&gt;     }&lt;br /&gt;     private &lt;span style=&quot;font-weight: bold;&quot;&gt;ZipCode&lt;/span&gt; _zipCode = null;&lt;br /&gt;     public &lt;span style=&quot;font-weight: bold;&quot;&gt;ZipCode&lt;/span&gt; ZipCode get { return _zipCode; }&lt;br /&gt;     private int _number = 0;&lt;br /&gt;     public int Number { get { return _number; } }&lt;br /&gt;     private string _complement = string.Empty;&lt;br /&gt;     public string Complement { get { return _complement; } }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Now the Client class&lt;br /&gt;public class &lt;span style=&quot;font-weight: bold;&quot;&gt;Client&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;     private long _id;&lt;br /&gt;     public long Id { get { return id; } set { this.id = value; } }&lt;br /&gt;     private string _name = string.Empty;&lt;br /&gt;     public Name&lt;br /&gt;     {        &lt;br /&gt;            get { return _name; }  &lt;br /&gt;            // Check if name is valid    &lt;br /&gt;            set&lt;br /&gt;            {&lt;br /&gt;                   if (name.Trim( ) == string.Empty) { throw new &lt;span style=&quot;font-weight: bold;&quot;&gt;InvalidNameException&lt;/span&gt;(); }               &lt;br /&gt;                   // Check if there are Clients with same name and address               &lt;br /&gt;                   &lt;span style=&quot;font-weight: bold;&quot;&gt;IClientRepository&lt;/span&gt; clientRepository = RepositoryManager.GetRepository&lt;client&gt;();&lt;br /&gt;                   bool exists = clientRepository.ClientExists(name,zipCodeNumber,number,addrComplement,country);&lt;br /&gt;                   if (exists) { throw new &lt;span style=&quot;font-weight: bold;&quot;&gt;ClientExistsException&lt;/span&gt;( ); }&lt;br /&gt;                   this._name = value;         &lt;br /&gt;                &lt;br /&gt;             }&lt;br /&gt;     }&lt;br /&gt;     private &lt;span style=&quot;font-weight: bold;&quot;&gt;Address&lt;/span&gt; _address;&lt;br /&gt;     public Address { get { return _address; } }&lt;br /&gt;     public &lt;span style=&quot;font-weight: bold;&quot;&gt;Client&lt;/span&gt;(string name,string zipCodeNumber,int number,string addrComplement,Country country)&lt;br /&gt;     {       &lt;br /&gt;             // Creates a Client&lt;br /&gt;             this.Address = new Address(zipCodeNumber,number,addrComplement,country);&lt;br /&gt;             this.Name = name;     &lt;br /&gt;      }&lt;br /&gt;}&lt;br /&gt;&lt;/client&gt;&lt;/zipcode&gt;&lt;/pre&gt;&lt;br /&gt;Repositories have at least two advantages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It removes data specific code from the domain classes which are concerned only about business logic&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;It allows unit tests since repositories are referred as interfaces in domain classes and thus fake repositories can be created without depend on database connection&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/3102517400544391123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/3102517400544391123' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/3102517400544391123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/3102517400544391123'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2009/06/how-repository-pattern-works.html' title='How the repository pattern works ?'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-8442411478405686557</id><published>2009-03-12T18:36:00.000-07:00</published><updated>2016-01-18T18:02:16.947-08:00</updated><title type='text'>Using .NET Nullable Types with NHibernate 1.2</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Originally, NHibernate 1.2 does not support nullable types from .NET such as &lt;span style=&quot;font-weight: bold;&quot;&gt;DateTime?, int?, bool?&lt;/span&gt;, etc. but that can be solved by implementing specific NHibernate specific user types.&lt;br /&gt;
Not all nullable user types are listed for all .NET nullable types are listed below. But it can be easily done by following the example specially for numeric types.&lt;br /&gt;
However if you need help you jut send an email.&lt;br /&gt;
&lt;br /&gt;
Nullable user types code listings:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;NullableDateTimeType.cs&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.UserTypes;
using NHibernate;
using System.Data;
using NHibernate.SqlTypes;

namespace Utilitario.GerenciaDados
{
  public class NullableDateTimeType : IUserType
  {
      #region IUserType Members
      public bool Equals(object x, object y)
      {
          return object.Equals(x, y);
      }
      public int GetHashCode(object x)
      {
          return x.GetHashCode();
      }
      public object NullSafeGet(IDataReader rs, string[] names, object owner)
      {
          //object valor = NHibernateUtil.DateTime.NullSafeGet(rs, names[0]);
          object valor = null;
          if (rs[names[0]] != DBNull.Value)
              valor = Convert.ToDateTime(rs[names[0]]);

          DateTime? dateTime = null;

          if (valor != null)
          {
              dateTime = (DateTime)valor;
          }
          return dateTime;
      }
      public void NullSafeSet(IDbCommand cmd, object value, int index)
      {
          if (value == null)
          {
              NHibernateUtil.String.NullSafeSet(cmd, null, index);
          }
          else
          {
              DateTime? dateTime = (DateTime)value;
              NHibernateUtil.AnsiString.NullSafeSet(cmd, dateTime.Value.ToString(&quot;yyyy/MM/dd HH:mm:ss.fff&quot;), index);
          }
      }
      public object DeepCopy(object value)
      {
          return value;
      }
      public object Replace(object original, object target, object owner)
      {
          return original;
      }
      public object Assemble(object cached, object owner)
      {
          return cached;
      }
      public object Disassemble(object value)
      {
          return value;
      }
      public SqlType[] SqlTypes
      {
          get { return new SqlType[] { new StringSqlType() }; }
      }
      public Type ReturnedType
      {
          get { return typeof(string); }
      }
      public bool IsMutable
      {
          get { return false; }
      }
      #endregion
  }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;NullableBooleanType.cs&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.UserTypes;
using NHibernate;
using System.Data;
using NHibernate.SqlTypes;

namespace Utilitario.GerenciaDados
{
  public class NullableBooleanType : IUserType
  {
      #region IUserType Members
      public bool Equals(object x, object y)
      {
          return object.Equals(x, y);
      }
      public int GetHashCode(object x)
      {
          return x.GetHashCode();
      }
      public object NullSafeGet(IDataReader rs, string[] names, object owner)
      {
          object valor = NHibernateUtil.Boolean.NullSafeGet(rs, names[0]);
          bool? caracter = null;
          if (valor != null)
          {
              caracter = (bool)valor;
          }
          return caracter;
      }
      public void NullSafeSet(IDbCommand cmd, object value, int index)
      {
          if (value == null)
          {
              NHibernateUtil.Boolean.NullSafeSet(cmd, null, index);
          }
          else
          {
              bool? caracter = (bool)value;
              NHibernateUtil.Boolean.NullSafeSet(cmd, caracter.Value, index);
          }
      }
      public object DeepCopy(object value)
      {
          return value;
      }
      public object Replace(object original, object target, object owner)
      {
          return original;
      }
      public object Assemble(object cached, object owner)
      {
          return cached;
      }
      public object Disassemble(object value)
      {
          return value;
      }
      public SqlType[] SqlTypes
      {
          get { return new SqlType[] { new StringSqlType() }; }
      }
      public Type ReturnedType
      {
          get { return typeof(string); }
      }
      public bool IsMutable
      {
          get { return false; }
      }
      #endregion
  }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;NullableCharType.cs&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.UserTypes;
using NHibernate;
using System.Data;
using NHibernate.SqlTypes;

namespace Utilitario.GerenciaDados
{
  public class NullableCharType : IUserType
  {
      #region IUserType Members
      public bool Equals(object x, object y)
      {
          return object.Equals(x, y);
      }
      public int GetHashCode(object x)
      {
          return x.GetHashCode();
      }
      public object NullSafeGet(IDataReader rs, string[] names, object owner)
      {
          object valor = NHibernateUtil.Character.NullSafeGet(rs, names[0]);
          Char? caracter = null;
          if (valor != null)
          {
              caracter = (Char)valor;
          }
         return caracter;
      }
      public void NullSafeSet(IDbCommand cmd, object value, int index)
      {  
          if (value == null)
          {
               NHibernateUtil.Character.NullSafeSet(cmd, null, index);
          }
          else
          {
              Char? caracter = (Char)value;
              NHibernateUtil.Character.NullSafeSet(cmd, caracter.Value, index);
          }
      }
      public object DeepCopy(object value)
      {
          return value;
      }
      public object Replace(object original, object target, object owner)
      {
          return original;
      }
      public object Assemble(object cached, object owner)
      {
          return cached;
      }
      public object Disassemble(object value)
      {
          return value;
      }
      public SqlType[] SqlTypes
      {
          get { return new SqlType[] { new StringSqlType() }; }
      }
      public Type ReturnedType
      {
          get { return typeof(string); }
      }
      public bool IsMutable
      {
          get { return false; }
      }
      #endregion
  }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;NullableDecimalType.cs&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.UserTypes;
using System.Data;
using NHibernate.Util;
using NHibernate;
using NHibernate.SqlTypes;

namespace Utilitario.GerenciaDados
{
  public class NullableDecimalType : IUserType
  {
      #region IUserType Members
      public bool Equals(object x, object y)
      {
          return object.Equals(x, y);
      }
      public int GetHashCode(object x)
      {
          return x.GetHashCode();
      }
      public object NullSafeGet(IDataReader rs, string[] names, object owner)
      {
          object valor = NHibernateUtil.Decimal.NullSafeGet(rs, names[0]);
          Decimal? inteiro = null;
          if (valor != null)
          {
              inteiro = (Decimal)valor;
          }
          return inteiro;
      }
      public void NullSafeSet(IDbCommand cmd, object value, int index)
      {
          if (value == null)
          {
              NHibernateUtil.Decimal.NullSafeSet(cmd, null, index);
          }
          else
          {
              Decimal? inteiro = (Decimal)value;
              NHibernateUtil.Decimal.NullSafeSet(cmd, inteiro.Value.ToString().Replace(&#39;,&#39;,&#39;.&#39;), index);
          }
      }
      public object DeepCopy(object value)
      {
          return value;
      }
      public object Replace(object original, object target, object owner)
      {
          return original;
      }
      public object Assemble(object cached, object owner)
      {
          return cached;
      }
      public object Disassemble(object value)
      {
          return value;
      }
      public SqlType[] SqlTypes
      {
          get { return new SqlType[] { new StringSqlType() }; }
      }
      public Type ReturnedType
      {
          get { return typeof(string); }
      }
      public bool IsMutable
      {
          get { return false; }
      }
      #endregion
  }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;NullableDoubleType.cs&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.UserTypes;
using NHibernate;
using NHibernate.SqlTypes;
using System.Data;

namespace Utilitario.GerenciaDados
{
  public class NullableDoubleType : IUserType
  {
      #region IUserType Members
      public bool Equals(object x, object y)
      {
          return object.Equals(x, y);
      }
      public int GetHashCode(object x)
      {
          return x.GetHashCode();
      }
      public object NullSafeGet(IDataReader rs, string[] names, object owner)
      {
          object valor = NHibernateUtil.Double.NullSafeGet(rs, names[0]);
          Double? valorD = null;
          if (valor != null)
          {
              valorD = (double)valor;
          }
          return valorD;
      }
      public void NullSafeSet(IDbCommand cmd, object value, int index)
      {
          if (value == null)
          {
              NHibernateUtil.Double.NullSafeSet(cmd, null, index);
          }
          else
          {
              Double? valor = (Double)value;
              NHibernateUtil.Double.NullSafeSet(cmd, valor.Value.ToString().Replace(&#39;,&#39;,&#39;.&#39;), index);
          }
      }
      public object DeepCopy(object value)
      {
          return value;
      }
      public object Replace(object original, object target, object owner)
      {
          return original;
      }
      public object Assemble(object cached, object owner)
      {
          return cached;
      }
      public object Disassemble(object value)
      {
          return value;
      }
      public SqlType[] SqlTypes
      {
          get { return new SqlType[] { new StringSqlType() }; }
      }
      public Type ReturnedType
      {
          get { return typeof(string); }
      }
      public bool IsMutable
      {
          get { return false; }
      }
      #endregion
  }
}
&lt;/pre&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;NullableInt32Type.cs&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&#39;prettyprint lang-cs&#39;&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.UserTypes;
using System.Data;
using NHibernate.Util;
using NHibernate;
using NHibernate.SqlTypes;

namespace Utilitario.GerenciaDados
{
  public class NullableInt32Type : IUserType
  {
      #region IUserType Members
      public bool Equals(object x, object y)
      {
          return object.Equals(x, y);
      }
      public int GetHashCode(object x)
      {
          return x.GetHashCode();
      }
      public object NullSafeGet(IDataReader rs, string[] names, object owner)
      {
          object valor = NHibernateUtil.Int32.NullSafeGet(rs, names[0]);
          Int32? inteiro = null;
          if (valor != null)
          {
              inteiro = (Int32)valor;
          }
          return inteiro;
      }
      public void NullSafeSet(IDbCommand cmd, object value, int index)
      {
          if (value == null)
          {
              NHibernateUtil.Int32.NullSafeSet(cmd, null, index);
          }
          else
          {
              Int32? inteiro = (int)value;
              NHibernateUtil.Int32.NullSafeSet(cmd, inteiro.Value, index);
          }
      }
      public object DeepCopy(object value)
      {
          return value;
      }
      public object Replace(object original, object target, object owner)
      {
          return original;
      }
      public object Assemble(object cached, object owner)
      {
          return cached;
      }
      public object Disassemble(object value)
      {
          return value;
      }
      public SqlType[] SqlTypes
      {
          get { return new SqlType[] { new StringSqlType() }; }
      }
      public Type ReturnedType
      {
          get { return typeof(string); }
      }
      public bool IsMutable
      {
          get { return false; }
      }
      #endregion
  }
}
&lt;/pre&gt;
&lt;/div&gt;


&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=oosofdev00-20&amp;marketplace=amazon&amp;region=US&amp;placement=1784393568&amp;asins=1784393568&amp;linkId=TYFK5S4CTW7TXJBB&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=oosofdev00-20&amp;marketplace=amazon&amp;region=US&amp;placement=1932394923&amp;asins=1932394923&amp;linkId=MBQDGSQVZ53GNHC5&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=oosofdev00-20&amp;marketplace=amazon&amp;region=US&amp;placement=184951304X&amp;asins=184951304X&amp;linkId=SPXSRVI4UEN657W5&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;

&lt;iframe style=&quot;width:120px;height:240px;&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&amp;OneJS=1&amp;Operation=GetAdHtml&amp;MarketPlace=US&amp;source=ac&amp;ref=tf_til&amp;ad_type=product_link&amp;tracking_id=oosofdev00-20&amp;marketplace=amazon&amp;region=US&amp;placement=1849516022&amp;asins=1849516022&amp;linkId=RDUGIAAS2P2HWSCC&amp;show_border=true&amp;link_opens_in_new_window=true&quot;&gt;
&lt;/iframe&gt;


</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/8442411478405686557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/8442411478405686557' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8442411478405686557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/8442411478405686557'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2009/03/using-net-nullable-types-with.html' title='Using .NET Nullable Types with NHibernate 1.2'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-7269830269714291107</id><published>2008-12-26T09:48:00.000-08:00</published><updated>2008-12-26T09:59:49.538-08:00</updated><title type='text'>Extremely Short Introduction for Ruby on Rails</title><content type='html'>&lt;style type=&quot;text/css&quot;&gt;  &lt;!--   @page { size: 8.5in 11in; margin: 0.79in }   P { margin-bottom: 0.08in }   H1 { margin-bottom: 0.08in }   H1.western { font-family: &quot;Arial&quot;, sans-serif; font-size: 16pt }   H1.cjk { font-family: &quot;MS Mincho&quot;; font-size: 16pt }   H1.ctl { font-family: &quot;Tahoma&quot;; font-size: 16pt }   H2 { margin-bottom: 0.08in }   H2.western { font-family: &quot;Arial&quot;, sans-serif; font-size: 14pt; font-style: italic }   H2.cjk { font-family: &quot;MS Mincho&quot;; font-size: 14pt; font-style: italic }   H2.ctl { font-family: &quot;Tahoma&quot;; font-size: 14pt; font-style: italic }  --&gt;  &lt;/style&gt;  &lt;h1 style=&quot;font-family: courier new;&quot; class=&quot;western&quot;&gt;Ruby on Rails&lt;/h1&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;This file contains brief descriptions of a Ruby on Rails project.&lt;/span&gt;&lt;/p&gt; &lt;h2 style=&quot;font-family: courier new;&quot; class=&quot;western&quot;&gt;Important Rails Commands&lt;/h2&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;Here a list of the most relevant rails command-line programs organized by task:&lt;/span&gt;&lt;/p&gt; &lt;ul  style=&quot;font-family:courier new;&quot;&gt;&lt;li&gt;&lt;p style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;Starting  a Rails Project:&lt;/u&gt; &lt;span style=&quot;text-decoration: none;&quot;&gt;rails  &lt;application&gt;&lt;/application&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;Executing  a Rails Project:&lt;/u&gt;&lt;span style=&quot;text-decoration: none;&quot;&gt; ruby  script\server ( on application directory )&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;Generating  a new Model:&lt;/u&gt;&lt;span style=&quot;text-decoration: none;&quot;&gt; ruby  script\generate model &lt;model&gt;&lt;/model&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;Generating  a new Controller:&lt;/u&gt;&lt;span style=&quot;text-decoration: none;&quot;&gt; ruby  script\generate controller &lt;controller&gt;&lt;/controller&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;br /&gt;&lt;/p&gt; &lt;h2 style=&quot;font-family: courier new;&quot; class=&quot;western&quot;&gt;Directory Contents&lt;/h2&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;app&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;Holds all the code that&#39;s specific to this particular application.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;app/controllers&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Holds controllers that should be named like weblogs_controller.rb for automated URL mapping. All controllers should descend from ApplicationController which itself descends from ActionController::Base.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;app/models&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Holds models that should be named like post.rb.&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Most models will descend from ActiveRecord::Base.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;app/views&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Holds the template files for the view that should be named like weblogs/index.erb for the WeblogsController#index action. All views use eRuby syntax.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;app/views/layouts&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Holds the template files for layouts to be used with views. This models the common header/footer method of wrapping views. In your views, define a layout using the &lt;tt&gt;layout :default&lt;/tt&gt; and create a file named default.erb. Inside default.erb, call &lt;% yield %&gt; to render the view using this layout.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;app/helpers&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Holds view helpers that should be named like weblogs_helper.rb. These are generated for you automatically when using script/generate for controllers. Helpers can be used to wrap functionality for your views into methods.&lt;/span&gt;&lt;/p&gt;&lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;config&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Configuration files for the Rails environment, the routing map, the database, and other dependencies.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;db&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Contains the database schema in schema.rb. db/migrate contains all the sequence of Migrations for your schema.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;doc&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;This directory is where your application documentation will be stored when generated using &lt;tt&gt;rake doc:app&lt;/tt&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;lib&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Application specific libraries. Basically, any kind of custom code that doesn&#39;t belong under controllers, models, or helpers. This directory is in the load path.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;public&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;The directory available for the web server. Contains subdirectories for images, stylesheets, and javascripts. Also contains the dispatchers and the default HTML files. This should be set as the DOCUMENT_ROOT of your web server.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;u&gt;&lt;b&gt;script&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Helper scripts for automation and generation.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;b&gt;test&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;Unit and functional tests along with fixtures. When using the script/generate scripts, template test files will be generated for you and placed in this directory.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;b&gt;vendor&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot; lang=&quot;en-US&quot;&gt;  &lt;span style=&quot;font-size:85%;&quot;&gt;External libraries that the application depends on. Also includes the plugins subdirectory. This directory is in the load path.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;h2 style=&quot;font-family: courier new;&quot; class=&quot;western&quot;&gt;How does Model, View and Controller relate to each other ?&lt;/h2&gt; &lt;p  style=&quot;font-family:courier new;&quot;&gt;T&lt;span style=&quot;font-size:85%;&quot;&gt;he application directory is structured like below:&lt;/span&gt;&lt;/p&gt; &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;app&lt;/span&gt;&lt;/p&gt; &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;|-controllers&lt;/span&gt;&lt;/p&gt; &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;|-models&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;|-views&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;The fastest way to generate a complete crud for a model is to generate a controller with the scaffold option:&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&gt; script/generate scaffold blog title:string content:text date_created:datetime&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;After understanding of ruby-on-rails it is considered better practice to generate models, views and controllers separately:&lt;/span&gt;&lt;/p&gt; &lt;ul  style=&quot;font-family:courier new;&quot;&gt;&lt;li&gt;&lt;p style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;To  generate a blog controller, one must type:&lt;/span&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;   &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt; &gt; script/generate controller blog&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;   &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;span style=&quot;text-decoration: none;&quot;&gt; &lt;/span&gt;&lt;u&gt;Result:&lt;/u&gt; a BlogController class will be generated at app/controllers in BlogController.rb&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;ul  style=&quot;font-family:courier new;&quot;&gt;&lt;li&gt;&lt;p style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;To  generate a blog model, one must type:&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;   &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt; &gt; script/generate model blog&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt; &lt;u&gt;Result&lt;/u&gt;: a Blog class will be generated at app/model in blog.rb&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;ul  style=&quot;font-family:courier new;&quot;&gt;&lt;li&gt;&lt;p style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;views  can not be generated, you have to go to app/views/blog and create a  blog.html.erb.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;   &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;Views for BlogController are automatically assigned in app/views/blog by name convention. ( Since &lt;b&gt;Blog&lt;/b&gt;Controller will have a &lt;b&gt;blog&lt;/b&gt; directory in app/views ).&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p  style=&quot;margin-bottom: 0in;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;Views in app/views/blog, must have a &lt;b&gt;*.html.erb&lt;/b&gt; extension and an &lt;b&gt;index.html.erb&lt;/b&gt; must be created for initial page. Other auxiliary pages can be created in the same directory with different names.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p face=&quot;courier new&quot; style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;In order to add/remove/update models fields, one must only update the corresponding table in the data model only. After that the following command should be executed to update the models in Ruby-on-Rails:&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;margin-bottom: 0in; font-family: courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&gt; rake db:migrate&lt;/span&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/7269830269714291107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/7269830269714291107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/7269830269714291107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/7269830269714291107'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2008/12/extremely-short-introduction-for-ruby.html' title='Extremely Short Introduction for Ruby on Rails'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-3199115922224119201</id><published>2008-11-23T12:10:00.001-08:00</published><updated>2008-11-23T14:25:13.889-08:00</updated><title type='text'>Generating Software Documentation from Unit Tests</title><content type='html'>In the beginning of my career as a software developer I participated in two software projects with the traditional approach of document-first and code later. It didn&#39;t take too much time for me to realize this was a not a good aproach. We passed months capturing requirements and writing use cases just to find later that many use cases was actually different from what the stakeholders needed and many requirements have changed.&lt;br /&gt;&lt;br /&gt;Then I came across with agile software development.  The idea behind made perfect sense for me and some work colleagues and we started to introduce slowly this new paradigm in our department. Projects that lasted 1 year  ( yes ! 1 year ) or more now lasted only a couple of months. Besides that because we were demonstrating the software every week or two to the stakeholders and thus we had feedback often from them.&lt;br /&gt;This made us more productive and the final product (the software!) gained more quality and more confidence. But what happened to our business documentation ? We didn&#39;t drop a line of it.&lt;br /&gt;&lt;br /&gt;Many agilists advocate that agile software development is about absence of documentation. Recently many agilists say it is not removing documentation but that it is seen from a different perspective from document-oriented traditional approach.  Only the real necessary documentation is produced. Although it sounds perfectly reasonable we still need a way to document business rules for the IT sector managers and also stakeholders. They couldn&#39;t read and understand these rules directly from the source-code since they were not programmers or technicians.  So I started to think of a way to  automatically generate this documentation.&lt;br /&gt;&lt;br /&gt;I was talking to Anselmo from Siemens and he gave me an interesting idea: Automatic generation of business documentation from unit tests. I started thinking how could I implement this alternative in our software architecture model where we have a service class for each use case and I got to the idea below:&lt;br /&gt;&lt;br /&gt;For a Client Registration use case we could have the following unit tests:&lt;br /&gt;&lt;pre&gt;[TestFixture][BusinessRules] // Business rule attribute means this test must be documented&lt;br /&gt;class Client_Registration_Use_Case&lt;br /&gt;{ &lt;br /&gt;   [Test]&lt;br /&gt;   void Normal_Flow__Check_if_name_is_not_null() { ... }&lt;br /&gt;&lt;br /&gt;   [Test]&lt;br /&gt;   void Normal_Flow__Check_if_address_is_valid() { ... }&lt;br /&gt;&lt;br /&gt;   [Test]&lt;br /&gt;   void Normal_Flow__Check_if_there_is_another_client_with_same_name() { ... }&lt;br /&gt;&lt;br /&gt;   [Test]&lt;br /&gt;   void Normal_Flow__Save_New_Client() { ... }&lt;br /&gt;&lt;br /&gt;   [Test ExpectedException(typeof(NullClientNameException)) ]&lt;br /&gt;   void Alternative_Flow__If_client_name_is_null_raise_message_to_the_user() { ... }&lt;br /&gt;&lt;br /&gt;   [Test ExpectedException(typeof(InvalidClientAddressException)) ]&lt;br /&gt;   void Alternative_Flow__If_client_address_is_invalid_raise_message_to_the_user() { ... }&lt;br /&gt;&lt;br /&gt;   [Test ExpectedException(typeof(ClientNameAlreadyExistsException)) ]&lt;br /&gt;   void Alternative_Flow__If_another_client_with_the_same_name_was_found_raise_message_to_the_user() { ... }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;At the end, a script in the continuous integration process can read this file or assembly and transform very easily this information and save to a documentation file such as Docbook, ODT or Word Doc.  It is important to note that test methods should be placed in the right order so that the right documentation can be generated.  The only work is reading the class and methods names and generate the documentation as follows:&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Client Registration Use Case:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Normal Flow:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Check if name is not null&lt;/li&gt;&lt;li&gt;Check if address is valid&lt;/li&gt;&lt;li&gt;Check if there is another client with same name&lt;/li&gt;&lt;li&gt;Save New Client&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Alternate Flows:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If client name is null raise message to the user&lt;/li&gt;&lt;li&gt;If client address is invalid  raise message to the user&lt;/li&gt;&lt;li&gt;If another client with the same name was found  raise message to the user&lt;/li&gt;&lt;/ol&gt;-----------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;This idea has the following advantages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Documentation reflects exactly what was implemented in the software code and never gets outdated&lt;/li&gt;&lt;li&gt;If a new check or action is needed in a use case documentation, the implementation and NOT documentation is changed&lt;/li&gt;&lt;li&gt;In order to update the documentation, new unit tests are required what can force discipline among the programmers&lt;/li&gt;&lt;li&gt;Every time a release is generated the entire application documentation is updated since the proper unit tests are written&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;There disadvantages as well:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Unit tests become more verbose what can slow down its implementation a little bit&lt;/li&gt;&lt;li&gt;Test methods descriptions may not reflect the test performed inside&lt;/li&gt;&lt;/ul&gt;However I still believe the benefits are higher and I wonder if someone is not applying this idea since it sounds so simple. If you have any ideas for agile business documentation please get in touch with me.</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/3199115922224119201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/3199115922224119201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/3199115922224119201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/3199115922224119201'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2008/11/generating-software-documentation-from.html' title='Generating Software Documentation from Unit Tests'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-2797623192274041419</id><published>2008-08-19T19:29:00.000-07:00</published><updated>2008-11-01T09:09:24.326-07:00</updated><title type='text'>Efficient Software Development Process with Open-Source Tools for .NET</title><content type='html'>When a software is been built, a series of characteristics must be pursuit in order to deliver a quality product during the development process:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Agility&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Testability&lt;/li&gt;&lt;li&gt;Readability&lt;/li&gt;&lt;li&gt;Extensibility&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Automated Documentation&lt;/li&gt;&lt;/ul&gt;It it important to say that I presume many readers of this text are already convinced about the advantages brought by object oriented programming when compared to traditional development and the tools presented below support this kind of programming paradigm besides the goals specified above.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Object-Relational Mapping Tool: Castle Project Active Record&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;One of the most time-consuming things in software development is mapping classes in tables.&lt;br /&gt;This process is partially automated by tools such as NHibernate but the Active Record offered by Castle Project not only maps classes to tables but it is also capable to generate the database from the object model which confers agility to the software process.&lt;br /&gt;&lt;a href=&quot;http://www.castleproject.org/activerecord/index.html&quot;&gt;http://www.castleproject.org/activerecord/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Source-Code Standards: FXCop&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Although it is free, FXCop is not a free-software since its code is private owned by Microsoft.&lt;br /&gt;Anyway it is very a useful tool whose objective is to verify if quality metrics and/or naming conventions of a project are been followed appropriately by the team members.&lt;br /&gt;By using naming well defined and known programming conventions, code readability is enhanced and different projects can be understood by every programmer in a software company.&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb429476%28VS.80%29.aspx&quot;&gt;http://msdn.microsoft.com/en-us/library/bb429476(VS.80).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Unit Tests: NUnit&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;It is the most used automated testing tool for .NET . These tests play an important role in a software project since they bring more confidence to developers to change software when needed since they can point out when a certain piece of the software might be broken due to some modification. Obviously NUnit brings testability to the software development environment.&lt;br /&gt;&lt;a href=&quot;http://www.nunit.org/index.php&quot;&gt;http://www.nunit.org/index.php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test Coverage: PartCover&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;How can you know what parts of your code is being covered by automated tests ?&lt;br /&gt;This process is called test coverage and it is the objective of PartCover.&lt;br /&gt;Altough NCover is largely mentioned in the net, PartCover is becoming increasingly&lt;br /&gt;important as a test coverage open-source project.&lt;br /&gt;&lt;a href=&quot;http://sourceforge.net/projects/partcover/&quot;&gt;http://sourceforge.net/projects/partcover/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Automated Documentation: NDoc&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Documentation can be a time consuming task but without it, the software extensibility and maintainability can slow down considerably specially for people outside the project and unaware of coding practices. One of the fastest ways to get documentation is generating it from the source-code. NDoc can generate developer level documentation from the XML tags in the C# source-code.&lt;br /&gt;&lt;a title=&quot;http://ndoc.sourceforge.net&quot; href=&quot;http://ndoc.sourceforge.net/&quot; id=&quot;mmns&quot;&gt;http://ndoc.sourceforge.net&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Web Framework: MonoRail&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The Castle Project seems to understand what is to have an agile development. Having this in mind, MonoRail is a web framework that truly obeys the MVC Design Pattern without slowing developers down. Besides agile, this framework lets us to have an improved readability also compared to traditional ASP.NET programming.&lt;br /&gt;&lt;a href=&quot;http://www.castleproject.org/monorail/gettingstarted/index.html&quot;&gt;http://www.castleproject.org/monorail/gettingstarted/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Continuous Integration: Cruise Control .NET&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Prior sections some tools for software quality were presented such as FXCop, NUnit, PartCover and NDoc. Although useful it is very easy for one of the team members to forget to manually execute some of this tools during the development process. Remembering and executing these tools can also be error prone since some member of the team can forget to execute some of these tools.&lt;br /&gt;In order to overcome these drawbacks and others, continuous integration rised as one the most known practices from Extreme Programming (XP). ( See XP in &lt;a title=&quot;http://www.extremeprogramming.org/&quot; href=&quot;http://www.extremeprogramming.org/&quot; id=&quot;uhsj&quot;&gt;http://www.extremeprogramming.org/&lt;/a&gt; )&lt;br /&gt;Basically continuous integration is performed by a build tool such as Cruise Control ( &lt;a title=&quot;http://cruisecontrol.sourceforge.net/&quot; href=&quot;http://cruisecontrol.sourceforge.net/&quot; id=&quot;d0m_&quot;&gt;http://cruisecontrol.sourceforge.net/&lt;/a&gt; ) that is responsible for executing specified tasks necessary prior to software delivery to the users such as compilation checking, unit tests executing, quality metrics verification and finally publication. However another combination of tasks can be though such as email notification and many others.&lt;br /&gt;Generally the continuous integration process is executed manually or during the night when there is low activity but it is possible to trigger this process through a version control system such as SVN prior to accept a commit requested by a team programmer.</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/2797623192274041419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/2797623192274041419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/2797623192274041419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/2797623192274041419'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2008/08/efficient-software-development-process.html' title='Efficient Software Development Process with Open-Source Tools for .NET'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36756501.post-4159735445163389141</id><published>2008-07-24T18:41:00.000-07:00</published><updated>2008-08-13T17:28:35.993-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Scrum Venture Capital Jeff Sutherland"/><title type='text'>Scrum as a criteria for Venture Capital Groups</title><content type='html'>I just read a Foreword from Jeff Sutherland ( co-creator of Scrum ) from the book &quot;Scrum and XP from the Trenches&quot; where he comments how he chooses companies who really apply Scrum framework ( an agile framework or methodology to develop software ) for a venture capital group as an agile coach.&lt;br /&gt;&lt;br /&gt;The more time pass the more I realize how agile software development will play an important role in near future. It already plays an important role but it can become a requirement for startup companies in search for funding from venture capital groups.&lt;br /&gt;&lt;br /&gt;If a company can not deliver its products in time or can not deliver working software or can not deliver something that was not what the client was expecting, it should not be expected that they would receive funding. As Mike Cohn cited in the same book in his foreword, agile development is not about beautiful documentation or future-problem-proof code, it is about software done and working. And that&#39;s exactly what clients need and expect from a software company.&lt;br /&gt;At the same time, Scrum as well as other kinds of agile software ideas ( be it frameworks, methodologies or practices ) is very easy to put in practice. Any company or organization can start using this idea anytime they want.&lt;br /&gt;&lt;br /&gt;If you have an idea about how is the Scrum process in five minutes or so, take a look at this articles: &lt;a href=&quot;http://www.softhouse.se/Uploades/Scrum_eng_webb.pdf&quot;&gt;http://www.softhouse.se/Uploades/Scrum_eng_webb.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Addionally the book &quot;Scrum and XP from the Trenches&quot; mentioned in the beginning of this post can be downloaded here: &lt;a href=&quot;http://www.infoq.com/minibooks/scrum-xp-from-the-trenches&quot;&gt;http://www.infoq.com/minibooks/scrum-xp-from-the-trenches&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Personally, as a software developer and a small investor I will take Jeff&#39;s tip for future investments in tech companies.</content><link rel='replies' type='application/atom+xml' href='http://hcmarchezi.blogspot.com/feeds/4159735445163389141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36756501/4159735445163389141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/4159735445163389141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36756501/posts/default/4159735445163389141'/><link rel='alternate' type='text/html' href='http://hcmarchezi.blogspot.com/2008/07/scrum-as-criteria-for-venture-capital.html' title='Scrum as a criteria for Venture Capital Groups'/><author><name>OO Development</name><uri>http://www.blogger.com/profile/00944577545488056873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>