At the end of this very interesting class, I have to speculate a little to define what I have learnt and what changed in me.
First, I have realized that I miss something. I just spent my entire life reading just technical books. When I was an Electrical Engineering student, it was all about circuits, electrical measurements, ICs, semi-conductor devices ... etc. When I later joined the Communications and Electronics sub-section in the EE department during the last two years of my Bachelor degree, it was all about analog and digital communications, antennae and microwave signals ... etc. When I started working as a telecom engineer after graduation, it was all about GSM, UMTS, network planning and dimensioning, network optimization ... etc. When I finally decided to change my career to software development, now it's all about programming languages, algorithms, computer systems ... etc. All are TECHNICAL knowledge. It is very clear that I didn't spend enough time investing in increasing my knowledge of management and process issues. This course helped me realize my big mistake.
I never before used to stop and think why something I do either works or doesn't. I guess I've been always doing things subconsciously following my knowledge of past experiences that this particular thing should work, while that on the other hand shouldn't. Even during the time of this class and following the projects and assignments we did, without these blog posts or the assignments questions, I would have never stopped and speculate about it. This is something I MUST change about myself. I will never learn quickly from my experience unless I stop every now and then and mine my mind for thoughts and knowledge about my life and work experience.
That's why writing these thoughts and answering the assignments questions can be sometimes a mind burning process for me. The thoughts are there, but they're buried deeply inside my brain and have to be extracted. That's why it takes me a lot of time to put these thoughts into words, because I don't extract them very often.
This course really helped me a lot in closing many of the gaps that I had. And coming from a different field other than software, getting to know these things early on in my career switch phase is much better than learning them by making mistakes later on.
SE511: Ahmed Fakhry
Wednesday, November 14, 2012
Tuesday, November 6, 2012
Tetris Done!!
I want to talk about two things. I'm currently sick, so I hope I will write something meaningful.
1- Tetris
- My Role: Implementing the CollisionManager
As per the design, the CollisionManager was an intermediate entity between other classes. In order to perform its job, it needed to be supplied by a ShapeObject, and to be able to use methods in the GameBoardManager class.
When I started working on it, the two other classes that I needed weren't written yet, not even stubbed out. But I had to write something. Maybe someone else in another team who will need the CollisionManager methods, needs to see something written. That's exactly what I did, stubbing out my methods, writting some code and then commenting it out so that the project remains buildable, until the other classes that I needed were written.
What really worked well, is that we have agreed earlier on the APIs of all classes, and hence, there was almost nothing needed to change after the other the two classes were written. Earlier good co-ordination really paid off very well here.
- Problems:
Well, to be honest, from the efficiency stand point, a lot of things could have done much better and much faster. But during design phase, we all agreed on using all of the supplied code with out customizing it to suit our needs, and we all took the position of "Let's just get it to work"!
I have to say that this saved us going through a lot of complexity, which worked well and helped get the game working with the minimal amount of effort. Yet I can give examples of things that could have been done better.
In the ShapeObject class, in order to draw a shape, the method goes through all of these switch cases to find out what type of Shape it is, so that it can call the appropriate draw() method that was originally supplied. Again, that's totally NOT the mistake of the programmer who wrote the ShapeObject class, as he himself wasn't pleased about it. It's all due to our ealier decision of "Let's use all of the supplied code, and let's get it to work".
Another example, for my CollisionManager, and in order to detect collision, I needed access to the individual blocks of each shape to test for collision. I thought that those will be stored an encapsulated somewhere, but strangely, they were not. I had to calculate the positions of each of these blocks inside my class by deducing them from the Shape type. Again, this was done by a series of switch cases, ... very unefficient. It shouldn't be the responsibility of the CollisionManager to keep track the positions of each shape's individual blocks.
As a better solution to the above two problems, Why have just one ShapeObject class, why not have a class for each type of shapes. A Z1ShapeObject, a L1ShapeObject, ... and so on. And Each shape object knows how to draw itself (without going through these silly switch cases) and it also keeps track of its blocks positions and encapsulates that very well.
Again, it was all about getting it to work, efficiency wasn't something that we considered at all. In fact even with the presence of these many switch cases, their impact in a very basic game like Tetris is almost not noticable.
2- Smart Sourcing
I didn't read the whole book yet, I just read part one of it. I have to say, it's very boring for me to read such kind of books, specially that I'm a very slow reader. I was planning to get most of it read by Lecture day, but unfortunately I couldn't as I got sick over this last weekend till today, and I couldn't get much done. I even couldn't get much done in my final Space Invaders game which is much more worrying! Hopefully I will get better soon.
Reading the first part though, made me get the general idea that the book is trying to convey. That is, Smart Sourcing is not necessarily about cost reduction, it's more about establishing a partnership through which a company focus on its major core competency (What it is really good at) and let the other non major tasks be handled by those trust worthy partners who really know how to do those things better. This should give more room for innovation and for the company's products and services enhancement.
1- Tetris
- My Role: Implementing the CollisionManager
As per the design, the CollisionManager was an intermediate entity between other classes. In order to perform its job, it needed to be supplied by a ShapeObject, and to be able to use methods in the GameBoardManager class.
When I started working on it, the two other classes that I needed weren't written yet, not even stubbed out. But I had to write something. Maybe someone else in another team who will need the CollisionManager methods, needs to see something written. That's exactly what I did, stubbing out my methods, writting some code and then commenting it out so that the project remains buildable, until the other classes that I needed were written.
What really worked well, is that we have agreed earlier on the APIs of all classes, and hence, there was almost nothing needed to change after the other the two classes were written. Earlier good co-ordination really paid off very well here.
- Problems:
Well, to be honest, from the efficiency stand point, a lot of things could have done much better and much faster. But during design phase, we all agreed on using all of the supplied code with out customizing it to suit our needs, and we all took the position of "Let's just get it to work"!
I have to say that this saved us going through a lot of complexity, which worked well and helped get the game working with the minimal amount of effort. Yet I can give examples of things that could have been done better.
In the ShapeObject class, in order to draw a shape, the method goes through all of these switch cases to find out what type of Shape it is, so that it can call the appropriate draw() method that was originally supplied. Again, that's totally NOT the mistake of the programmer who wrote the ShapeObject class, as he himself wasn't pleased about it. It's all due to our ealier decision of "Let's use all of the supplied code, and let's get it to work".
Another example, for my CollisionManager, and in order to detect collision, I needed access to the individual blocks of each shape to test for collision. I thought that those will be stored an encapsulated somewhere, but strangely, they were not. I had to calculate the positions of each of these blocks inside my class by deducing them from the Shape type. Again, this was done by a series of switch cases, ... very unefficient. It shouldn't be the responsibility of the CollisionManager to keep track the positions of each shape's individual blocks.
As a better solution to the above two problems, Why have just one ShapeObject class, why not have a class for each type of shapes. A Z1ShapeObject, a L1ShapeObject, ... and so on. And Each shape object knows how to draw itself (without going through these silly switch cases) and it also keeps track of its blocks positions and encapsulates that very well.
Again, it was all about getting it to work, efficiency wasn't something that we considered at all. In fact even with the presence of these many switch cases, their impact in a very basic game like Tetris is almost not noticable.
2- Smart Sourcing
I didn't read the whole book yet, I just read part one of it. I have to say, it's very boring for me to read such kind of books, specially that I'm a very slow reader. I was planning to get most of it read by Lecture day, but unfortunately I couldn't as I got sick over this last weekend till today, and I couldn't get much done. I even couldn't get much done in my final Space Invaders game which is much more worrying! Hopefully I will get better soon.
Reading the first part though, made me get the general idea that the book is trying to convey. That is, Smart Sourcing is not necessarily about cost reduction, it's more about establishing a partnership through which a company focus on its major core competency (What it is really good at) and let the other non major tasks be handled by those trust worthy partners who really know how to do those things better. This should give more room for innovation and for the company's products and services enhancement.
Wednesday, October 31, 2012
Partitioning: Design Phase
I think I will sound a little negative
towards partitioning in general. For something that seems simple to
implement in a weekend like Tetris, it's going to take us three weeks
to finish here. Let alone all the problems that will result from the
lack of co-ordination between the different team, and the assumptions
that each team will make about the other teams.
The hardest thing in the design phase
was to figure out how should each piece or component of the program
connect with the other, defining the APIs needed, and making sure
that each component gets exactly what it is expecting.
That was all the talk this week was all
about, and theoretically everything is setup and ready for phase 2,
the implementation! I'm going to sound negative again, but more
problems will show up I think, things that we didn't anticipate in
our design. Hopefully that won't be the case, but wishful thinking
isn't enough. We will need to communicate more during the
implementation phase, and will need to adapt the design quickly to
any needed changes. If it's just going to be that each team
implements its own part and that's it, it's going to end up in a
disaster.
More spices will be added to these
problems if you take this project to a global development level. All
problems will be amplified and magnified. I keep asking myself this
question, with all of the problems and risks associated with global
development, why would we go for it? Overall, it doesn't even seem
cheaper at all.
I started reading in the “Smart
Sourcing” book, which was talking about how necessary it is to
outsource some work to help the company focus only on its major
competencies, the things that it is really good at. But is that
really worth all of this risk? I guess I will find out more as I
continue reading the book.
Tuesday, October 23, 2012
Subordinate Projects : I Got the Point
With part 2 of the project successfully completed, now it's time to reflect for a while. The whole idea of subordinate projects is to save time of both the designer team and the implementation team, by making each team focus only on one thing at a time, and creating parallelism in their tasks.
After this assignment project, I tend to believe that this is not the case at all, and probably in a real world situation it will be even worse. It does NOT save time.
For the designer team, it takes time to:
I have to mention here though, that if both teams, the designers and the implementers, were the same team or at least co-located, this could achieve the desired purpose of having a subordinate project (the efficiency and parallelism). This will make dealing with the above problems much easier and less time-consuming.
After this assignment project, I tend to believe that this is not the case at all, and probably in a real world situation it will be even worse. It does NOT save time.
For the designer team, it takes time to:
- write a good TDD,
- explain it to the implementers,
- make sure they understand everything,
- follow up their progress to make sure they are on track,
- test their code and report their bugs,
- understand the design,
- request changes to the design,
- understand difficult algorithms that the design might be dependent on,
- work on the bugs resulting from your lack of understanding of the design,
- defeat your "ego" or "selfish" feeling that you could have designed it better.
I have to mention here though, that if both teams, the designers and the implementers, were the same team or at least co-located, this could achieve the desired purpose of having a subordinate project (the efficiency and parallelism). This will make dealing with the above problems much easier and less time-consuming.
Wednesday, October 17, 2012
Project 2: Designing for Others to Implement
First of all, I want to mention that I really love data structures. The 'Data Structures And Algorithms' class, which I took in the summer quarter here at DePaul University, changed how I think so much. Now I always analyze any code I write in the back of my mind. Asking myself questions as:
- Is it efficient enough?
- Is this the best way to store the data?
- What are the operations that I will need to do quite often on these data? Maybe I can focus on optimizing those more?
Now back to the 'Search List' data structure that we had to design for this project, so that another team in the class will implement it. Everybody, gave it a bit of thought, and came up with his own idea. I spent a whole night working on it to present my idea to the team during our Skype meeting that we arranged the next day.
My design idea to implement it as a binary search tree was welcomed by the other guys, and they thought it was the best approach. Now it was my responsibility to write the design document for the other team. Everyone thought that I would come up with a single-page document that has some general design decisions that I made. Well, that's not how I think! Whenever I'm assigned a task, I believe I'm 100% responsible for it and I must be fully committed to produce the best output that I can. For me, and that's something I learned from my previous work as a Telecom Engineer, being a team member means lifting your team up on your shoulder if you can. It's not like just do your part and that's it. It's more like do your part and help others do theirs as well. It's exhausting sometimes I have to say, but it's very rewarding when you see your team appreciates you and the team itself is prospering. This is what I came up with:

