May 30, 2011 Design Patterns 4 comments
May 30, 2011 Design Patterns 4 comments
// Abstract expression public abstract class Goods { public abstract int Interpret(CurrentPricesContext context); } // Nonterminal expression public class GoodsPackage : Goods { public List<Goods> GoodsInside { get; set; } public override int Interpret(CurrentPricesContext context) { var totalSum = 0; foreach (var goods in GoodsInside) { totalSum += goods.Interpret(context); } return totalSum; } } // Terminal expression internal class TV : Goods { public override int Interpret(CurrentPricesContext context) { int price = context.GetPrice("TV"); Console.WriteLine("TV: {0}", price); return price; } } // Here other terminal expressions go (Laptop, Bed)
public void RunInterpreterDemo() { // create syntax tree that represents sentence var truckWithGoods = PrepareTruckWithGoods(); // get latest context var pricesContext = GetRecentPricesContext(); // invoke Interpret var totalPriceForGoods = truckWithGoods.Interpret(pricesContext); Console.WriteLine("Total: {0}", totalPriceForGoods); } private CurrentPricesContext GetRecentPricesContext() { var pricesContext = new CurrentPricesContext(); pricesContext.SetPrice("Bed", 400); pricesContext.SetPrice("TV", 100); pricesContext.SetPrice("Laptop", 500); return pricesContext; } public GoodsPackage PrepareTruckWithGoods() { var truck = new GoodsPackage() { GoodsInside = new List<Goods>() }; var bed = new Bed(); var doubleTriplePackedBed = new GoodsPackage() { GoodsInside = new List<Goods>() { new GoodsPackage() { GoodsInside = new List<Goods>() { bed } } } }; truck.GoodsInside.Add(doubleTriplePackedBed); truck.GoodsInside.Add(new TV()); truck.GoodsInside.Add(new TV()); truck.GoodsInside.Add(new GoodsPackage() { GoodsInside = new List<Goods>() { new Laptop(), new Laptop(), new Laptop() } }); return truck; }
Quickly output:
Bed: 400
TV: 100
TV: 100
Laptop: 500
Laptop: 500
Laptop: 500
Total: 2100
Interpreter is one of the design patterns that you most likely will never use in your life. It is bit cumbersome and has very specific application.
May 14, 2011 Errors, WCF No comments
Hey, I believe that everyone of us have ever dealt with versioning. Versioning inside of WCF doesn’t exist if so to say, but it is very easy to keep all your stuff running until you actually have to validate schema of the messages.
In recent time me with my team had to make our Phone client of version 1.0 and 1.1 work with either version of server 1.0 or 1.1. In other words we had 4 cases. Two of them are obviously non-problematic and two are not that clear. Accordingly to MSDN there is no direct support for versioning in WCF, except of that each data elements are optional by default. This means that if you haven’t specified opposite all of your DataMembers are going to be null if they are missed in incoming XML.
So having this in mind I expected that all of our versioning scenarios will go smoothly, but this did not happen. We were getting ugly exception looking like this: “The resource MultipleIdDefinition was not found”. Honestly it was very surprisingly since google search did not give me any good answer for this.
So here are steps that I took to figure out where the problem is:
Added properties could not brake serialization, so I found other differences, which were additional z:Id=”i7” right after one of the data contracts. Some of you might know that this is cause of IsReference=true of the DataContract. So I did research if this really has been changed between version 1.0 and 1.1 and found out that it was.
So, long story short, if you having some issues with serialization inside of WCF when dealing with versioning think less about new or even deleted elements of you contract, but think more what can cause mismatch in messages. And dong forget to see source control logs.
May 8, 2011 Design Patterns No comments
Do you imagine yourself defusing bomb? Scary? Even if you couldn’t imagine this there is such profession as bomb defuser and people owning it are human as well, so I bet they feel scary when near bomb. For our luck there is technology nowadays that allows remotely operate with some kind of robot that can defuse bomb. Using robots also allows to do more complex operations with safely lifting bombs, and manipulating them. I bet human hands would shake while holding bomb, not robot’s.
Connection with robot is wireless of course and you would have special suit that makes you body operate robot remotely as you were it. (Ok on the picture above you see not such advance robot, but lets imagine we are in future.) Robot still has control panel on it that will allow operating it directly. This is needed just in case connection could not be made (say someone is blocking signal).
To summarize, robot is heavy instance and it can be operated directly or you can proxy your requests through special suit.
Proxy is design pattern that surrogates real object and proxies requests to it when needed, it also instantiates real object if it is not yet instantiated.
Talking about example above, object which we use is robot (RobotBombDefuser) it is heavy stuff, which we move using remote controls aka. proxy suit (RobotBombDefuserProxy). As this suit works wirelessly with robot it knows how to connect to real object and how to pass your requests to it. The same is happening when we connect to some remote web server and call methods on it.
Proxy is also often used when you need lazy initialization. In this case instead of connecting to remote resource there is simple check if object is not null and then assigning an instance if needed.
Let’s see what we have in our example. Here is robot itself.
public class RobotBombDefuser { private Random _random = new Random(); private int _robotConfiguredWavelength = 41; private bool _isConnected = false; public void ConnectWireless(int communicationWaveLength) { if(communicationWaveLength == _robotConfiguredWavelength) { _isConnected = IsConnectedImmitatingConnectivitiyIssues(); } } public bool IsConnected() { _isConnected = IsConnectedImmitatingConnectivitiyIssues(); return _isConnected; } private bool IsConnectedImmitatingConnectivitiyIssues() { return _random.Next(0, 10) < 4; // immitates 40% good connection, aka. very bad } public virtual void WalkStraightForward(int steps) { Console.WriteLine("Did {0} steps forward...", steps); } public virtual void TurnRight() { Console.WriteLine("Turned right..."); } public virtual void TurnLeft() { Console.WriteLine("Turned left..."); } public virtual void DefuseBomb() { Console.WriteLine("Cut red or green or blue wire..."); } }
Main methods that do the stuff are WalkStraightForward, TurnRight, TurnLeft, DefuseBomb. Methods to connect wirelessly and IsConnected are just for imitating reality of this app. You could omit how it works internally.
Here we have Proxy implementation. It always has reference to real object and often implements same interface if is not derived from object’s class.
public class RobotBombDefuserProxy : RobotBombDefuser { private RobotBombDefuser _robotBombDefuser; private int _communicationWaveLength; private int _connectionAttempts = 3; public RobotBombDefuserProxy(int communicationWaveLength) { _robotBombDefuser = new RobotBombDefuser(); _communicationWaveLength = communicationWaveLength; } public virtual void WalkStraightForward(int steps) { EnsureConnectedWithRobot(); _robotBombDefuser.WalkStraightForward(steps); } public virtual void TurnRight() { EnsureConnectedWithRobot(); _robotBombDefuser.TurnRight(); } public virtual void TurnLeft() { EnsureConnectedWithRobot(); _robotBombDefuser.TurnLeft(); } public virtual void DefuseBomb() { EnsureConnectedWithRobot(); _robotBombDefuser.DefuseBomb(); } private void EnsureConnectedWithRobot() { if (_robotBombDefuser == null) { _robotBombDefuser = new RobotBombDefuser(); _robotBombDefuser.ConnectWireless(_communicationWaveLength); } for (int i = 0; i < _connectionAttempts; i++) { if (_robotBombDefuser.IsConnected() != true) { _robotBombDefuser.ConnectWireless(_communicationWaveLength); } else { break; } } if(_robotBombDefuser.IsConnected() != true) { throw new BadConnectionException("No connection with remote bomb diffuser robot could be made after few attempts."); } } }
So our proxy simply redirects requests to real object and before doing so it always ensures that connection is established, and if it is not it establishes it with three attempts and if it couldn’t it then throws an exception.
So let’s see usage:
public static void Run() { int opNum = 0; try { var proxy = new RobotBombDefuserProxy(41); proxy.WalkStraightForward(100); opNum++; proxy.TurnRight(); opNum++; proxy.WalkStraightForward(5); opNum++; proxy.DefuseBomb(); opNum++; Console.WriteLine(); } catch (BadConnectionException e) { Console.WriteLine("Exception has been caught with message: ({0}). Decided to have human operate robot there.", e.Message); PlanB(opNum); } } private static void PlanB(int nextOperationNum) { RobotBombDefuser humanOperatingRobotDirectly = new RobotBombDefuser(); if(nextOperationNum == 0) { humanOperatingRobotDirectly.WalkStraightForward(100); nextOperationNum++; } if (nextOperationNum == 1) { humanOperatingRobotDirectly.TurnRight(); nextOperationNum++; } if (nextOperationNum == 2) { humanOperatingRobotDirectly.WalkStraightForward(5); nextOperationNum++; } if (nextOperationNum == 3) { humanOperatingRobotDirectly.DefuseBomb(); } } }
In sample code above you can see usage of the defuser proxy, there is also “plan B”, when direct instance of the defuser is created and used. Code might look bit complex, because of that opNum and nextOperationNum noise. I added it to ensure robot continues it work from where it stopped.
Output:
Did 100 steps forward…
Turned right…
Exception has been caught with message: (No connection with remote bomb diffuser robot could be made after few attempts.). Decided to have human operate robot there.
Did 5 steps forward…
Cut red or green or blue wire…
My implementation of this Design Pattern is slightly different from its original implementation in GoF book where you have two derived classes both from some interface or superclass. But I think in real world implementation with deriving from already existing class is more common. For example such proxy is used always you need to have virtual methods for some framework, say mocking framework or ORM framework.
Here is UML for my example:
February 28, 2011 HowTo No comments
In one of my previous posts I wrote that we use Distributed Transactions in our code. This worked just fine till we tested all installed on one machine. But once we installed SQL server on machine1 and our services on machine2 and services that use our services on machine3 we got following error messages:
“Inner exception message: Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.”
This means that your transaction is distributed but not as much as you wish it to be. So it is not enabled for Network access. You would need to go to Administrative Tools –> Component Services to enable it.
Here is everything explained up and down how you Enable Network DTC Access:
http://msdn.microsoft.com/en-us/library/cc753510%28v=ws.10%29.aspx
Also, please keep in mind that you would need to enable it on both machines between which you are distributing your transaction.
February 26, 2011 Design Patterns No comments
// Colleague class BodyPart { private readonly Brain _brain; public BodyPart(Brain brain) { _brain = brain; } public void Changed() { _brain.SomethingHappenedToBodyPart(this); } }
class Ear : BodyPart { private string _sounds = string.Empty; public Ear(Brain brain) : base(brain) { } public void HearSomething() { Console.WriteLine("Enter what you hear:"); _sounds = Console.ReadLine(); Changed(); } public string GetSounds() { return _sounds; } }
So it basically can HearSomething and can provide its status by GetSounds method. Some other body parts can have some reactions, as simple Face implementation below:
class Face : BodyPart { public Face(Brain brain) : base(brain) { } public void Smile() { Console.WriteLine("FACE: Smiling..."); } }
// Mediator class Brain { public Brain() { CreateBodyParts(); } private void CreateBodyParts() { Ear = new Ear(this); Eye = new Eye(this); Face = new Face(this); Hand = new Hand(this); Leg = new Leg(this); } public Ear Ear { get; private set; } public Eye Eye { get; private set; } public Face Face { get; private set; } public Hand Hand { get; private set; } public Leg Leg { get; private set; } public void SomethingHappenedToBodyPart(BodyPart bodyPart) { if (bodyPart is Ear) { string heardSounds = ((Ear)bodyPart).GetSounds(); if (heardSounds.Contains("stupid")) { // attacking offender Leg.StepForward(); Hand.HitPersonNearYou(); Leg.Kick(); } else if (heardSounds.Contains("cool")) { Face.Smile(); } } else if (bodyPart is Eye) { // brain can analyze what you see and // can react appropriately using different body parts } else if (bodyPart is Hand) { var hand = (Hand)bodyPart; bool hurtingFeeling = hand.DoesItHurt(); if (hurtingFeeling) { Leg.StepBack(); } bool itIsNice = hand.IsItNice(); if (itIsNice) { Leg.StepForward(); Hand.Embrace(); } } else if (bodyPart is Leg) { // leg can also feel something if you would like it to } } }
Personally I liked example that I’ve prepared. Hope there is no such example over internet, but who knows.
In addition here below is some UML stuff. You can click on image to see it bigger.
February 18, 2011 Certification, Success 3 comments
So far so good, I passed everything I planned to pass for the next 1.5 years. Take a look at the picture in career plan for software engineer blog post. I guess that I probably was afraid about learning ASP.NET. And as I passed everything sooner I can plan for more cool stuff, for instance starting my own small project or spend more time on personal life.
But here is just a little bit more on exam itself. I was ready for this exam not because of some books, training kits or anything else. It is all my experience. I extremely enjoyed passing this exam, you just apply your experience and common sense if you have it in software development of enterprise applications. Exam measures my understanding of designing application, its components, their testing, stabilizing, deployment, also choosing appropriate technologies. That is what I encounter often at work.
This is good plus to my CV and promotion strategy.
Exam 70-565: PRO: Designing and Developing Enterprise Applications Using the Microsoft .NET Framework 3.5
I passed 70-565 exam with score 971 out of 1000. And this time exam questions just flattered to me. I liked them much. I believe that this is because they are not kind of questions where you have to know exact method signature. These are questions where you have to think and choose appropriate decision, and even more, they overlap a lot with questions I encountered in my experience.
You can see my transcript using this information:
https://mcp.microsoft.com/authenticate/validatemcp.aspx
Transcript ID: 904316
Access Code: andriybuday
Nearest certification plans
There is still one thing left. It is 4.0 .NET framework outside, not 3.5 so I’m looking for upgrade of the current certification. The best matching exam would be transition of my skills to MCPD 4.0 Windows Developer (70-521). At the moment I don’t have exact date for this exam, but it might be in 2-4 weeks.
February 11, 2011 Blog 2 comments
Here below are results of the poll that have been on my blog:
Obviously people want me to write more on software design and patterns and no one wants to see “Hello World” applications. I’ve been thinking about this poll that it might be that I misses something related to frameworks and new technologies/languages. I’m afraid that those are valuable options as per me.
Anyway, that isn’t so much bad, 24 people have voted and I appreciate all of the votes. I will try to be stick to it, but cannot promise that I will have everything in proportion. Actually I’m planning to have 24 book reviews this year. This means 48 posts on design patterns and software design. Hm.. not that many.
Thank you very much.
February 10, 2011 Silverlight 4 comments
Here is binding (I did not change it):
<UserControls:NumericTextBox AllowDecimals=”True”
Minimum=”0″ UseMinimum=”True”
Maximum=”999.999″ UseMaximum=”True”
MaxLength=”6″
Value=”{Binding Mileage, Mode=TwoWay}”
private double? _mileage; public double? Mileage { get { return _mileage; } set { _mileage = value; EnteredMileage = value; RaisePropertyChanged("Mileage"); } }
_mileage = EnteredMileage.HasValue ? EnteredMileage : CalculatedMileage; RaisePropertyChanged("Mileage");
February 10, 2011 Book Reviews, Certification, Success No comments
Training Kit
Exam 70-561: TS: Microsoft .NET Framework 3.5, ADO.NET Application Development
You can see my transcript using this information:
https://mcp.microsoft.com/authenticate/validatemcp.aspx
Transcript ID: 904316
Access Code: andriybuday
Nearest certification plans
January 31, 2011 NHibernate No comments
Most of our current NHibernate saving methods look like below:
public void SaveCustomer(CustomerEntity customer) { var transaction = GetActiveTransaction(); transaction.Begin(); try { // some code Session.SaveOrUpdate(customer); transaction.Commit(); } catch (Exception e) { transaction.Rollback(); throw e; } }
this works great if you need to save just Customer or just Vendor. But in recent time we got kindof challenge to save Customer and Vendor at once in scope of one transaction for piece of functionality, and at the same time method should work for another piece of functionality.
For this we change our methods as following:
public void SaveVendor(VendorEntity vendor) { using (var scope = new TransactionScope(TransactionScopeOption.Required)) // if there is no transaction scope, new will be created... { using (var transaction = Session.BeginTransaction()) { // some code Session.SaveOrUpdate(vendor); transaction.Commit(); } scope.Complete(); } }
Now we can utilize our methods higher in the call stack:
public void SaveBunchOfInformationAtOnce(CustomerEntity customer, VendorEntity vendor) { try { using(var scope = new TransactionScope(TransactionScopeOption.RequiresNew)) // always new transaction will be created { CustomersRepository.SaveCustomer(customer); VendorsRepository.SaveVendor(vendor); scope.Complete(); } } catch(Exception e) { // log errors... throw; } }
This all works just fine both for existing method calls and for new one. Hope it helps.
Next thing that I might need to put into place is to distribute transactions through WCF services. That should be fun.