this is what the book said about Inappropriate Intimacy:
sometimes classes become far too intimate and spend too much time delving in each other's private parts. we may not be prudes when it comes to people, but we think our classes should follow strict, puritan rules. over intimate classes should be broken up as lovers were in ancient days.... Inheritance often can lead to over intimacy. sub classes are always going to know more about the their parents ( base class) then their parents would like them to know.
There is one thing for sure, over intimacy is bad, which is the direct anti-pattern of Encapsulation. when you have this smell in the code, you will find it is difficult to change code, change in one class may lead to changes in many other classes. change in one user control may lead to change in many hosts( form or user controls) and hosts of the hosts and even more,,,, if you run code metrics, you will see high in class coupling, this is another direct anti-pattern of "high cohesion and low coupling".
let's take a look at our codebase to see where we are in this aspect:
the top 100 methods of class coupling are in the arrange of (38 to 94), more than 50% of them are in UI
the top 100 classes of class coupling are in the arrange of ( 119 to 378), more than 75% of them are in UI
CA1506: Avoid excessive class coupling is one of the warning message generated by Code analysis. MS message says "A class coupling above 40 indicates poor maintainability, a class coupling between 40 and 30 indicates moderate maintainability, and a class coupling below 30 indicates good maintainability." over 6410 classes in our code base, we have 586 classes with class coupling over 40. and 736 classes with class coupling over 30.
In UI project I know of the total number of classes is 831, while number of classes with coupling over 40 is 374.
it looks like the UI project is the main source of this bad smell. let's take a look at some examples code
Me.Address.DomesticAddUserControl.County.HideToCustomization()
This piece of code block is in a form. Address is an instance of user control AddressUserControl
inside AddressUserControl control there is an instance of another user control , USDomesticAddressUserControl
inside USDomesticAddressUserControl control, there is an instance of another control (part of DevExpress) , (DevExpress.XtraLayout.LayoutControlItem)
inside LayoutControlItem control , there is a method call HideToCustomization ()
Take form as level zero, you can tell the intimacy level is 3, anything happen to the API of all these user controls involved will affect the code in the form. this is a typical case of Inappropriate Intimacy.
take a look at this line of code
Me.Address.addressGroupControl.Text = "Address"
this code is in a form, in the form there is a user control AddressUserControl
inside AddressUserControl user control there is an instance of another user control, GroupControl
inside GroupControl there is a property named Text property.
in the form, the code reach out to AddressUserControl and go inside to GroupControl to set the Text property of the control. this is another example of Inappropriate Intimacy.
let's have another example:
Enough said about Inappropriate Intimacy, let's see how to deodorant this bad smell. specifically how to address it in UI project.
1) in a form/user control, all user controls it uses to be made as private, not accessible outside of it
2) the hosting form / user control access it through its public interface ( property, method and events)
in other classes, try to keep the public facing members to minimum. as our rule called "Secure by default". With those guidelines, the Inappropriate Intimacy smell in our code will be reduced.
if after doing all these , we still felt the intimacy is still high, there are other more advanced way to reduce the intimacy. the following are some technics:
1) move methods and fields so that they stay together ( in the same class)
2) change bidirectional association to unidirectional association between classes
3) if there are 2 classes sharing common interest, extract the commonality into a separate class
4) replace inheritance with Delegation
5) Hide Delegate to let another class act as go-between.
Thursday, December 19, 2013
Bad smell in code - Data Class
In
the book titled “Refactoring Improving the design of existing code”, the author
wrote the following with regard to the data class.
These
are classes that have fields , getting and setting methods ( setters and
getters) for the fields, and nothing else. Such class are dumb data holders and
almost certainly be manipulated in far too much detail by other classes. In
early stages these class may have public fields. If so, you should immediately
apply Encapsulate
Field
before anyone notices. If you have collection fields, check to see whether they
are properly encapsulated and apply Encapsulate
Collection if
they aren’t. Use Remove
Setting Method (
setters) on any field that should not be changed.
Looking
for where these getting and setting method are used by other classes. try to use
Move Method to move behavior into the data class. If you can’t move a whole
method, use Extract Method to create a method that can be moved. after a while
you can start Hide Method and the getters and setters.
Data
class are like children, they are okay as a starting point, but to participate
as grownup objects, they need to take some responsibilities
DTO
is another form of data class, ( all properties and fields, no behaviors).. which is
used to pass data between layers. as different layers have their own Business
Entities, Transformation is need to transform between BEs and DTOs.
Take an example, supposed we have a Data Layer Component (
DLC) and a Business Layer Component ( BLC), there are business entities in
respective layers ( let’s call them BE-DLC and BE-BLC respectively. Then in
between BLC and DLC, we will have another set of classes call
DTO-BLC-DLC).
In
this design, when BLC talking to DLC they use DTO-BLC-DLC passing data back and
forth. when they want to passing data to the other
side, they transform their own Bes into the DTOs and then pass them over, on the
receiving party, after receiving the data in DTO format, it will transform them
into their own Bes. The goal is this design is to achieve
independency between layers. if one component need to change its own Bes,
it only need to change its own transformer, there will be no impact to
other parties. however, if the DTOs need to be changed, both parties need to be
changed.
In
the book titled “Microsoft .Net Architecting Application for Enterprise”, the
authors wrote the following regarding DTO:
The
use of DTOs in conjunction with BO ( Business Entity in our case)
is one of those topics that can trigger an endless, and pointless,
discussion within the team. The Theory suggests that DTOs are used
in all cases to reduce coupling between layers and to lend the system greater
formal neatness. the practices, though, often reminds us that the complexity is
generally high enough that we should avoid any unnecessary additions. As a
practical rule, you probably don’t want to double the numbers of classes just to
be neater in your implementation. in this case, a DTA might likely be the same
as BOs.
I
personally strongly against the use of DTO when all layers are under your
design. For one, it increases the complexity of the system for sure, 4 sets of
classes are added to implement DTO. DTO itself, one transformer at
each side. plus the BE classes is each layers as comparing only
one set of Bes for the system. Secondly it negatively impact the
overall performance due to the time taking for transformation. The fact is that
when all components are under one architect / design team, most likely they are
the same or can be made same. hence, most of the transformation
is just direct mapping. but these classes live in different
namespaces, even if it is direct mapping, the transformation is still needed. in
a way, you transform an apple from DLC to an apple in DTO and then transform the
apple in DTO to the apple in BLC. through they are repenting the same apple from
business point of view, technically they are distinct objects. you cannot do
compare between them, you cannot assign an instance of one to a
field with the type of the other. in summary: it is pure over-engineering
practice and should be avoid whenever possible. It is viewed as one of
anti-patterns, Over Engineering.
However,
DTO concept will offer its promise when you deal with third parties in your
system. let’s say your system needs to interface with Exchange Server, or your
system need to interface with Facebook. , or your system need to interface with
the system run by government agency ( e.g. SSA). In
these cases, you are not in position to influence their BE/DTO design, whatever
they give you, you just take, no question asked. On the other end, in most
cases, you are only interested at a subset of their services whether it is BEs.
or DTOs in these scenario, you get the library for their DTOs from
them or you code them yourself and add in your own transformation logic in your
components. in this way the changes in the interface would be isolated in
transformation logic. your Business Entity will be much stable
than otherwise.
Other
than the proper employment of DTOs, we should avoid data class in all other
scenario. Plain and simple “, they need to take some responsibilities”, failure
in doing so, it will produce following undesirable result in your
system:
1) High
class coupling
2) Duplicated
business logic
3) high
codebase size
4) inappropriate
intimacy
5) lower
maintainability and high complexity
In
summary, cost more time and money to develop and do maintain, produce lower
quality product in all aspects.
the following table shows some metrics of a project I know about:
Component
|
Cyclomatic Complexity
|
Maintainability Index
|
Lines Of Code
|
# of classes
|
BE (Business Entity)
|
6.329%
|
94%
|
66,259
|
1137
|
BLC ( Business Layer Component)
|
47.486%
|
69%
|
39,500
|
263
|
UI (User Interface)
|
21.894%
|
82%
|
398,612
|
406
|
SLC(Service Layer Component)
|
32.226%
|
69%
|
31,149
|
235
|
UIP ( User Interface Process)
|
41.095%
|
70%
|
30,293
|
135
|
DLC ( Data Layer Component)
|
18.537%
|
53%
|
66,327
|
220
|
It is a fairly large system, about one million LOCs. From the figures here one could tell the BE could be more accurately described as "Data Entity" or "Data Class". Together with other technical challenges, it leads the project to some kind of undesired state.
Ok, one would ask, we have what we have here. You listed all kind of reasons why it smells bad, and what kind of results I will face. more importantly, how we can go from here? the author offered a few technics in the paragraph I quoted above:
- Encapsulate Field
- Encapsulate Collection
- Remove Setters if can be made read only
- Move Method to move behavior into the data class
- Extract Method and move
I
will add one more there, Encapsulate
business logic as read only property or methods in BE classes whenever you can and remember to name them properly so that others in the team could be benefited from your work. .
Let’s
collectively give our BE components some more intelligence and give them some
more responsibilities. let’s gown it from baby infant into its adulthood
.
Wednesday, December 11, 2013
Bad Smell code -- Incomprehensive Class Library
In the modern program languages like .Net, object-oriented-programming concepts are baked into the language, but that does not mean we programmer immediately become a OOP programmer when we started to write code in .Net. 20 years ago, I have seen a programmer wrote his entire C++ program in one class while using C++ compiler. I have seen people using COBOL85 compiler writing the code that can be compiled by COBOL74 compiler..
In a project I was involved, there is an item in NFRS says :
The system shall use object-oriented development principles such as encapsulation, inheritance, and polymorphism to support a UML-oriented design process.
and the response to that was:
The software product meets the requirement. The framework of the product is based on Microsoft’s .NET framework and uses VB.NET as the programming language which is a fully object-oriented programming (OOP) language. Various modules within the system use the OOP principle of encapsulation, inheritance and polymorphism.
while one of the architects told me not to mention OOP to much as we are doing SOA.
I thought more elaboration or assurance on how to meet the requirement could serve the requirement better.
The point I like to make here is: OOP programming languages facilitate programmers writing program observing OOP principles, but it does not prevent programmer from writing non-OOP program. Once the decision is made on programming language, the person who writes the program is the determining factor on how these OOP principles are observed.
During my vacation, my wife and I attended a piano recital which my 6 years old daughter is one of the performers range from having learned piano for 5 years to young pianist like my daughter who only have touched piano for less than a year. During the performance, the same set of pianos were used, different pieces of music were performed, in some case, the same piece of music was performed by different performers on the same piano. You guessed right. Even people like me can tell the difference. sometime the difference is so huge! Like people said "the difference is between the chair and the keyboard". In my daughter’s piano recital case, it is between the bench and the keyboard.
In the old days, designers document their design in writing, the programmers convert that into code, that’s why "programmer" was also referred as "coder". In modern programming world, from the time you started touch your code in IDE till you check in your code and complete your task or bug fixing, you are engaging in design all the time. Programming work is a highly intelligence work. That’s why we are referred as "knowledge worker" now a days. It has nothing to do with "copy and paste" or "cookie cutting". we no longer been addressed as "coder" anymore! we are the developers!
Yes, we are the software developers developing software, like home builders building homes. A of software product is made of packages, a package is made of components, a component is made of classes and interfaces, a class is made of members like properties, methods and other elements. The developing activities is building these software elements so that collectively, the software is capable of implement certain business process. The processing of programming is a process of building software elements so that the business requirements can be fulfilled by using the elements we build (as comparing to doing something to fulfill the business requirement). When you write a method, when you write a class, you are building these elements for the software. You are not the ONLY consumer of the software elements you are building. They can be consumed by other methods, other classes, or other components. Most importantly, these consumers could be very well possible are going to be written by your fellow developers now or in the future. In another word: you are building class library for the software. if the class library we are building is incomplete, or not consumer friendly or misleading or could be abused for unintended purpose, we are in danger of producing this bad smell.
This is what the author said about this smell " Reuse is often touted as the purpose of objects. we think reuse is overrated ( WE JUST USE!). "The term of "reuse" suggests something is built for its own primary purpose, then can be reused for other purpose as bonus. In OOP programming, once a software element is build, it is made available for the rest of the system. when you write a software element, do not only care for your own purpose, think for others.(sometimes, when I suggest to make some changes to a method or a property, I got some response saying " no, we cannot do that, it will impact many places!". well, if the method or the property is named right, if they are all used rightfully. you want your changes impacting all these places! That is the idea of OOP! If your changes negatively impacting some places, there are only 2 reasons 1) the method was named wrong so that suggested wrong use, 2) it was wrong to reference the method at that places.) Fail in doing so will result in "Incomplete Library" or "Incomprehensive Class Library"
However, the preventive measures to the smell is quite simple: Think more before writing, When you find something was not named properly, refactor it! The guidelines on preventing this smell are the following:
1.Naming your software element (class, method, property, event) accurately and with proper abstraction level.
2.Consider all possible consuming scenarios
3.Define proper accessibility ( public, private, internal, protected)
The key technic in programming practices is review the code you wrote outside the context of the feature or defect you are working on. If they still make sense outside of your context, you are building software elements, otherwise, you are doing things for yourself which may cause more trouble in the long run the software development life cycle..
The result of this smell are duplicated logic written in multiple places, convoluted functionalities provided repeatedly with similar names in different place or in the same place. From software development business point of view, like all other bad smells, it is one of the contributing factors to high development cost, huge code base size, high defect rate, high defect reopen rate, and high cost of fixing them. These symptoms collectively lead to over budget, behind schedule, aged and unstable software product. It is not unusual that they cause the project get killed before the software product goes to production. I myself have witnessed a few in my decades of software development career. so do not repeat the mistakes others have made. learn from their mistakes and produce high quality software with lowest possible cost!
Programming work should be an enjoyable work, make it so!
As always, comments, feedbacks, suggestions are most welcome on either the content of this article or topics of future weekly articles…
you can communicate with my in public or in private, anyway you feel comfortable…
Programming work should be an enjoyable work, make it so!
In a project I was involved, there is an item in NFRS says :
The system shall use object-oriented development principles such as encapsulation, inheritance, and polymorphism to support a UML-oriented design process.
and the response to that was:
The software product meets the requirement. The framework of the product is based on Microsoft’s .NET framework and uses VB.NET as the programming language which is a fully object-oriented programming (OOP) language. Various modules within the system use the OOP principle of encapsulation, inheritance and polymorphism.
while one of the architects told me not to mention OOP to much as we are doing SOA.
I thought more elaboration or assurance on how to meet the requirement could serve the requirement better.
The point I like to make here is: OOP programming languages facilitate programmers writing program observing OOP principles, but it does not prevent programmer from writing non-OOP program. Once the decision is made on programming language, the person who writes the program is the determining factor on how these OOP principles are observed.
During my vacation, my wife and I attended a piano recital which my 6 years old daughter is one of the performers range from having learned piano for 5 years to young pianist like my daughter who only have touched piano for less than a year. During the performance, the same set of pianos were used, different pieces of music were performed, in some case, the same piece of music was performed by different performers on the same piano. You guessed right. Even people like me can tell the difference. sometime the difference is so huge! Like people said "the difference is between the chair and the keyboard". In my daughter’s piano recital case, it is between the bench and the keyboard.
In the old days, designers document their design in writing, the programmers convert that into code, that’s why "programmer" was also referred as "coder". In modern programming world, from the time you started touch your code in IDE till you check in your code and complete your task or bug fixing, you are engaging in design all the time. Programming work is a highly intelligence work. That’s why we are referred as "knowledge worker" now a days. It has nothing to do with "copy and paste" or "cookie cutting". we no longer been addressed as "coder" anymore! we are the developers!
Yes, we are the software developers developing software, like home builders building homes. A of software product is made of packages, a package is made of components, a component is made of classes and interfaces, a class is made of members like properties, methods and other elements. The developing activities is building these software elements so that collectively, the software is capable of implement certain business process. The processing of programming is a process of building software elements so that the business requirements can be fulfilled by using the elements we build (as comparing to doing something to fulfill the business requirement). When you write a method, when you write a class, you are building these elements for the software. You are not the ONLY consumer of the software elements you are building. They can be consumed by other methods, other classes, or other components. Most importantly, these consumers could be very well possible are going to be written by your fellow developers now or in the future. In another word: you are building class library for the software. if the class library we are building is incomplete, or not consumer friendly or misleading or could be abused for unintended purpose, we are in danger of producing this bad smell.
This is what the author said about this smell " Reuse is often touted as the purpose of objects. we think reuse is overrated ( WE JUST USE!). "The term of "reuse" suggests something is built for its own primary purpose, then can be reused for other purpose as bonus. In OOP programming, once a software element is build, it is made available for the rest of the system. when you write a software element, do not only care for your own purpose, think for others.(sometimes, when I suggest to make some changes to a method or a property, I got some response saying " no, we cannot do that, it will impact many places!". well, if the method or the property is named right, if they are all used rightfully. you want your changes impacting all these places! That is the idea of OOP! If your changes negatively impacting some places, there are only 2 reasons 1) the method was named wrong so that suggested wrong use, 2) it was wrong to reference the method at that places.) Fail in doing so will result in "Incomplete Library" or "Incomprehensive Class Library"
However, the preventive measures to the smell is quite simple: Think more before writing, When you find something was not named properly, refactor it! The guidelines on preventing this smell are the following:
1.Naming your software element (class, method, property, event) accurately and with proper abstraction level.
2.Consider all possible consuming scenarios
3.Define proper accessibility ( public, private, internal, protected)
The key technic in programming practices is review the code you wrote outside the context of the feature or defect you are working on. If they still make sense outside of your context, you are building software elements, otherwise, you are doing things for yourself which may cause more trouble in the long run the software development life cycle..
The result of this smell are duplicated logic written in multiple places, convoluted functionalities provided repeatedly with similar names in different place or in the same place. From software development business point of view, like all other bad smells, it is one of the contributing factors to high development cost, huge code base size, high defect rate, high defect reopen rate, and high cost of fixing them. These symptoms collectively lead to over budget, behind schedule, aged and unstable software product. It is not unusual that they cause the project get killed before the software product goes to production. I myself have witnessed a few in my decades of software development career. so do not repeat the mistakes others have made. learn from their mistakes and produce high quality software with lowest possible cost!
Programming work should be an enjoyable work, make it so!
As always, comments, feedbacks, suggestions are most welcome on either the content of this article or topics of future weekly articles…
you can communicate with my in public or in private, anyway you feel comfortable…
Programming work should be an enjoyable work, make it so!
Developing Services for Modern Applications with ASP.Net Web API
First of all, let me give you Microsoft's definition of "Modern applications" as the applications runs in the following platforms (not limited to):
Browser (written in Java script, Ajax)
Device ( xbox, blue ray player, TV set-tops etc.)
Smart Phone runs various operating like IOS, Android OS, WP
Tablets runs various operating systems like IOS, android OS, Window 8
refrigerators and cars runs on various platforms including Linux.
If you take a closer look at the apps available in these platforms in the market, you will find most of them depends on some kind of back-end service to operate. If an app only acts on its own, its usefulness would be limited. So how to design and develop services for apps running in these device is an strategically important issue for many software architects and software makers. Look at the running environment of these modern apps, you will find the commonality among these devices are (1) they all have limited bandwidth in term network connectivity ( Wi-Fi, 3G or 4G wireless network) if any. (2) the common language they understand is HTTP, not wsdl , not SOAP. (3) most of these apps are at hands of consumers who has limited knowledge about computer or configurations. With all these considerations, Web Service or WCF service would not be considered as good candidates. TCP/IP socket programming is too much towards the low layer, may not be efficient in term of productivity and not many programmers are knowledgeable about it .
To response to such technical landscape, Microsoft came out with a new technology call "ASP.Net Web API" and the current version is 2.0. so it is commonly referred as "ASP.Net Web API 2". it is not web service pre-said. to be more accurately, it is HTTP Service.
I am sure you can find tons of resource if you search these key words on the web, the save my energy on more useful content, I am not going to offer you a list here. as I said search "ASP.Net Web API" on the web, you will get lots useful information from white paper, to presentation to sample app source code. In a nutshell, it is an extension of ASP.Net MVC. it has all kind of terms like model, controller. but no views for the reason that it act as an API library does not need views. ( IBM also has its own Web API technology based on Web Sphere in Java world)
There is a say "talk is cheap, show me the code!" , I like that very much, so let me show you some code for you to see how simple it is to build your service with "ASP .Net Web API 2" in Visual Studio..
public class ModuleController : ApiController
{
protected ServiceEngine _service;
public AdminController()
{
_service = new ServiceEngine();
}
public IEnumerable<Module> GetAllModules()
{
return _service.GetModules(false);
}
public IHttpActionResult GetModule(int id)
{
var model = _service.GetModule(id);
if (model == null)
{
return NotFound();
}
else
{
return Ok(model);
}
}
}
you can see here with around 10 line of code, I made a service with 2 functionalities . Here the ServiceEngine is a class that provide the data from your data store. if your data stores in SQL/Server, you could write your own ADO code, or use Enterprise Library Database Application Block or using Entity Framework. To show how cool I am, I chose to use the latest version of Entity Framework, EF 6.0. With EF6.0, the code for ServiceEngine code is as follow:
public IList<VModuleList> GetModuleCatalog()
{
return (new DataEntities().ModuleLists()
}
public Module GetModule(int id)
{
DataEntities context = new DataEntities ();
var module = context.Modules.Where(m => m.Id == id).FirstOrDefault();
var words = context.Words.Where(w => w.ModuleId == module.Id).ToList();
return module;
}
so, all in all, in less than 20 line of code, I made a service with 2 operations.
let's test it out.
run your app and hit your app site with the following address:
http://localhost:8817/api/Module/ and http://localhost:8817/api/Module/1
you will get some content similar to the following respectively:
[
{
"WordCount":677,
"Title":"First Grade Vocabulary",
"Description":"Complete List of First Grade Vocabulary",
"Id":0
},
{
"WordCount":479,
"ProductId":2,
"Title":"Kindergarten Vocabulary",
"Description":"Complete List of Kindergarten Vocabulary",
"Id":0,
}
]
{
"Words":[
{
"Spelling":"across",
"SampleSentence":"across the road, there is a big building.",
"ParentId":0,
"Id":1,
}
],
"Title":" Kindergarten Vocabulary",
"Description":"Complete List of Kindergarten Vocabulary",
"Id":1,
}
what are they? most of you might know they are JSON strings that can be de-serialized into an object. if you want them to be in XAML format, it is as simple as add one line in your client code, (I will talk about Web API client in my next article). In the service side, no code change is needed. For these who are interested at JSON, or JSON library, there would be another topic by itself. just let me know.
I have my service deployed to my home server, and I made my home server accessible to the public, if you are interested to try by yourself, let me know, I will provide you with the URL of the service.
Isn't it cool. If you are as excited as I am. you might want to ask where is it , how can I get it? well. it has been there for some time,
1. ASP.Net Web API was first released with Visual Studio 2012, In Visual Studio 2012, there is a project template under <Web><ASP.Net MVC 4.0 Web Application> call <Web API>
2. ASP.Net Web API 2 was released as part of Visual Studio 2013. In Visual Studio 2013, there is a project template under <Web><ASP .Net Web Application> call <Web API>
3. API 2 is also available as a stand-alone NuGet package for Visual Studio 2012, the package name is "Microsoft ASP.Net Web API2 Core",
4. you also can find other useful packages like "simple test client for ASP.Net Web API" , "Web API2 Client", "Web.API2 OData" etc. from NuGat library.
5. Best of all, it is open source, if you do not like some parts of it, you can download the source code and make changes yourself. if like to share your changes with others, you can submit your changes at codeplex.com
Another great point is that it is very easy to adopt it. In my case, starting from the point I thought I need to have some kind of service for my demo window store app and had no idea on how to do it, to the point I got the service up and running. it look less than a day. I started it last Saturday morning and at Sunday breakfast table I was so excited talking to my wife about the wonderful service I had developed, leaving alone I still spend time with my family on grocery shopping and play piano with my daughter and other weekends family activities.
Browser (written in Java script, Ajax)
Device ( xbox, blue ray player, TV set-tops etc.)
Smart Phone runs various operating like IOS, Android OS, WP
Tablets runs various operating systems like IOS, android OS, Window 8
refrigerators and cars runs on various platforms including Linux.
If you take a closer look at the apps available in these platforms in the market, you will find most of them depends on some kind of back-end service to operate. If an app only acts on its own, its usefulness would be limited. So how to design and develop services for apps running in these device is an strategically important issue for many software architects and software makers. Look at the running environment of these modern apps, you will find the commonality among these devices are (1) they all have limited bandwidth in term network connectivity ( Wi-Fi, 3G or 4G wireless network) if any. (2) the common language they understand is HTTP, not wsdl , not SOAP. (3) most of these apps are at hands of consumers who has limited knowledge about computer or configurations. With all these considerations, Web Service or WCF service would not be considered as good candidates. TCP/IP socket programming is too much towards the low layer, may not be efficient in term of productivity and not many programmers are knowledgeable about it .
To response to such technical landscape, Microsoft came out with a new technology call "ASP.Net Web API" and the current version is 2.0. so it is commonly referred as "ASP.Net Web API 2". it is not web service pre-said. to be more accurately, it is HTTP Service.
I am sure you can find tons of resource if you search these key words on the web, the save my energy on more useful content, I am not going to offer you a list here. as I said search "ASP.Net Web API" on the web, you will get lots useful information from white paper, to presentation to sample app source code. In a nutshell, it is an extension of ASP.Net MVC. it has all kind of terms like model, controller. but no views for the reason that it act as an API library does not need views. ( IBM also has its own Web API technology based on Web Sphere in Java world)
There is a say "talk is cheap, show me the code!" , I like that very much, so let me show you some code for you to see how simple it is to build your service with "ASP .Net Web API 2" in Visual Studio..
public class ModuleController : ApiController
{
protected ServiceEngine _service;
public AdminController()
{
_service = new ServiceEngine();
}
public IEnumerable<Module> GetAllModules()
{
return _service.GetModules(false);
}
public IHttpActionResult GetModule(int id)
{
var model = _service.GetModule(id);
if (model == null)
{
return NotFound();
}
else
{
return Ok(model);
}
}
}
you can see here with around 10 line of code, I made a service with 2 functionalities . Here the ServiceEngine is a class that provide the data from your data store. if your data stores in SQL/Server, you could write your own ADO code, or use Enterprise Library Database Application Block or using Entity Framework. To show how cool I am, I chose to use the latest version of Entity Framework, EF 6.0. With EF6.0, the code for ServiceEngine code is as follow:
public IList<VModuleList> GetModuleCatalog()
{
return (new DataEntities().ModuleLists()
}
public Module GetModule(int id)
{
DataEntities context = new DataEntities ();
var module = context.Modules.Where(m => m.Id == id).FirstOrDefault();
var words = context.Words.Where(w => w.ModuleId == module.Id).ToList();
return module;
}
so, all in all, in less than 20 line of code, I made a service with 2 operations.
let's test it out.
run your app and hit your app site with the following address:
http://localhost:8817/api/Module/ and http://localhost:8817/api/Module/1
you will get some content similar to the following respectively:
[
{
"WordCount":677,
"Title":"First Grade Vocabulary",
"Description":"Complete List of First Grade Vocabulary",
"Id":0
},
{
"WordCount":479,
"ProductId":2,
"Title":"Kindergarten Vocabulary",
"Description":"Complete List of Kindergarten Vocabulary",
"Id":0,
}
]
{
"Words":[
{
"Spelling":"across",
"SampleSentence":"across the road, there is a big building.",
"ParentId":0,
"Id":1,
}
],
"Title":" Kindergarten Vocabulary",
"Description":"Complete List of Kindergarten Vocabulary",
"Id":1,
}
what are they? most of you might know they are JSON strings that can be de-serialized into an object. if you want them to be in XAML format, it is as simple as add one line in your client code, (I will talk about Web API client in my next article). In the service side, no code change is needed. For these who are interested at JSON, or JSON library, there would be another topic by itself. just let me know.
I have my service deployed to my home server, and I made my home server accessible to the public, if you are interested to try by yourself, let me know, I will provide you with the URL of the service.
Isn't it cool. If you are as excited as I am. you might want to ask where is it , how can I get it? well. it has been there for some time,
1. ASP.Net Web API was first released with Visual Studio 2012, In Visual Studio 2012, there is a project template under <Web><ASP.Net MVC 4.0 Web Application> call <Web API>
2. ASP.Net Web API 2 was released as part of Visual Studio 2013. In Visual Studio 2013, there is a project template under <Web><ASP .Net Web Application> call <Web API>
3. API 2 is also available as a stand-alone NuGet package for Visual Studio 2012, the package name is "Microsoft ASP.Net Web API2 Core",
4. you also can find other useful packages like "simple test client for ASP.Net Web API" , "Web API2 Client", "Web.API2 OData" etc. from NuGat library.
5. Best of all, it is open source, if you do not like some parts of it, you can download the source code and make changes yourself. if like to share your changes with others, you can submit your changes at codeplex.com
Another great point is that it is very easy to adopt it. In my case, starting from the point I thought I need to have some kind of service for my demo window store app and had no idea on how to do it, to the point I got the service up and running. it look less than a day. I started it last Saturday morning and at Sunday breakfast table I was so excited talking to my wife about the wonderful service I had developed, leaving alone I still spend time with my family on grocery shopping and play piano with my daughter and other weekends family activities.
Programming should be an enjoyable, make it so!
Thursday, May 2, 2013
How to Organize Constant Values
We all know that hard coding is a bad thing in programming. So we create a class’s call AppConstants. Well, that is better than hardcoding in most of cases, but it is far from good enough. In some case, it is even worse.
First of all, let’s say what should not be treated as constants. Anything that is user (included administrator) changeable, editable or maintainable should not be treated as constant. We must understand that any change of these constant values will lead to code change and build and redeployment before the change take effect.
Now let’s move on to the topic of how to organize constants values.
The first question to ask is: is this group of values representing permissible values of certain fields? e.g. CreditCardType (MasterCard, Discover, Visa), Gender (Unknown, Male, Female). If the answer is “Yes” we can group them together as an enum and use enum as data type for these fields. The code example as following:
Public Enum CreditCardType
None
MasterCard
Discover
Visa
End Enum
Public Enum Gender
Unknown = 3
Male = 1
Female = 2
End Enum
Inside your class, you use these enum as data type, for example, inside Customer class you will have Gender property defined as following:
Public Property Gender() As Gender
And inside Payment class, you might have a property indicate the CreditCardType as following:
Public Property CreditCardType () As CreditCardType
And then you can assign values to these properties with the enum values or compare the value of these properties with their respective enum values. the following are some examples:
ShoppingCart.Payment.CreditCardType = CreditCardType.Visa
If Transaction.Customer.Gender = Gender.Male
If the answer to the first question is “No”, we then process to the next question. “If the group of values representing certain attributes of certain entity and meant to be accessed by index. For example, they are position offsets of all fields of certain message, or they are length of each field of certain messages” If the answer to this question is “Yes” we could establish a static dictionary within a static constructor of a class with these group of values as value and the index you want to access them with. The following are some sample code:
Public Shared Sub SetDecalMaxLength()
DecalMaxLength = New Dictionary(Of VehicleTypes, Integer)
DecalMaxLength.Add(VehicleTypes.Moped, 5)
DecalMaxLength.Add(VehicleTypes.Snowmobile, 6)
DecalMaxLength.Add(VehicleTypes.WaterCraft, 7)
End Sub
Public Structure Field
Public Offset As Integer
Public Length As Integer
Public Sub New(ByVal offset As Integer, ByVal length As Integer)
Me.Offset = offset
Me.Length = length
End Sub
End Structure
Private Shared Sub SeupUDFileds()
UD = New Dictionary(Of LegacyCDLISUD, Field)
UD.Add(LegacyCDLISUD.DriverLicense, New Field(0, 13))
UD.Add(LegacyCDLISUD.SSN, New Field(25, 9))
UD.Add(LegacyCDLISUD.FirstName, New Field(34, 30))
UD.Add(LegacyCDLISUD.FirstNameTruncatedCode, New Field(64, 1))
UD.Add(LegacyCDLISUD.FirstNameTransliteratedCode, New Field(65, 1))
UD.Add(LegacyCDLISUD.MiddleName, New Field(66, 70))
UD.Add(LegacyCDLISUD.MiddleNameTruncatedCode, New Field(136, 1))
UD.Add(LegacyCDLISUD.MiddleNameTransliteratedCode, New Field(137, 1))
UD.Add(LegacyCDLISUD.LastName, New Field(138, 70))
UD.Add(LegacyCDLISUD.LastNameTruncatedCode, New Field(208, 1))
UD.Add(LegacyCDLISUD.LastNameTransliteratedCode, New Field(209, 1))
UD.Add(LegacyCDLISUD.DateofBirth, New Field(210, 8))
UD.Add(LegacyCDLISUD.Gender, New Field(218, 1))
UD.Add(LegacyCDLISUD.HeightFeet, New Field(219, 1))
UD.Add(LegacyCDLISUD.HeightInches, New Field(220, 2))
UD.Add(LegacyCDLISUD.Weight, New Field(222, 3))
UD.Add(LegacyCDLISUD.EyeColor, New Field(225, 3))
UD.Add(LegacyCDLISUD.TransactionNumber, New Field(228, 4))
UD.Add(LegacyCDLISUD.PreviousJuridiction, New Field(232, 2))
UD.Add(LegacyCDLISUD.PreviousDriverLicense, New Field(234, 25))
UD.Add(LegacyCDLISUD.PreviousSSN, New Field(259, 9))
UD.Add(LegacyCDLISUD.PreviouseName, New Field(268, 35))
UD.Add(LegacyCDLISUD.PreviousDateofBirth, New Field(303, 8))
End Sub
With the code above, you will get 6 by accessing DecalMaxLength(VehicleTypes.Snowmobile), if a member is defined as VehicleTypes enum type, for example, if we have Type property defined in VehicleBE as following:
Public Property Type () As VehicleTypes
We would get the respective Decal Max length with following code:
DecalMaxLength (MyVehcile.Type)
UD(LegacyCDLISUD.PreviousDateofBirth).Offset will get you 303 and
UD(LegacyCDLISUD.PreviousDateofBirth).Lenght will get you 8
If the above 2 scenario do not match the situation you are handing, suggest to defined a static class with proper name and define constants with the static class. Sometime you may want to put all these type of static class into one umbrella class. The following is an example in our AppConstant class
Public Class TransactionNumberLength
Public Const TransactionID = 19
Public Const NewTransactionID = 13
End Class
We have come out 3 different ways in treating constants, let me finish this article by addressing the naming of constant, whither we define them as part of an enum, or define them as constants of a static class, when it comes to naming, we MUST exercise Abstraction. The following are some naming example which did not exercise abstraction:
Public Const ENTRY_APP_TRANS_NUMBER = "ENTRY_APP_TRANS_NUMBER"Public Const SSN = "SSN"Public Const C As String = "C"Public Const PRINT = "Print"Public Const Number_0 = "0"Public Const EMPTY_STRING As String = ""
Public Enum NumberSeries
MINUS_ONE = -1
ZERO = 0
ONE = 1
TWO = 2
THREE = 3
FOUR = 4
FIVE = 5
SIX = 6
SEVEN = 7
EIGHT = 8
NINE = 9
TEN = 10
ELEVEN = 11
TWELVE = 12
THIRTEEN = 13
FOURTEEN = 14
FIFTEEN = 15
SIXTEEN = 16
….
….
End Enum
An easy way to verify if we have exercised abstraction is to see when we change the value of the variables without changing the name, will it cause confusion. If it does, then we did not exercise abstraction.
The following is an example, in which we did not exercise abstraction well.
<Obsolete("Please use MinimumAgeForRenewal")> Public Const AgeForRenewal = 21
In this case, anyone who knows license renewal policy would know that it is not true that you have to be at age of 21 to be able to renew your driving license rather you have to be age 21 or older in order to do so. Sure enough, this constant will be used to compare with customer’s age when doing renewal. It is kind of dangerous to name the constant after the name of the field they are used to compare with.
The guidelines on constant enum naming are exercise Abstraction and use business term to name them.
Thursday, April 25, 2013
Bad Smells in Code -- By Kent Beck
Duplicated Code
Long Method
Large Class
Long Parameter List
Divergent Change
Shotgun Surgery
Feature Envy
Data Clumps
Primitive Obsession
Switch Statements
Parallel Inheritance Hierarchies
Lazy Class
Speculative Generality
Temporary Field
Message Chains
Middle Man
Inappropriate Intimacy
Alternative Classes with Different Interfaces
Incomplete Library Class
Data Class (dumb class)
Refused Bequest
Comments
Monday, April 22, 2013
100% bug free
In the commercial software development world, 100% bug free code is either does not exist, or should not exist or code without commercial value.
Subscribe to:
Posts (Atom)