They were surprised that I wrote a 5-page well-formatted design document, with examples, sample code, diagrams and UML. I felt really happy that they liked it.
I also took the challenge of implementing my design just as a coding exercise. I wrote the whole data structure in Java, and then tested it, and it worked. Well, we're using C# for this class, and I could have definitely written it in C#, but here's why I wrote it in Java:
- While C# and Java are quite similar, I haven't used Java for a while, so I thought this is a good time to practice a bit.
- I love Eclipse, more than Visual Studio.
Back to the love of data structures, I really thank Mr. Keenan for forcing us to write our own whenever we need any. I'm sure we'll reap the rewards of this later on. I think I already started to reap some of these rewards now, by feeling so much comfortable with data structures. I also had to send a thank you e-mail to my data structures class teacher, Mr. Jonathan Gemmell, for being a great teacher. We have this saying in Egypt, "I'd become a servant for whoever teaches me a single letter!" That's why I felt grateful, and had to thank him. Here's what he said when he replied back to my e-mail:
"Thanks, but it's really not hard to teach a student as motivated as you. Good luck in your degree!"I'm really happy that I made the decision a year ago to come to DePaul University. So far, it's been a great place to learn.
Monday, October 8, 2012
Unit Testing: How Come I Never Used You Before?
Unit Testing is absolutely something new to me; I have never done before. But it has such a great power that I keep wondering how come I never used it before. It's true that I'm still relatively new to the software industry so I have my excuse. Honestly, I heard about it before several times, but I never cared to explore more about it since Testing is usually something regarded as something boring and unattractive.
Now that I had to try it for myself, I really realize its power now. I keep imagining myself writing some pieces of code and then writing their unit tests routines and make sure they all pass for all possible combinations of input and output. And then a while later, coming back to that same code to refactor it and probably add new features or implementing a new algorithm and so on. After I'm done, all I have to do is just run those tests that I already wrote long time ago, and make sure they still pass, if not, then I must have introduced some bugs or broke the code some how. This is really great to validate that new features doesn't introduce new bugs with them. Of course, some tests might need to be modified to accommodate some changes in the code. But generally, this is a great way to guarantee correctness of work.
There's this whole other idea of Test Driven Development (TDD), which I believe, well, is good, but it seems that it has the potential to waste time. I'm not sure of that though, since I've never had experience with it. But it's certainly a good way of validating code while being on the process of writing it.
With project 1 almost completed, I have to say it went smoothly without any problem. Everyone committed to the deadline they chose for themselves, although one team member had lagged behind a bit, but the good thing is, he confirmed that he's working on his tests, and is willing to finish them tonight.
What concerns me is that our team members are mostly busy, we don't get to stay in touch a lot. We didn't have to for this project because apparently it was mostly easy for everyone, but how is it going to be in a bigger project. I tend to think that we should take advantage of this opportunity to simulate as much as possible the real thing .. a distributed development environment. Yet again, everyone has different priorities, including me. I just want to be ready for the real thing after graduation. There's room to make mistakes now, but there won't be later. That's the opportunity I want to take.
Now that I had to try it for myself, I really realize its power now. I keep imagining myself writing some pieces of code and then writing their unit tests routines and make sure they all pass for all possible combinations of input and output. And then a while later, coming back to that same code to refactor it and probably add new features or implementing a new algorithm and so on. After I'm done, all I have to do is just run those tests that I already wrote long time ago, and make sure they still pass, if not, then I must have introduced some bugs or broke the code some how. This is really great to validate that new features doesn't introduce new bugs with them. Of course, some tests might need to be modified to accommodate some changes in the code. But generally, this is a great way to guarantee correctness of work.
There's this whole other idea of Test Driven Development (TDD), which I believe, well, is good, but it seems that it has the potential to waste time. I'm not sure of that though, since I've never had experience with it. But it's certainly a good way of validating code while being on the process of writing it.
With project 1 almost completed, I have to say it went smoothly without any problem. Everyone committed to the deadline they chose for themselves, although one team member had lagged behind a bit, but the good thing is, he confirmed that he's working on his tests, and is willing to finish them tonight.
What concerns me is that our team members are mostly busy, we don't get to stay in touch a lot. We didn't have to for this project because apparently it was mostly easy for everyone, but how is it going to be in a bigger project. I tend to think that we should take advantage of this opportunity to simulate as much as possible the real thing .. a distributed development environment. Yet again, everyone has different priorities, including me. I just want to be ready for the real thing after graduation. There's room to make mistakes now, but there won't be later. That's the opportunity I want to take.
Tuesday, October 2, 2012
Project #1: Will It Be A Success?
Now that the first phase of the project is over, which was supposed to layout our team's process and plan, I really feel concerned. We've been trying for a week to setup an appointment to Skype, we eventually managed to at the end. A lot of the decisions we needed to take were postponed until we managed to Skype, so I think we were a bit late.
It's understandable that everyone has different priorities. some team members are taking a lot of other classes, and some of them are actually working for long hours every week. This really simulates the real thing I guess, Since most companies will have different projects with different priorities. That made me wonder, how can we put everybody on the same wavelength? Is it done through strict due dates, or through being pushy to everyone?
The team lead position was not easy to decide as well. Everyone says "I can do it, but if someone else want it I'm fine with that". Everyone (including me!) is afraid to impose himself on others, which is a good thing of course. But still, someone had to step in anyway, and that's what happened in our case, someone just volunteered.
What concerns me is that it took a while to setup the basic things, how is it going to be when we actually start the real work and do the unit testings? I believe that everything is difficult at the beginning, and once the basic processes are laid out, everything else flows naturally afterwards. So hopefully it will be a success!
Subscribe to:
Posts (Atom)