Showing posts with label Development. Show all posts
Showing posts with label Development. Show all posts
Sunday, June 23, 2013
ASP.NET Web API
The ASP.NET Web API framework was introduced recently into ASP.NET. I touched on it some previously at an overview level, but would like to dig in a little more at this time to show the power of having a true Web API in your product.
Labels:
.NET,
.NET 4.5,
Architecture,
asp.net,
Development,
WebApps
Thursday, April 18, 2013
Extension Methods
I recently saw an email where a development manager was reminding his team of the value of extension methods. This is a great method for adding base class type functionality to objects without introducing dependencies and utility classes for simple functions.
Extension methods are an easy way to "add" functionality to existing types without having to create derived types, recompile, or otherwise modify the original type. Extension methods are a static method, but they are called as if they were methods on the target type. Using C#, there is no apparent difference between calling an extension method and the methods that are actually part of the defined type.
Here is an example extension method. This method will extend the object string to break apart camel cased names and return a human readable name. This can be very useful for populating drop down lists with all values of an Enumeration and other such activities. First, we create the static method as follows.
Then, this method can be called in the same format as any other method on the type String.
These methods are quite simple to create and yet are a very powerful replacement for utility classes. They can be used on native types as well as complex types.
Extension methods are an easy way to "add" functionality to existing types without having to create derived types, recompile, or otherwise modify the original type. Extension methods are a static method, but they are called as if they were methods on the target type. Using C#, there is no apparent difference between calling an extension method and the methods that are actually part of the defined type.
Here is an example extension method. This method will extend the object string to break apart camel cased names and return a human readable name. This can be very useful for populating drop down lists with all values of an Enumeration and other such activities. First, we create the static method as follows.
public static string SplitCamelCase(this String input) { return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim(); }This simply create a method (SplitCamelCase) and adds it to the methods available to any String variable in namepace scope with this class.
Then, this method can be called in the same format as any other method on the type String.
static void Main(string[] args) { String testValue = "ThisIsACamelCasedSentence"; Console.WriteLine(testValue.SplitCamelCase()); }
These methods are quite simple to create and yet are a very powerful replacement for utility classes. They can be used on native types as well as complex types.
Labels:
C#,
Coding,
Development,
Principles
Thursday, April 4, 2013
Inversion of Control (IoC) Pattern
I have been involved in many architectural discussion lately, where groups of people have been throwing around ideas on the correct way to build systems. I am always coming from a position of loosely coupling and making sure that all aspects of your system are interchangeable and have the ability to be dynamically changed or replaced without system wide impact. One topic that I find myself mentioning over and over again is the pattern known as Inversion of Control. Inversion of control (IoC) is a OOP technique by which object coupling is bound at run time by an another object that is typically not known at compile time using static analysis. The basic idea of this pattern is separate the creation of an object from the class which is trying to consume it.
The problem
As with every design pattern, the reasoning behind IoC is to avoid the possibility of design related problems. For example, let's create an Appointment class which contains a Person class object. The biggest issue with the code below is tight the coupling between classes. In other words the Appointment class depends on the Person object. This main seem innocuous enough at a glance. But, the byproduct of this design is that if for any reason Person class changes, it will lead to a compile of the Appointment class. Then, in our world any object compilation leads to regression testing of the recompiled object, even though there was not an actual change.public class Person { } public class Appointment { private Person person; public Appointment() { person = new Person(); } }The biggest problem with the sample code is that the appointment class controls the creation of Person object. The patient class is directly referenced in the Appointment class which leads to tight coupling between these two objects.The Appointment class is aware of the Person class type. So if we add new Person types (like patient, sales person, employee, or pet), it will lead to changes in the Appointment class also as Appointment class is exposed to the actual Person implementation. This also means that the creation of the Appointment class is dependent upon the successful creation of the Patient object within it's constructor.
The solution
If we are able to shift this task / control of object creation from the Appointment class to some other entity we have solved our problem. This means we are able to invert the control to a third party object and thus have found the solution. Some people call the IoC pattern the 'Hollywood' pattern because the simplest explanation of it's purpose is summed up the in phrase "Don't call us, we'll call you." This is a good summary of the idea of this pattern. There are many ways to accommodate this pattern with varying degrees of overhead. In my opinion, the simplest implementation of an IoC Container. IoC containers are used to simplify the provision of a dependant class's dependencies. In the most basic form, an IoC container is an implementation of the service locator design pattern that permits pre-instantiated objects to be registered with the container and later extracted. To substitute a new class and modify the operation of an entire solution, only the initial registration of the type need be changed.IoC Container
Some IoC containers allow you to register types, rather than objects, and instantiate the type when requested, possibly using parameters. Others allow the registrations to be deserialised from an XML file, which could be modified in a text editor. In this article we will create a basic IoC container that does not include these additional features. This will demonstrate the use of IoC containers with the simplest possible code. You may decide to enhance the code to add extra features for your own use. However, you should also consider obtaining one of the many alternative IoC container solutions that are currently available. Following is the code to create a very a basic IoC container.public static class IoC { static Dictionary<Type, object> _registeredTypes = new Dictionary<Type, object>(); public static void Register<T>(T toRegister) { _registeredTypes.Add(typeof(T), toRegister); } public static T Resolve<T>() { return (T)_registeredTypes[typeof(T)]; } }
Using the IoC Container
To illustrate the usage of the IoC container we first need to create an interface and a class that implements it. We will later register an instance of the class for the interface's type. The code for a simple interface and class that is used to grab a value are as follows:public interface IPerson { void SayYourName(string name); } public class Person : IPerson { public void SayYourName(string name) { Console.WriteLine(name); } }We can now register the interface's type and provide a new Person object, which will be returned whenever the type is resolved. You would usually do this when your application is first started. In this example we will only register one type. In a real solution you can register as many types as are required for the operation of your software.
static void Main(string[] args) { IoC.Register<IPerson>(new Person()); IPerson person = IoC.Resolve<IPerson>(); person.SayYourName("Jim Garrett"); }Once registered, any code that has access to the IoC class can resolve the type. In the sample the first line requests the object from the IoC container that implements IPerson. This returns the previous registered Person object. The object is then used to output a message to the console.
Labels:
C#,
Coding,
Development,
Patterns,
Principles
Friday, March 29, 2013
iOS home screen icons for web apps
Since a lot of us are trying to create more dynamic web content for consumption on mobile devices, we find ourselves moving away from native applications and toward responsive design in web applications. One of the small items that can make these web applications feel more like the native app that users download from the iOS store is to create a proper home screen icon. This is the icon that stays on the home screen of the iOS device when a user creates a shortcut. This is easily handled and can actually be designed for specific devices using nothing more than your markup. This is accomplished by creating icons of differing resolutions using a standardized naming convention that will be natively referenced and leveraged by the iOS device as part of the shortcut making process.
One of the cool things that iOS does for you is add rounded corners, shine and drop shadows to your icon in order to ensure some level of short cut consistency. All you need to do there is create you icon without making an attempt at any of those effects. If you consider yourself a graphic artist and want to do your own effects, just append append the -precomposed keyword to the end of the file name when you create your icon. This will instruct the iOS device to not apply the native effects it has. The only thing left at this point is to copy the files to the root directory of your web applications domain with the following naming scheme intact.
This mechanism is flexible enough to allow individual pages to set their own icons via markup as well. Here is an example of targeted icons per device with the following code added to the individual page(s).
Now, when a user on an iOS device creates a shortcut to this web application or a specific page, they will get a nice looking, branded icon that represents the application well and gives the user a native feel for launching their application.
One of the cool things that iOS does for you is add rounded corners, shine and drop shadows to your icon in order to ensure some level of short cut consistency. All you need to do there is create you icon without making an attempt at any of those effects. If you consider yourself a graphic artist and want to do your own effects, just append append the -precomposed keyword to the end of the file name when you create your icon. This will instruct the iOS device to not apply the native effects it has. The only thing left at this point is to copy the files to the root directory of your web applications domain with the following naming scheme intact.
| File Name | Size | Device | iOS adds effects |
| apple-touch-icon.png | Any | Any | Yes |
| apple-touch-icon-precomposed.png | Any | Any | No |
| apple-touch-icon-57x57.png | 57x57 | Touch | Yes |
| apple-touch-icon-57x57-precomposed.png | 57x57 | Touch | No |
| apple-touch-icon-72x72.png | 72x72 | iPad | Yes |
| apple-touch-icon-72x72-precomposed.png | 72x72 | iPad | No |
| apple-touch-icon-114x114.png | 114x114 | Retina | Yes |
| apple-touch-icon-114x114-precomposed.png | 114x114 | Retina | No |
| apple-touch-icon-144x144.png | 144x144 | Retina | Yes |
| apple-touch-icon-144x144-precomposed.png | 144x144 | Retina | No |
This mechanism is flexible enough to allow individual pages to set their own icons via markup as well. Here is an example of targeted icons per device with the following code added to the individual page(s).
<link rel="apple-touch-icon" href="/icon.png"/>
<link rel="apple-touch-icon" href="iphone-icon.png" />
<link rel="apple-touch-icon" sizes="72x72" href="ipad-icon.png" />
<link rel="apple-touch-icon" sizes="114x114" href="iphone4-icon.png" />
<link rel="apple-touch-icon" sizes="144x144" href="ipad144-icon.png" />
Now, when a user on an iOS device creates a shortcut to this web application or a specific page, they will get a nice looking, branded icon that represents the application well and gives the user a native feel for launching their application.
Labels:
Development,
iOS,
WebApps
Tuesday, March 12, 2013
The argument for coding standards
Creating and enforcing
coding standards, or coding style guidelines, is one method by which software
companies can ensure that source code written by a software developer is easily
understood, while being maintained by any other software developer in their
employ. Smashing Magazine contributor Nicholas C. Zakas penned an article titled,
“Why Coding Style Matters”, illustrating the value realized by creating and
adhering to coding standards. He states
that standards ensure individual members of a development team are able to tailor
the visual appearance of their source code while still allowing their
individual talents to flourish.
Standardized coding style also ensures better communication between team
members by allowing the product of work to act as a form of documentation for
the creators to leave clues for themselves and for others who come after. Potential programming errors are more easily
identified when a group of programmers adheres to a coding standard since any
code that does not comply becomes more visible and draws scrutiny of other
developers. Standardizing the code
comment, which is a way for developers to create non-executing code strictly
designed for inter-developer communication, is a good way to ensure other
engineers are able to understand why code was written in this specific way to
accomplish the known task.
Zakas begins the article by discussing his own introduction to coding
standards as a student in college. One
of his professors considered the style with which code was written equally as important
as the execution of the code. His
definition of coding style is insightful as it illustrates that the standard
can be as generalized or granular as the creator desires. All individual developers inherently have a
coding style, whether formalized and forced or inadvertently formed in
seclusion over time. The biggest challenge with a standardized style to a
creative group, he states, is the undeniably personal nature of any style. Mr. Zakas created a memorable simile
regarding individual musicians in a band.
While all of the musicians have a talent on their instruments, unless
they are orchestrated in some fashion beyond their individual creative style,
the music they produce will not likely be enjoyable to the listener. The structure provided by band governance for
items such as tempo, key, and lead timing, ensures a quality musical product
without forcing the conformance of individual creativity. That is exactly the marriage of the individual dynamic
within a team structure that is required. Prior to enforcing standards, you have to understand the challenges and resistance will be based on individual styles and creativity being 'standardized'. It is vital to communicate that coding standards and style guides do not throttle creativity or individualism, they simply channel it into a team effort and ensure forward progress.
Communication is a natural and valuable byproduct of coding
standards. Most communication within a
group of developers is resident within the source code itself. The output of any developer’s daily work is a
complete, exhaustive, and readable trail of every task he or she executed. When one developer reads the source code
created by another developer, the original developer’s view of the problem,
strategy to correct it, and final solution are communicated to the second via
the code itself. Once you reach this
realization alone, it indicates the need for standardization. The code communication is also useful for
developers to leave clues for themselves in the future. It is equally important for the author of the
code to understand that he may need to maintain a creation of his own in the
distant future. Intellectual breadcrumbs
and standardized formatting will ensure that old code and new code look the
same to the maintaining programmer.
Coding standards bring potential software errors
into view more easily. As programmers become more acclimated to specific patterns, they will more
naturally notice code that does not adhere.
This ultimately draws the attention of programmers and causes them to
consider the segment of code more closely, as it is an anomaly. Since the coding standard itself is designed
to enable consistently stable source code, one must focus on which items to
standardize with direct intent. You will probably not find a coding style guide with too much detail, but can find them with too little detail. The importance in your level of detail is based on the importance of ensuring items that are standardized are complete and
targeted at specific items important to the individual team. In other words, its not a good idea to standardize every aspect of development, just for the sake of doing it. You should focus on standards as they align with your business need and allow the developers to leverage their creativity and talent within the style guide.
Labels:
Coding,
Development,
Principles
Monday, February 4, 2013
Authorization Using WIF 4.5
I'd like to continue the topic of claims-based security using WIF 4.5, and talk about the authorization model and its options at a deeper level. First, just to ensure we are all using the same terminology when discussing items, I want to clarify "authorization" when I use it in this context. Authorization and authentication are still widely confused when discussing overall security methodology. They are both aspects of security, but they play completely different roles in the process.
Authorization is the mechanism by which we evaluate whether an authenticated user has access to a specified modality (url, service, module or data element) within the application to which they are authenticated. For instance, an authenticated user may be an administrator which makes them authorized to change settings, post content, etc. While another authenticated user may be a guest, which makes them authorized to read public content. In its most simple form, authentication is who you are and authorization is what you are allowed to do.
Authorization vs. Authentication
Authentication is really just the process of having users log in so you can ensure they have the right to access the application. Authentication is the concept at work when you log in to any web application at all. By having an approved and active user account, and entering the proper credentials, the user is authenticated to use the application. In most cases, users are authenticated prior to authorization.Authorization is the mechanism by which we evaluate whether an authenticated user has access to a specified modality (url, service, module or data element) within the application to which they are authenticated. For instance, an authenticated user may be an administrator which makes them authorized to change settings, post content, etc. While another authenticated user may be a guest, which makes them authorized to read public content. In its most simple form, authentication is who you are and authorization is what you are allowed to do.
Claims-based Authorization
As we discussed before, claims-based authorization is the approach where you write code to allow or disallow access based on logic that checks data called 'claims'. Remember that in the case of a role-based authorization, the only claim we actually used was the claim a user made about his or her roles. A role claim was used for us to decide if the current user 'is a' specific role. Let's walk through making access decisions using a claims-based authorization approach.- A user arrives at your application and needs to be authenticated.
- WIF forwards the user to your identity provider.
- Once the user is authenticated, the original request is made again, but now there is a new security token attached to the request which contains data representing the user by using claims representing each granular piece of data. WIF attaches these new claims to the principal that represents the user so it can be referenced quickly and easily.
- Your application checks the claims via code to ensure the claims are met. These checks can be made via code, service calls, database, home-grown rules, or the native ClaimsAuthorizationManager.
- Your application decides whether or not to allow the request based on the claims:logic check.
- Your application grants the request if the outcome of your check is true and denies it if false.
Role-based Authorization
Role-based authorization is implemented by assigning users to user roles that have been defined for the application. This is the example that I used when talking about an administrator or a guest. Both of those are considered roles. When using this methodology, users are assigned 1:n roles within the system which can be checked at run time for derivation of access rights. You can check the roles of the user in a few different ways to ensure they are authorized for access.- Checking IPrincipal.IsInRole(“RoleToCheck”). This is probably the most straight-forward and widely-used method. Since it returns a boolean indicating membership in the role, you can use it in your conditional statements at any place in your code as a security check.
- Using PrincipalPermission.Demand(). When you make the Demand() call, the application will throw an exception if the demand is not met by the roles. This flows into standard try-catch-finally blocks and makes authorization just another exception in the block. Be warned that exceptions are much more expensive from a performance standpoint when compared to the IsInRole() method.
- Using the <authorization> section in web.config. This really only works if you are blocking entire URLs against roles. This is the most strict, blanket level authentication so far. The upside is that it requires no code changes for implementation since it is part of the configuration file.
- Using [PrincipalPermission(SecurityAction.Demand, Role = “RoleToCheck”)] attributes. The declarative method cannot be used in code blocks or within the service/method implementations as it is an actual attribute of the method itself. The method will throw an exception if the authenticated user doesn't belong to the role being demanded.
Labels:
.NET 4.5,
Architecture,
Development,
Security,
Services,
SOA,
WIF
Thursday, January 17, 2013
Javascript is a Free-For-All....
As part of a boot camp I am teaching this week, we decided to see how much insanity we could inject into Javascript before it would fail. The group is made up of experienced C# programmers and we decided to experiment with blowing up the sort of structure and type restrictions we have all grown accustomed to in a structured language. We created the following code block just to see how far we could push the 'undefined ' functionality, along with the variable typing being a basic free-for-all.
This is not only viable syntax, but this code will run and output values consistent with the index resolution of the array (when it is an array and not a function, that is). Interestingly, it appears to be a valid strategy to have an undefined value as a key in a key value pair. My favorite aspect of this is declaring a function, array and key/value list as a single variable and have it act accordingly depending on how you reference it. Even when you make one of the values within the key/value array the array itself.
Go home Javascript, you are drunk.
var arr = function()
{
alert(arr['testB']);
}
arr['testA'] = true;
arr['testB'] = false;
arr['testC'] = true;
arr[arr[0]] = arr;
document.write(arr[arr[0]]);
document.write("<br/>");
document.write(arr['testC']);
document.write("<br/>");
document.write(arr[0]);
document.write("<br/>");
arr[arr[0]]();
document.write("<br/>");
document.write("foreach...<br/>");
for (var i in arr)
{
document.write(arr[i]);
document.write("<br/>");
}
This is not only viable syntax, but this code will run and output values consistent with the index resolution of the array (when it is an array and not a function, that is). Interestingly, it appears to be a valid strategy to have an undefined value as a key in a key value pair. My favorite aspect of this is declaring a function, array and key/value list as a single variable and have it act accordingly depending on how you reference it. Even when you make one of the values within the key/value array the array itself.
Go home Javascript, you are drunk.
Labels:
Coding,
Development,
Javascript
Tuesday, June 12, 2012
Object Design Principles - Part 5
Dependency Inversion Principle
The DIP states that high level classes should not depend on
low level classes. Both should depend on abstractions. Details should depend
on abstractions. Abstractions should not depend on details. The DIP is about
reversing the direction of dependencies from higher level
components to lower level components such that lower
level components are dependent upon only the interfaces owned by the higher level components. This is a method for moving to a more loosely
coupled architecture. Basically, you
have to depend on a standard interface used by objects and not depend on
their details. This one might be best
illustrated by example.
In the following example, the BadCar class is tightly coupled to the actual implementation of the BadMotor function. This means that these two objects are married, and changes to one directly impact the other.
public class BadMotor
{
public Boolean Start()
{
Console.Write("Starting");
return true;
}
}
//tightly coupled to details.
public class BadCar
{
public BadMotor Motor {get;set;}
public Boolean Start(BadMotor badMotor)
{
Motor = badMotor;
return Motor.Start();
}
}
While this does function, it creates a dependency relationship between two objects at their implementation level. This creates hardships for maintenance and scalability long term. The proper way to build this relationship would be to invert dependencies onto interfaces to ensure no object has knowledge or visibility into implementation of any other object. Consider the following examples:
public interface IEngine
{
bool Start();
}
public interface IGreenEngine : IEngine
{
bool IsCharged ();
}
public class FourCylEngine : IEngine
{
public bool Start()
{
Console.WriteLine("4Cyl Starting");
return true;
}
}
public class V8Engine : IEngine
{
public bool Start()
{
Console.WriteLine("V8 Starting");
return true;
}
}
public class HybridEngine : IGreenEngine
{
public bool Start()
{
if (IsCharged())
Console.WriteLine("Hybrid Starting");
return true;
}
public bool IsCharged()
{
Console.WriteLine("Hybrid is charged");
return true;
}
}
public class Car
{
public Car(IEngine engine)
{
Engine = engine;
}
public IEngine Engine{get ; set ; }
public Boolean Start()
{
return Engine.Start();
}
}
I built this interface dependency and inheritance to ensure that objects are loosely coupled and only share an interface. This allows for actual base implementations to come and go and even be recognized dynamically without causing lower level objects to update their implementation. Here is an example of hot swapping and scaling with the previously defined objects and interfaces.
class Program
{
static void Main(string[] args)
{
// Cars are only dependant upon an Engine interface
Car BigThing = new Car(new V8Engine());
BigThing.Start();
// Cars are only dependant upon an Engine interface
Car SmallThing = new Car(new FourCylEngine());
SmallThing.Start();
// Since we have an interface dependency, it is easy to hot swap.
BigThing.Engine = new HybridEngine();
BigThing.Start();
}
}
The output is as follows:
As you can see, this allows for maintainability and long-term scalability by ensuring that the objects stay out of each other's business. By adhering to the spirit of this principle as well as the previous SOLID principles, you can keep your code base healthy and easy to maintain when the requirement changes come.
Labels:
.NET,
Architecture,
C#,
Coding,
Development,
Principles,
SOLID
Friday, June 8, 2012
Object Design Principles - Part 4
Interface Segregation Principle (ISP)
The ISP says that an interface should not become too 'fat' but
be split into smaller and more specific interfaces so that only methods that
pertain to a client need to be implemented. You should focus on designing abstractions
that have a very small, focused and sleek design.
Basically, no client should be forced to implement methods or properties
it does not need to use. We should
always start at the most granular level and extend interfaces as needed. You can create new interfaces that are extensions, or groupings, of other interfaces to form classes and objects
desired. Rather than forcing
everyone to consume the entirety of a polluted interface, you are allowing them to
implement an array of more focused interfaces.
I like analogies for getting my hands around design principles. I think of this one much like eating at a
restaurant. If you sit down and order
a burger, how do you react if you are given soup; then a burger, fries, and a coke; then an ice cream sundae? And you are expected to pay for all of it.
Apparently, the only way to get a burger is to implement the IThreeCourseMeal
interface. If it doesn't make sense in life, it doesn't make sense in design.
During application design we should pay close attention to how we abstract modules that contain several sub-modules. Granularity is always the side on which to err when doing interface design. It is much easier to couple interfaces than to decouple a polluted interface (just as it would be very difficult to 'un-salt' your food.) As I look through existing interfaces, it seems that this principal is easily and repeatedly violated, probably without intent. In reviewing for this piece, I saw that months ago I created an interface that flagrantly violated this principle as a quick means to an end. I plan to decouple it as part of this mental exercise.
Using the restaurant analogy above, I created some interfaces that, while silly, illustrate the principle. First, I would go for the most granular interface that could logically be shared for all iterations of this type. I landed on a menu item:
public interface IMenuItem
{
String Item { get; set; }
String Price { get; set; }
}
Then, I started creating logical abstractions of a menu item into various aspects of a meal:
public interface IEntree : IMenuItem
{
String CookingInstructions { get; set; }
}
public interface ISide : IMenuItem
{
Boolean IsVeggie { get; set; }
}
public interface IDrink : IMenuItem
{
Int16 CupSize{ get; set; }
}
public interface IAppetizer : IMenuItem
{
//...
}
public interface IDessert : IMenuItem
{
//...
}
Next, I moved onto large interfaces that would have enough real world implementations to justify a single abstraction:
public interface IValueMeal : IEntree, ISide, IDrink
{
//...
}
public interface IThreeCourseMeal : IAppetizer, IEntree, ISide, IDrink, IDessert
{
//...
}
The advantage is that I can always come in at the implementation level and create my own dynamic abstraction. Notice which properties' objects are created when I choose to implement the interface:
public class MyCustomMeal : IEntree, IDrink
{
#region IEntree Members
public string CookingInstructions
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
#endregion
#region IMenuItem Members
public string Item
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public string Price
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
#endregion
#region IDrink Members
public short CupSize
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
#endregion
}
Hopefully, you can see how this principle allows for much scalability and dynamism of types without the inherent bloat from linear bulge. This is a great principle to keep in focus during design.
Labels:
.NET,
Architecture,
C#,
Coding,
Development,
Principles,
SOLID
Friday, May 25, 2012
Object Design Principles - Part 1
Singular Focus and Coupling
This will be the first installment of a multiple part
posting on object design principles.
These are vital to keep in mind as we go through creation of large
product platforms with many interaction services and objects that must be
maintained and enhanced over time.
Object Responsibility
In my mind, the most vital question you can ask yourself at
the outset of an object design is, "What is this object's core
responsibility?" Your entire design
should flow from that very basic question. You should consistently look for the
most granular object definition possible and work back from that. It's really easy to get blinded by the
vastness of the entire project and the complete set of user stories and
completely misjudge where to segregate your logic. Once you have defined the core responsibility
and focus of an object, you can immediately start creating an inheritance path
as well as supplemental interfaces to bring your object into full
functionality. This is the most vital
step in ensuring a scalable and easily maintainable system long term. Consider the following basic user
requirement: "I need to be able to
view images and apply enhancements to them." The first thing that comes to my mind is that
although the user requirement is to always view images, every image view
session will not ultimately result in an image enhancement session. So, I immediately break into two objects, a
viewer and an editor : viewer. At its
core, the viewer object should do nothing more than accept image data and
render in a viewable state. The viewer should have no concept of any data or
state outside of the image itself. It
should interact via an interface with a standardized image format so that it
doesn't need to have any system context.
The system also should have no specific knowledge of the viewer (more on that when we talk about coupling). Then, the editor class should start by extending the known viewer class. It should not extend any operation that pertains to the loading and displaying of the base image. That aspect of responsibility should be a black box to the editor. The editor should contain an interface for advertising its list of manipulations as well as a standardized message based interface for executing them. This object is not responsible for a menu or toolbar system, it is simply an image manipulator requiring system input to launch an execution of its internally known action. It also would not have any context for displaying an image history listing. It would maintain a list of events, based on its internally known list of manipulations and allow an outside source to interact with that list via a standardized message or interface.
The system also should have no specific knowledge of the viewer (more on that when we talk about coupling). Then, the editor class should start by extending the known viewer class. It should not extend any operation that pertains to the loading and displaying of the base image. That aspect of responsibility should be a black box to the editor. The editor should contain an interface for advertising its list of manipulations as well as a standardized message based interface for executing them. This object is not responsible for a menu or toolbar system, it is simply an image manipulator requiring system input to launch an execution of its internally known action. It also would not have any context for displaying an image history listing. It would maintain a list of events, based on its internally known list of manipulations and allow an outside source to interact with that list via a standardized message or interface.
Loosely Coupled Objects
The main point of the granularity of the design listed above
is to ensure a loosely coupled framework.
These controls and objects should all be interacted with via their
interface over standardized messages. If
each object is singularly purposed and has a black box for its implementation,
the only exposure and ultimate point for breakdown is the interface itself. The loosely coupled system (or systems)
interacts with itself based on standard messages or interfaces. The
granularity, once released to production, allows for a dynamically upgradeable
system with hot swap components. In this
scenario, we could easily swap out our image viewer or image editor in any
given system with a very limited impact on the system as a whole. The change would be contained in a singularly
purposed object that is loosely coupled with its housing system. We would be able to quickly respond to a requirement for viewing a new image format without having to make changes to our image editor control. Additionally, this transforms every control,
service or object in every system into a plausible enterprise level base class by
never assuming product knowledge or any aspect of external state.
By thoroughly investigating singular focus and coupling as part of every design, we can work toward a much more stable and dynamic system in the future.
Labels:
.NET,
Architecture,
C#,
Coding,
Development,
Principles,
SOLID
Tuesday, May 22, 2012
Microsoft Certifications
The certification marathon is complete. The process was long and extremely difficult. The exams themselves are very detailed and require some fairly in-depth knowledge of the specific environment / technology being covered. I received the following six certifications:
For those of you keeping score, or just wondering, I passed all of my exams the first time (passing grade was 700/1000) . My average score was just above 870/1000 with a high of 978/1000 (MCPD Windows). I hope to leverage the new knowledge and intense training on some new platforms very soon.
- MCTS - Accessing Data with .Net Framework 4.0
- MCTS - .Net Framework 4 - Web Application Development
- MCTS - WCF Development with .Net Framework 4.0
- MCTS - .Net Framework 4 - Windows Application Development
- MCPD - Designing and Developing Windows Applications using .Net Framework 4.0
- MCPD - Designing and Developing Web Applications using .Net Framework 4.0
For those of you keeping score, or just wondering, I passed all of my exams the first time (passing grade was 700/1000) . My average score was just above 870/1000 with a high of 978/1000 (MCPD Windows). I hope to leverage the new knowledge and intense training on some new platforms very soon.
Labels:
C#,
Certifications,
Development
Monday, May 14, 2012
jQueryUI and ASP.NET Master Pages
Here is cool trick to save some time when using jQueryUI and ASP.NET with master pages. The thing that always seems to trip someone up is finding a control from the master page and trying to hit it with a jQuery call. When ASP.NET adds a control to the DOM and you are using master pages, the ID is actually changed from what you assigned in the designer. It seems to be fairly random and shouldn't be counted on for consistency or convention, aside from all of the randomness preceding the ID from the designer. After piddling around for a while, I did find something that will work. Consider the following code (This code assumes you have all of your links and css hooked up.):
By using the jQuery "ends with" selector ($=) I am able to find any control with an ID. So, by using this master page, ANY control that has an ID ending with 'txtCal' will be formatted to be a drop down calendar using jQueryUI. By using this sort of approach and following consistent naming conventions, you would be able to do most of your UI changes from your master pages, allowing for consistent theme style control over their implementation.
This also opens the door for driving more jQuery behavior from the the master page.
<script type="text/javascript">
$(function ()
{
$('[id$=txtCal]').datepicker({
showOn: "button",
buttonImage: "../images/calendar16.png",
buttonImageOnly: true,
buttonText: 'Choose'
});
}
</script>
Labels:
asp.net,
Coding,
Development,
jQuery,
Visual Studio,
VS2010
Sunday, May 6, 2012
MCTS Windows Development with .NET 4
The first certification I am pursuing is the MCTS in Windows application development. Coming in with a few years of C# winforms development in hand, I thought this one would be fairly straightforward. I soon realized that having in-depth exposure in my world doesn't always equate to having wide exposure in the rest of the world. The expectations are high for this session. The workload amounts to 12-13 hours a day between labs, studying and practice tests. I have read a five hundred and eighty page text book in just over two days and have found that at least 65% of it has been fairly new territory. The MCTS certification is heavily slanted to WPF. It seems like Microsoft is pushing the technology toward this platform as the standard for development. After having some time to delve into it, the reason becomes obvious. The rich presentation layer that can be created on this platform is powerful, scalable and adaptable. The xaml itself is not unlike any other markup, and if you can read and follow html, xml, etc., you will be fine reading through xaml and understanding the intent of the code. What stands out to me regarding this platform is the inherent dynamism of the GUI itself. The ease with which we can create a highly usable and intuitive interface is really quite impressive. Take the following example (borrowed from the class):
This creates a button template that applies a style (very ugly) and behavior that can be associated with any button. By including the following style block and associated setters, the template is automatically applied to all buttons contained in the current window.
If I wanted to apply this template and style to the entire application, I would simply move these snippets to the app.xaml. Another level of dynamism comes by allowing you to link to external xaml files as application resources and swap them. So, not only could you customize the look and feel of the application, you can dynamically customize the inherent behavior of elements at the application level. There is a ton more to get into with this kind of thing, and we will at a later date. Other possibilities include, command triggers, gestures, framed animations and much more. It has been very interesting to date and I will bring back some renewed focus on pushing the ui envelope within our applications.
<Window.Resources>
<ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
<Grid>
<Ellipse Name="Ellipse1" Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="{TemplateBinding BorderThickness}">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin=".5, .5">
<GradientStop Color="Red" Offset="0" />
<GradientStop Color="Orange" Offset=".25" />
<GradientStop Color="Blue" Offset=".5" />
<GradientStop Color="Yellow" Offset=".75" />
<GradientStop Color="Green" Offset="1" />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Ellipse1" Property="Fill">
<Setter.Value>
<RadialGradientBrush GradientOrigin=".5, .5">
<GradientStop Color="LightCoral" Offset="0" />
<GradientStop Color="LightSalmon" Offset=".25" />
<GradientStop Color="LightBlue" Offset=".5" />
<GradientStop Color="LightYellow" Offset=".75" />
<GradientStop Color="LightGreen" Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Ellipse1" Property="Fill">
<Setter.Value>
<RadialGradientBrush GradientOrigin=".5,.5">
<GradientStop Color="Gray" Offset="0" />
<GradientStop Color="LightGray" Offset=".25" />
<GradientStop Color="Black" Offset=".5" />
<GradientStop Color="White" Offset=".75" />
<GradientStop Color="DarkGray" Offset="1" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard AutoReverse="True">
<DoubleAnimation To="0" Duration="0:0:0.1"
Storyboard.TargetProperty="Width" />
<DoubleAnimation To="0" Duration="0:0:0.1"
Storyboard.TargetProperty="Height" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="{x:Type Button}">
<Setter Property="Template" Value="{StaticResource ButtonTemplate}" />
</Style>
</Window.Resources>
This creates a button template that applies a style (very ugly) and behavior that can be associated with any button. By including the following style block and associated setters, the template is automatically applied to all buttons contained in the current window.
<Style TargetType="{x:Type Button}">
<Setter Property="Template" Value="{StaticResource ButtonTemplate}" />
</Style>
If I wanted to apply this template and style to the entire application, I would simply move these snippets to the app.xaml. Another level of dynamism comes by allowing you to link to external xaml files as application resources and swap them. So, not only could you customize the look and feel of the application, you can dynamically customize the inherent behavior of elements at the application level. There is a ton more to get into with this kind of thing, and we will at a later date. Other possibilities include, command triggers, gestures, framed animations and much more. It has been very interesting to date and I will bring back some renewed focus on pushing the ui envelope within our applications.
Labels:
C#,
Certifications,
Development,
WPF
Subscribe to:
Posts (Atom)
