Showing posts with label Tips n Trick. Show all posts
Showing posts with label Tips n Trick. Show all posts

Designing Systems, the Art and Pitfalls

This article mainly based from this stackoverflow question about designing system. As I have written before about learning by teaching, this is a good example that I see. Even though I had experience designing a system, but I still cannot define exact steps needed to design it. Now I have learned much and able to provide the explicit steps of designing a system, at least from my experience.

The High Level and Low Level Module

In the context of system (application) design, a high level module is an overview picture about how the system interacts with the user, and other integrated system. Since low level module is a detailed picture about how the system interacts between each other subsystems inside. That's it, a system design are divided between two modules.

High Level Module

We need to divide the design to separated modules, because it is hard to design a system without high level (overview of the system) module. High level module are more understandable by the business users. Moreover, there are many pitfalls beside system errors, such as wrong use case scenario and wrong business rule validations. Defining those pitfalls in high level module design is easier and faster. Who does not loves simplicity, faster, and easier job? That's why we should do high level module design.

Taken from my stackoverflow answer, about a standard point-of-sales system that has the following sub-modules:

  • ordering
  • commiting order
  • down payment
  • goods delivery
  • return

Here is the steps of defining high level module design:

  1. Define the standard use case between user and systems
  2. Pour the use cases to some collaborated diagram such as rich picture (or anything familiar)
  3. Define the exceptions use cases. If the exceptions can be defined easily, put it immediately to model. If not, mark the model with the case exceptions to be further discussed with business teams. Some use case exceptions can be changing committed order, changing committed order after down payment, cancelling payed order, goods out of stock, etc.
  4. Iterate the process. Usually step 3 can become step 1 (the exception can / will be another use case). For example the changing committed order can be a use case, since the change of occurring is high.
  5. When the 3rd is completed without additional use case exceptions (all use case has been handled), usually I add value-additional operations.
    Those operations can be notification (email / on-screen), historical data maintenance, reminder, error-handling, etc. Some operations can be another use case as well, so maybe you will need to iterate over to no.1.
    Some example maybe when you get error during down payment settlement, maybe you will need another use case to input the down payment data manually. Or maybe you will need to maintain reminder system in another system.
  6. Move to low level model
Well, each point can be separated as another discussion.

Low Level Module

Low level module design, on the other hand gives more detailed view in the systems and it shows how each of the subsystems work between each other. Many times, low level modules are overlooked by the management because it is far very faster to immediately begin to code than creating the low level module. Then what is the benefit of low level module design?

These are the benefits of low level module design that is often overlooked:

  1. It can act as a documentation
    Class diagram, database design, state diagram, flowchart, sequence. Everything can be taken as a technical documentation or "blueprint" of the system. Is it needed? Yes in most cases, usually in first step of debugging
  2. It catches pitfalls, errors and exceptions early
    Most of the time error and exceptions are being caught during integration testing. When during testing and find some of the error, you will review the general process of the system. At that time, it is too late because your code already been constructed with your database structures
  3. It design your code base clean
    Little hacks and tweaks are sometimes (most of the times) done to fix something during the testing time (see point 2). Having a low level module, you are forced to define some general structure of your code base, and pitfalls can be avoided early, making your code cleaner and less need to refactor
  4. It can be reviewed easily
    Discussing designs with peers using low level module design will be easier and faster, compared to reviewing code
  5. It can be used as basis of review and evaluation
    After the code has been completed, you can review the mechanism and structure with low level module design. This will help to find pitfalls or unfinished works earlier (before integrated tests)
Well, there are many benefits but often overlooked by management, because usually they only make schedules with waterfall model. That is, having the development going forward (from design, code, testing, publishing) without handling for exceptions in between (bug fix during testing, redesign during code, etc). And the benefit of low level module in a simple CRUD application seems overkill (even though nice to have) for most management, that in their consideration: "it is okay to have a buggy code published rather than having 40 hours of designing low level module.

Then how do you design low level module? Well, the answer lies in many books, such as UML guidance for OOP, etc.

Learning by Teaching

Docendo discimus or Learning by Teaching, is one of good method to improve yourself (or at least, myself).

Learning by teaching gives you better experience, knowledge and skills, and can be very useful, compared to learning by yourself or from other. It is because in order to teach someone, you will need to know the answer from the problem beforehand, or at least has an expertise in the case. Also, teaching requires you to be able to explain the method correctly and presenting the knowledge. In other words, converting Tacit Knowledge to Explicit Knowledge. Not other than that, you must proof your knowledge and defend it from any disagreements.

Has an Expertise in the Case

You cannot teach or giving knowledge if you do not has an expertise in the case. Some exceptions may be for seniority or positional power, but it is another topic. It means that if you already can teach, you already has some level of expertise in the case. It is a good indicator to measure yourself.

If you need to teach, answering question or giving knowledge, it means that you need to know the field and becoming an expert at that field too. It forces you to learn. Even when teaching or after that (evaluation) you can still learning from your teaching. It is a very good improvement.

Able to Explain

