I just love this quote. It shows us our unchanging ways and how we stick to something for the sake of sticking to it and after careful consideration we might find that something that held true for years and which we either liked or came to depend on is no longer relevant.
This is maybe the biggest challenge I find as a leader, to continuously challenge the process and to refine it, redefine the reason and to improve on it.
In my team we continuously investigate all processes and try to either improve on them or at least see whether they still hold true or whether we are just doing them for some legacy reason. Processes are only relevant if they still hold true.
Here is an example of our revision when it comes to tracking development work and bugs.
“We need prisoners to interrogate, and that tends to work best when they're alive”
As with prisoners you also need to keep bugs in a location so that they don’t “escape” and cause mayhem. We I took over the department, bugs was handled in a spreadsheet that was mailed around and everyone could do one, add one and it was expected that every developer would test his own bugs / work and bugs was only reported and added to the sheet after the publish was made to the client. This means that most of the bugs were reported by the client. (Not so good)
I started looking at the process and it was very inefficient and costly. Sometimes the same bug would be fixed by two developers, communication on the process and progress was shoddy and we often had recurring issues.
The process was insufficient
The first step we took was to centralize the logging, progress tracking and assignment of bugs by creating a system we call “Devlog”. This meant that all bugs was hosted in a databases and that developers would only do the bugs that was assigned to them or in some cases where the developers were faster than I could allocate work they could claim bugs. This tool has now evolved to where it helps with overall planning and resource allocation.
This process seemed to work really well: in the beginning. Soon loop holes appeared and bugs would still be recognized too late or developers would not test their own work properly.
The process was better, but had loopholes
I soon realized, as a developer, I would test around the conditions that made the software work and users tested a completely different way. Since there was no way I could sufficiently do Hallway testing I decided to hire someone to do my QA (see our blog on QA). So my Quality assurance department was born. Rules were wrote up, reports styled and we would soon dedicate time for every developer to give their work QA for testing, and we would allocate time before any release for testing and bug fixing. This meant that most bugs were reported internally and the client would never see 90 % of the issues instead of reporting 90 % of the issues.
The process delivers results
Soon we had less bugs, better turnaround time, and due to the QA reports being official and used in every developer’s revue we had less bugs and software that was developed faster and better than ever before.
“The Code is more like guidelines, really”
Although this is a small part of our entire development process and even our current QA process, it is a critical one and we continuously look to giants like Microsoft, Apple and Google to see what they do differently and how we could take their processes and apply them to our business. Taking into consideration that we don’t have Google type budgets, man power or timelines there always seem to be some tweaking to a process to get it to work for us, but it does help us to see that one fact holds true. Even though a process might be sufficient today, it can always be optimized tomorrow.
Visit the QBCon website.
Microsoft Visual Studio tips and tricks
Today I will discuss some Microsoft Visual Studio tips and tricks any web developer should be aware of. These tips and tricks will improve your productivity and ease your day-to-day development duties so that every developer can boost his output.
Keyboard shortcuts can save a lot of time. Microsoft Visual Studio ships with an arsenal of standard keyboard shortcuts for common tasks and allows for customisation (Tools > Options (Show All Settings) > Environment > Keyboard). As part of our in-house development and training programme, every developer is expected to know Visual Studio. Below is a list of useful standard keyboard shortcuts used in common day-to-day tasks:
1. F7: Toggle between code-behind and mark-up.
2. Shift + F7: Switch the designer between modes e.g. Source and Design Views.
3. Right Alt + Right Shift + Enter: Switch between full screen and normal mode.
This is particularly useful for code files, where every bit of display real estate is valuable.
4. Ctrl + K + D: Formats any code file's content with properly defined indentation for readability.
5. Debugging shortcuts: F5 > Run with Debugging, Ctrl + F5 > Run without Debugging, F10 > Step Over and F11 > Step Into.
6. Ctrl + M + L: Toggle code files between collapsed or expanded view.
7. Shift + Del: Delete the current line.
8. F12: Go To Definition of the current item.
9. Ctrl + K + C: Comment the current code block.
10. Ctrl + K + U: Uncomment the current code block.
Environment setup can hog a computer with unnecessary eye-candy robbing you of valuable development time. Here are a few tweaks to speed up Microsoft Visual Studio: (All these options are under Tools > Options (Show all settings))
1. Environment > AutoRecover: If you're in the habit of regularly saving your work and have a source control server, you can turn this option off and save precious hard drive access.
2. Environment > General: Adjust or turn off visual enhancements (VS2005: Animate Environment Tools and VS2010: Automatically adjust visual experience ... )
3. Environment > Startup > At startup > Show empty environment: Speeds up launch time and does not download content from the news channels.
3. Launch time: Right-click the Microsoft Visual Studio shortcut, click Properties > Shortcut and add -nosplash at the end of the Target. This will speed launch time even more.
4. Page file: Hard drive access has a significant impact on Microsoft Visual Studio. By default the page file is located on the system drive. To speed up the system, move the page file to another physical drive to take pressure off the system drive. Preferably the physical drive used for the page file should do only paging for maximum benefit.
5. ReadyBoost: If you are using Microsoft Windows Vista / 7, you could take advantage of the ReadyBoost feature. ReadyBoost keeps a shadow copy of the page file on a device with faster access time and burst read speed than a typical hard drive.
Normally, a flash drive would suffice this requirement and is a cost-effective means to speed up system performance without upgrading hardware.
There you go, a bunch of easy tips and tricks to make you more productive and maximize your development experience. Enjoy!
Keyboard shortcuts can save a lot of time. Microsoft Visual Studio ships with an arsenal of standard keyboard shortcuts for common tasks and allows for customisation (Tools > Options (Show All Settings) > Environment > Keyboard). As part of our in-house development and training programme, every developer is expected to know Visual Studio. Below is a list of useful standard keyboard shortcuts used in common day-to-day tasks:
1. F7: Toggle between code-behind and mark-up.
2. Shift + F7: Switch the designer between modes e.g. Source and Design Views.
3. Right Alt + Right Shift + Enter: Switch between full screen and normal mode.
This is particularly useful for code files, where every bit of display real estate is valuable.
4. Ctrl + K + D: Formats any code file's content with properly defined indentation for readability.
5. Debugging shortcuts: F5 > Run with Debugging, Ctrl + F5 > Run without Debugging, F10 > Step Over and F11 > Step Into.
6. Ctrl + M + L: Toggle code files between collapsed or expanded view.
7. Shift + Del: Delete the current line.
8. F12: Go To Definition of the current item.
9. Ctrl + K + C: Comment the current code block.
10. Ctrl + K + U: Uncomment the current code block.
Environment setup can hog a computer with unnecessary eye-candy robbing you of valuable development time. Here are a few tweaks to speed up Microsoft Visual Studio: (All these options are under Tools > Options (Show all settings))
1. Environment > AutoRecover: If you're in the habit of regularly saving your work and have a source control server, you can turn this option off and save precious hard drive access.
2. Environment > General: Adjust or turn off visual enhancements (VS2005: Animate Environment Tools and VS2010: Automatically adjust visual experience ... )
3. Environment > Startup > At startup > Show empty environment: Speeds up launch time and does not download content from the news channels.
3. Launch time: Right-click the Microsoft Visual Studio shortcut, click Properties > Shortcut and add -nosplash at the end of the Target. This will speed launch time even more.
4. Page file: Hard drive access has a significant impact on Microsoft Visual Studio. By default the page file is located on the system drive. To speed up the system, move the page file to another physical drive to take pressure off the system drive. Preferably the physical drive used for the page file should do only paging for maximum benefit.
5. ReadyBoost: If you are using Microsoft Windows Vista / 7, you could take advantage of the ReadyBoost feature. ReadyBoost keeps a shadow copy of the page file on a device with faster access time and burst read speed than a typical hard drive.
Normally, a flash drive would suffice this requirement and is a cost-effective means to speed up system performance without upgrading hardware.
There you go, a bunch of easy tips and tricks to make you more productive and maximize your development experience. Enjoy!
Using PageMethods in ASP.Net Ajax
In addition to allowing XML-HTTP requests to call conventional Web service methods, ASP.NET AJAX also supports a special type of Web method known as the page method. Page methods are Web service methods implemented in Web pages (*aspx). This means there is no need for a conventional ASMX (Web services) file. Page methods enable developers to trigger XML-HTTP type call-backs (in other words, there is no need for a PostBack to the server) without building dedicated Web services.
Page methods must be public static methods and must be decorated with the [WebMethod] or [ScriptMethod] attribute. Your page must be ajax enabled, meaning a ScriptManager must be present (Set the EnablePageMethods attribute to true)
[WebMethod]
public static string example(int var1, int var2)
{
return "This string was returned by the Page Method with values" + var1 + " and " + var2;
}
PageMethods can return any variable type and even objects as long as it is serializable.
The setup for using PageMethods is now complete. Let’s have a look at how to put it all together.
Using JavaScript, call the webmethod as defined in your aspx.cs file by making use of the PageMethod object.
function btnSomething_Click()
{
var var1 = 10;
var var2 = 20;
PageMethods.example(var1, var2,
function success(result, context, methodName)
{
window.alert(result + ‘ was returned by ‘ + methodName);
},
function failed (err, context, methodName)
{
window.alert(methodName + "\n" + err.get_message());
},
“this is a context variable” );
}
Successful execution resulted in the success javascript function being called. This method receives three parameters. Result contains the value returned by the PageMethod.
If the PageMethod could not be called, or something went wrong in returning a value back to the client the failed javascript method is called.
In the above example, both the successful () and failed () functions received a parameter called context. This is a optional parameter that can be supplied by the user in the original PageMethod call. The value of the user context variable will now contain the value “this is a context variable”. If nothing was passed to the page method, this value will be null. We use PageMethods religiously when the client expects increased performance and response times. Combined with a healthy understanding of HTML rendering and Stylesheets (see our blog on CSS) there is little a well-constructed Javascript function using Pagemethods cannot do.
And that is all that is to it. Easy!
Carel Steenkamp
Page methods must be public static methods and must be decorated with the [WebMethod] or [ScriptMethod] attribute. Your page must be ajax enabled, meaning a ScriptManager must be present (Set the EnablePageMethods attribute to true)
[WebMethod]
public static string example(int var1, int var2)
{
return "This string was returned by the Page Method with values" + var1 + " and " + var2;
}
PageMethods can return any variable type and even objects as long as it is serializable.
The setup for using PageMethods is now complete. Let’s have a look at how to put it all together.
Using JavaScript, call the webmethod as defined in your aspx.cs file by making use of the PageMethod object.
function btnSomething_Click()
{
var var1 = 10;
var var2 = 20;
PageMethods.example(var1, var2,
function success(result, context, methodName)
{
window.alert(result + ‘ was returned by ‘ + methodName);
},
function failed (err, context, methodName)
{
window.alert(methodName + "\n" + err.get_message());
},
“this is a context variable” );
}
Successful execution resulted in the success javascript function being called. This method receives three parameters. Result contains the value returned by the PageMethod.
If the PageMethod could not be called, or something went wrong in returning a value back to the client the failed javascript method is called.
In the above example, both the successful () and failed () functions received a parameter called context. This is a optional parameter that can be supplied by the user in the original PageMethod call. The value of the user context variable will now contain the value “this is a context variable”. If nothing was passed to the page method, this value will be null. We use PageMethods religiously when the client expects increased performance and response times. Combined with a healthy understanding of HTML rendering and Stylesheets (see our blog on CSS) there is little a well-constructed Javascript function using Pagemethods cannot do.
And that is all that is to it. Easy!
Carel Steenkamp
To clone or not to clone
Have you ever needed to copy an object’s values to another object of the same type? If you have and have done this manually by copying each value separately this blog entry is for you. In this post I will guide you to make the object cloning process as easy as possible.
Let's say you have the following classes
public class Person
{
public Person()
{ }
private string _FirstName = "";
private string _LastName = "";
private Car _Car = new Car();
public string FirstName
{
get { return _FirstName; }
set { _FirstName = value; }
}
public string LastName
{
get { return _LastName; }
set { _LastName = value; }
}
public Car PersonCar
{
get{return _Car;}
set{_Car=value;}
}
}
public class Car
{
public Car()
{ }
private string _Make = "";
public string Make
{
get { return _Make; }
set { _Make = value;
}
}
I will now create two instances of this class. One where I create the Person object from scratch and another where I assign the new person to be the same as Person One.
Person personOne = new Person();
personOne.FirstName="Peter";
personOne.LastName = "Cane";
Person personTwo = new Person();
personTwo = personOne ;
If this code is executed, the values of the two person objects will be the same. But when you change the FirstName of person two, the the FirstName of person one will also change. When you use the equals (=) sign to assign an object to another object, you only copy the reference to the actual values. If you change any propery of any of the person object, the value will change for person one and person two. Thus a change made in one instance will also affect the other instance directly because they are the same instance with different names.
To copy the actual values of the object and create a new object, you need to implement the ICloneble interface. To implement this interface add the following to your class declaration.
class Program :ICloneable
When you implement this interface, the following method is added to your class. You need to implement the method so that is does the cloning for you.
public object Clone()
{
throw new Exception("The method or operation is not implemented.");
}
Types of cloning
There are two types of cloning. Shallow copy and a deep copy of the object. Shallow copy will clone the objects value types,but will only copy the references of any reference types in the object. For example, let’s say you clone the Person object created above using shallow copy. The person will be cloned, but the car object will not be cloned. In other words the new Person will still use the other guy’s car. To clone the object so that both have their own car, you have to use deep copy. A car will be cloned for the new guy as well.
• Shallow Copy : use the MemberwiseClone function. This will copy the value types, but only copy the references to the reference types
public object Clone()
{
this.MemberwiseClone();
}
• Deep Copy : To implement a deep copy, you will need to serialize the object and then deserialize the object as follows.
public object Clone()
{
MemoryStream mm = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(mm, this);
mm.Seek(0, SeekOrigin.Begin);
object o;
o = bf.Deserialize(mm);
return o;
}
In this instance I would say cloning is the optimum solution, as for cloning sheep….I don't agree.
Dewald Fortier.
Let's say you have the following classes
public class Person
{
public Person()
{ }
private string _FirstName = "";
private string _LastName = "";
private Car _Car = new Car();
public string FirstName
{
get { return _FirstName; }
set { _FirstName = value; }
}
public string LastName
{
get { return _LastName; }
set { _LastName = value; }
}
public Car PersonCar
{
get{return _Car;}
set{_Car=value;}
}
}
public class Car
{
public Car()
{ }
private string _Make = "";
public string Make
{
get { return _Make; }
set { _Make = value;
}
}
I will now create two instances of this class. One where I create the Person object from scratch and another where I assign the new person to be the same as Person One.
Person personOne = new Person();
personOne.FirstName="Peter";
personOne.LastName = "Cane";
Person personTwo = new Person();
personTwo = personOne ;
If this code is executed, the values of the two person objects will be the same. But when you change the FirstName of person two, the the FirstName of person one will also change. When you use the equals (=) sign to assign an object to another object, you only copy the reference to the actual values. If you change any propery of any of the person object, the value will change for person one and person two. Thus a change made in one instance will also affect the other instance directly because they are the same instance with different names.
To copy the actual values of the object and create a new object, you need to implement the ICloneble interface. To implement this interface add the following to your class declaration.
class Program :ICloneable
When you implement this interface, the following method is added to your class. You need to implement the method so that is does the cloning for you.
public object Clone()
{
throw new Exception("The method or operation is not implemented.");
}
Types of cloning
There are two types of cloning. Shallow copy and a deep copy of the object. Shallow copy will clone the objects value types,but will only copy the references of any reference types in the object. For example, let’s say you clone the Person object created above using shallow copy. The person will be cloned, but the car object will not be cloned. In other words the new Person will still use the other guy’s car. To clone the object so that both have their own car, you have to use deep copy. A car will be cloned for the new guy as well.
• Shallow Copy : use the MemberwiseClone function. This will copy the value types, but only copy the references to the reference types
public object Clone()
{
this.MemberwiseClone();
}
• Deep Copy : To implement a deep copy, you will need to serialize the object and then deserialize the object as follows.
public object Clone()
{
MemoryStream mm = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(mm, this);
mm.Seek(0, SeekOrigin.Begin);
object o;
o = bf.Deserialize(mm);
return o;
}
In this instance I would say cloning is the optimum solution, as for cloning sheep….I don't agree.
Dewald Fortier.
Subscribe to:
Posts (Atom)