Sherlock Holmes said once in his book Study in Scarlet, It was easier to know it than to explain why I know it. If you were asked to prove that two and two made four, you might find some difficulty, and yet you are quite sure of the fact. It is not an easy thing to explain something that you know and most of the time, it is easier for you to understand it yourself.

That is one of good reason why learning by explaining is better than learning by yourself. If you already can teach or explaining the knowledge, it means that you already have the knowledge in a good level. If you do not know the knowledge itself, how can you explain it?

Defend from any Disagreement

Disagreement may comes from other source. The worst type of disagreement by comes from those who has better expertise in the fields (someone that has been respected as masters, such as Martin Fowler for OOP design). In order to prove that your knowledge is correct (or at least acceptable), you must have some ability to protect it from any disagreements. (well in this case, I don't want to mention the worst type of agreement in an organization, that is disagreement from people who has the power, and the disagreement comes from their taste themselves)

Some published books are good to be referenced as sources. Because if you cannot explain the knowledge well, or cannot defend it, you can use the reference as your shield. Published book is good because it is well written, mostly easy to understand and accepted by most people. Moreover, it is written by experts in the fields, improving the correctness (as described in the first point here). The authors itself, is already at a level that is able to defend their statements from disagreements.

Don't worry if you find that your statements cannot be protected. It means that you still need to learn. Moreover, you can learn from the disagreement as the starting point, and begin research from it. At the moment you know the facts that can be used to defend it, you begin to make statements again, and the process iterated itself. It only means that whether your statement can be protected or not, it has learning process in it, and it is good.

Conclusion

Learning by teaching is a good thing to do to improve yourself. Most of the time, you need to do some other types of learning before teaching, so it only leads to some process of learning.

C# Public Property vs Public Attribute

Well, setelah cukup lama bermain dengan C#, ada beberapa hal yang terkesan 'lucu' dalam pembelajaran. Hal tersebut adalah property vs attribute.
Dalam mendeklarasi class di C#, ada beberapa cara untuk merepresentasikan attribut, di antaranya adalah:
  • Public attribute, yaitu dengan mendeklarasi attribute dengan access modifier public, sehingga mudah dapat digunakan oleh class lain
  • Property, yaitu mendeklarasi public attribute dengan accessor get; dan/atau set;
  • Function getter setter, cara ini digunakan umum oleh java
Sekilas, public attribute dan property tidak banyak berbeda, terkecuali get/set accessor yang dapat di-inject oleh potongan syntax. Namun ternyata setelah banyak menggunakan dua hal ini, ada perbedaan yang cukup jelas, yaitu public attribute tidak akan tampil untuk data yang di-binding, baik itu WPF binding, winform binding ataupun Asp.Net binding. Karenanya, biasakan untuk menggunakan property dan bukan public attribute.

Try / Catch, The Double-edged Sword

Try/catch, untuk mayoritas programmer (terutama java) pasti tidak asing lagi dengan syntax tersebut. Syntax tersebut memiliki kemampuan yang hebat dan sangat membantu dalam melakukan pengembangan.

Namun, penggunaan try/catch yang tidak hati-hati dan sembarangan dapat membuat celah dalam sistem. Salah satu celah yang paling umum adalah tidak adanya error message (isi catch kosong). Celah tersebut membuat debugging menjadi susah karena exception tidak menghasilkan error box.

Jadi, apa saja yang harus diperhatikan dalam penggunaan try/catch? Berikut adalah beberapa hal yang sepengalaman saya harus diperhatikan:

1. Penanganan Exception dalam catch.
Object Exception memiliki property Message yang membawa pesan error yang terjadi. Salah satu penanganan exception yang paling mudah adalah menggunakan MessageBox (desktop app) atau Response.Write (asp). Penanganan lebih 'advanced' dapat berupa refresh data, kalkulasi autonomous, dan lainnya sesuai dengan tujuan.

2. Object Exception memiliki turunan
Object Exception memiliki turunan sesuai dengan error yang ada. Misalnya seperti FormatException pada .Net yang dihasilkan dari penggunaan format yang berbeda (misalnya ada karakter ketika parsing ke int, umumnya terjadi ketika parse). Ada juga NullReferenceException dimana program berusaha mendapatkan dan memproses variable yang bernilai null. Penanganan yang berbeda untuk tiap-tiap jenis Exception yang berbeda dapat membantu mempercepat development.

3. Pastikan tidak ada proses bersangkutan yang berjalan setelah ada Exception. Ingat, proses tetap berjalan setelah try/catch.
Misalkan anda memiliki int angka yang didapat dari parsing tbox1.Text. Anda men-'trap' proses parsing tersebut ke dalam try/catch. Kemudian angka tersebut akan digunakan untuk memasukkan data ke dalam database. Proses input data tersebut akan tetap berjalan walaupun ada Exception tanpa penanganan.

Proses yang salah:

int angka=0;
try{
  angka = int.Parse(tbox1.Text);
}
catch(Exception e){
  //show message here
}
//insert process, nilai angka adalah 0


Salah satu cara untuk menghindarinya:

int angka=0;
try{
  angka = int.Parse(tbox1.Text);
  //insert process
}
catch(Exception e){
  //show message here
}