Here is my presentation for the workshop at CodeGym today about Design patterns. One of the biggest issue in training design patterns is the trainees don’t know how to apply them together in a single real world problem. I tried to create a real world problem and introduced a simple way to get it solved by combining some design patterns.

KFC. Order system

KFC is very famous fastfood brand, they have many franchises in various places that share the same hotline, menu.

When users open the menu on KFC website, they see the single menu, choose and order food by calling to the single hotline. A order center (OC) receives the order and notifies to the appropriate store by a specific criteria (now is location and can be changed in the future). A store can answer their possibility to take this order (they need to cook and deliver it on time). If a store takes this order, the process ends; otherwise, the OC will find another one.

To process a order, a store has a recipient who receives the order from OC, forwards it to the kitchen, finds the right delivery man and updates the order basing on the information from delivery man such as payment, status (accepted or declined), customer feedback… to OC. So OC has real time data of every orders but doesn’t have order’s internal note that works within the store.

When OC gets the order information from customer, they may get the extra information in some categories like food change, delivery time, special notes… If customer calls to OC to cancel the order, OC can directly cancel it by updating the order status in taken store.

Design the system by design patterns.

446 total views, no views today

I will have a workshop at CodeGym at the end of this month about Design patterns. One of the biggest issue in training design patterns is the trainees don’t know how to apply them together in a single real world problem. Here is my example that will be used as the exercise for this workshop. Is it interesting enough? Try it out.

KFC. Order system

KFC is very famous fastfood brand, they have many franchises in various places that share the same hotline, menu.

When users open the menu on KFC website, they see the single menu, choose and order food by calling to the single hotline. A order center (OC) receives the order and notifies to the appropriate store by a specific criteria (now is location and can be changed in the future). A store can answer their possibility to take this order (they need to cook and deliver it on time). If a store takes this order, the process ends; otherwise, the OC will find another one.

To process a order, a store has a recipient who receives the order from OC, forwards it to the kitchen, finds the right delivery man and updates the order basing on the information from delivery man such as payment, status (accepted or declined), customer feedback… to OC. So OC has real time data of every orders but doesn’t have order’s internal note that works within the store.

When OC gets the order information from customer, they may get the extra information in some categories like food change, delivery time, special notes… If customer calls to OC to cancel the order, OC can directly cancel it by updating the order status in taken store.

Design the system by design patterns.

—————————————————————-

The solution will be updated later.

437 total views, 1 views today

Hôm nay đồng nghiệp hỏi câu này: Tại sao nên viết như #a thay vì #b?

Tôi mở rộng câu hỏi thành: Sắp xếp các cách viết sau theo thứ tự “tốt dần”.

Khá khó để nói #3 và #4, cách nào tốt hơn; nhưng có thể dễ dàng khẳng định #1 và #2 không tốt bằng #3, #4. Tại sao?

Nguyên tắc chung của lập trình hướng đối tượng là trừu tượng hoá và cố gắng tối đa việc trừu tượng hoá. Trừu tượng (không phải là giải pháp toàn vẹn nhưng) là một phần trong cách tư duy về Open / Closed principle. #1 rất trực quan và dễ hiểu: tạo một danh sách lưu trữ sách dưới dạng ArrayList. Nhưng những thứ cụ thể rất khó để sửa đổi và thay thế. Ví dụ, sau khi implement, chúng ta phát hiện ra đoạn code phía sau sử dụng rất nhiều thao tác thêm phần tử vào list thay vì lấy phần tử ra; do đó lưu trữ dưới dạng Stack cho hiệu suất tốt hơn; chúng ta phải sửa đổi các đoạn code phía dưới với implement cụ thể của Stack (thay cho ArrayList). Một thời gian sau, nhu cầu lấy phần tử từ list đủ nhiều để sử dụng ArrayList cho hiệu suất tốt hơn, chúng ta phải sửa lại đoạn code phía dưới với implement cụ thể của ArrayList. (Tham khảo: hiệu suất các implement của List). Khổ chưa?

Một cách thông minh hơn là sử dụng #3, khi đó, đoạn code phía dưới chỉ sử dụng những method được định nghĩa cho interface List. Khi cần thay đổi implement cụ thể thành Stack, LinkedList…, chúng ta chỉ đơn giản thay new List<Book>() bởi new Stack<Book>() hay new LinkedList<Book>(). 

Và theo cách tư duy đó, #4 tốt hơn #3? Không hẳn, nếu chúng ta đã xác định list chỉ chứa Book, việc khai báo list chứa Object khiến chúng ta có thể mất công cast những object này trong trường hợp sử dụng những method cụ thể của Book (và thường là vậy). Nên dùng #4 thường là bất lợi hơn #3 (trừ trường hợp list chữa những object khác ngoài Book).

Do đó, sử dụng #3 (khai báo interface và khởi tạo bằng class (đương nhiên)) thường là cách viết nên được “quen tay”.

Thật ra #3 còn nên viết theo 1 cách khác tốt hơn như sau. Tại sao nhỉ?

531 total views, no views today

Don’t wanna get your wife angry just because of let her wait so long for a dinner? This program is for you. It’s a guide to build the simple application that automatically sends SMS to your wife at a specific time if you need to stay longer at the office.

Get Twilio account

Register an account at: https://www.twilio.com, the service lets you send the SMS via REST API. During trial period, you could get 10$ – enough free messages; then you get charged with low fare later (~0.01 – 0.05$ for each SMS).

Setup Twilio

  1. Buy a number at: https://www.twilio.com/console/phone-numbers/incoming. It costs 1$, Twilio uses this number to send SMS. Call it SENDER.
  2. Verify your wife’s phone number (with country code like +84 988 999 888) at: https://www.twilio.com/console/phone-numbers/verified (to make sure you don’t spam anyone). Call it RECEIVER.
  3. Create API key at: https://www.twilio.com/console/dev-tools/api-keys. You can get API key and secret key here. Call them KSID and KSECRET.
  4. Go to https://www.twilio.com/console and get your account SID. Call it ASID. 

Now replace this command with your information above, replace + in the phone number with %2B.

Then run.

Got it? We are almost done.

Setup a cronjob

You can send SMS to your wife by only 1 command; now get it automated.

1. Create a file sweet_sms_to_darling.sh, put the command above.

2. Get it executable, and run at 18:30 every day.

Add this line, correct your file path, 18, 30 is the hour and minute triggers this bash script.

3. Save this file and add to cronjob. That’s all.

OK, now when your computer is up on 18:30, it automatically send the SMS to your wife.

Don’t worry about she get angry. Now work. 

Please don’t put this job on server – it’s always up 😉

It’s general idea of building the application, you could do it in others platform like Windows with BAT file and scheduled task. Another simpler and specific version for Mac is coming soon 😉

687 total views, 1 views today

Code refactoring là hoạt động chỉnh sửa khiến source code dễ đọc hơn, được tổ chức khoa học hơn, và (có thể) có kiến trúc / cấu trúc tốt hơn nhưng không làm thay đổi hành vi của hệ thống về mặt chức năng.

Việc này giống như chúng ta sắp đặt lại hệ thống điện trong nhà theo một cách khoa học hơn nhưng vẫn đảm giữ nguyên vị trí và chức năng của những công tắc, ổ cắm trên tường. Tôi muốn lấy ví dụ này để bạn hiểu rằng, những gì nhóm phát triển làm với code refactoring hoàn toàn “nằm trong bức tường”, nơi mà khách hàng hoàn toàn không nhìn hay cảm nhận được; nhưng lại rất quan trọng, đặc biệt trong dự án thực hành Agile. “Tôi muốn có một ổ cắm điện ở vị trí này”, sau 10 lần hoàn thành yêu cầu đó từ khách hàng, hệ thống dây điện chắc chắn sẽ chứa nhiều bất cập và không dễ bảo trì. Việc sắp đặt lại những dây điện này một cách hợp lý nhưng vẫn đảm bảo được chức năng hiện có giúp chúng ta sẵn sàng cho yêu cầu về một ổ cắm điện thứ 11. Và thật may là code refactoring thì thường không “tốn kém” và phức tạp như việc đục các bức tường để sắp đặt lại hệ thống dây điện. Vì vậy, chúng ta cũng có thể (và nên)  làm việc này thường xuyên.

Thực hiện code refactoring như thế nào? Vấn đề này thậm chí là quá nhiều cho cả một cuốn sách. Những cách thức đơn giản nhất bạn có thể tham khảo tại http://refactoring.com của huyền thoại Martin Fowler. Tại đây bạn có thể tham khảo những kỹ thuật đơn giản nhất và dấu hiệu nhận biết một đoạn code có thể được refactor; từ chuyện đơn giản nhất như chuyển 2 đoạn code giống nhau thành một hàm đến sự liên kết giữa các đối tượng nhằm đảm bảo tính hướng đối tượng của chương trình. Trang web này thực sự hữu ích với những hệ thống thiết kế theo tư tưởng hướng đối tượng (phù hợp với đa số những mã nguồn hiện giờ), nhưng cũng rất tốt với những tư tưởng lập trình khác. Một chú ý hay là, đôi khi bạn thấy hướng dẫn refactor một đoạn code từ A sang B và nơi khác lại hướng dẫn refactor đoạn code từ B sang A. Điều này không mâu thuẫn, bởi “A hay B tốt hơn?” thì chỉ chính bạn mới có câu trả lời xác đáng trong ngữ cảnh của source code hiện tại. Tuy vậy, vẫn sẽ có những chuẩn chung để một đoạn code được coi là “tốt” hay “dở”; ví dụ, đặt tên biến là a là điều không chấp nhận được trong phát triển phần mềm (nơi duy nhât tôi thấy cách đặt tên biến này phát huy tác dụng là trong những cuộc thi lập trình với source code ngắn và thời gian ganh đua tính bằng mili giây). Và hãy nhớ rằng, code refactoring không làm thay đổi hành vi của chức năng hay hệ thống; do đó, kết quả của việc kiểm thử phải không đổi.

Khi nào thực hiện code refactoring? Về lý thuyết, hãy thực hiện code refactoring bất cứ khi nào có thể. Trước khi commit, mỗi lập trình viên cần đọc lại những đoạn code mình đã viết và xem có thể cải tiến được không. Sau một thời gian, nhóm phát triển cần cùng nhau nhìn lại xem có thể cải tiến ở những điểm nào và cùng thực hiện code refactoring. Tuy nhiên, vấn đề không đơn giản như vậy.

Điều gì ngăn cản code refactoring? Đây là một câu hỏi rất thú vị. Tôi đã gặp rất nhiều nhóm thực hành Agile nhưng không bao giờ thực hiện code refactoring, với những lý do chính như sau:

  • Trình độ kém. Khi nhóm phát triển không có hiểu biết sâu sắc về OOP thì đương nhiên những đoạn code ban đầu viết ra sẽ rất “dở”, nhưng quan trọng là họ hoàn toàn không biết rằng nó “dở”. Việc này càng nguy hại nếu không thực hiện code refactoring bởi nhóm sẽ mãi duy trì năng lực hiện có.
  • Chấp nhận. Sau một thời gian dài, nhóm phát triển nhận ra có rất nhiều đoạn code “dở” nhưng nhóm vẫn chấp nhận bởi số lượng code “dở” là quá nhiều và có tư tưởng chấp nhận “sống chung với lũ”, hoặc nghĩ tới việc viết lại toàn bộ hệ thống.
  • Không có thời gian. Đây là lý do khá xác đáng; bởi như tôi nói ở trên, khách hàng hoàn toàn không nhận được lợi ích trực tiếp từ code refactoring, nên khó thuyết phục họ trả tiền cho nhóm phát triển thực hiện code refactoring. Tuy vậy, việc lắp ổ điện thứ 11 mất 10 giờ, thay vì 2 giờ cho ổ điện thứ 1, thì cũng là tiền của khách hàng mà thôi (và điều này có thể nảy sinh nghi ngờ từ khách hàng rằng năng lực hoặc thái độ làm việc của nhóm đã kém đi).

Tuy vậy, những lý do này sẽ đẩy cả nhóm phát triển vào một vòng luẩn quẩn không hồi kết: trình độ kémsức ép thời gian đưa ra những đoạn code “dở”, không thực hiện code refactoring khiến trình độ không được cải thiện, sau một thời gian đành chấp nhận, khiến sức ép thời gian càng lớn, không thể thực hiện code refactoring, và trình độ không được cải thiện… Và dự án, từ đam mê bỗng thành gánh nặng với nhóm phát triển, khiến động lực làm việc không còn đúng.

Vậy giải pháp là gì? Từ góc độ một lập trình viên, tôi cho rằng việc không thực hiện code refactoring là trách nhiệm của lập trình viên; do họ không đủ đam mê và trách nhiệm cần thiết với “đứa con tinh thần” của mình; không khác một nhà văn viết ra những tác phẩm rẻ tiền. Tuy vậy, người “lãnh đạo” trong dự án Agile cũng phải có trách nhiệm tạo ra những “khoảng lặng” về những chức năng cần bổ sung để nhóm phát triển thực hiện code refactoring. Việc này diễn ra càng đều đặn, trình độ và năng suất của lập trình viên càng cao bởi code refactoring chính là một cách nâng cao tay nghề và hiểu biết sâu sắc dựa trên những best practice cải tiến họ tốt hơn. 1 ngày dành cho code refactoring hôm nay có thể giảm bớt 10 ngày phát triển buồn tẻ sau này.

Giải pháp cho source code đã quá “cũ”? Khi chúng ta “động đâu cũng thấy vấn đề” trong source code, chấp nhận hoặc làm lại từ đầu thường là giải pháp; tuy vậy, cả 2 giải pháp này đều rất tốn kém. Code refactoring có thể là một giải pháp:

  • Sử dụng công cụ phân tích source code (tôi sẽ đề cập ở những bài viết sau) để tìm ra những đoạn code “dở”
  • Nhóm phát triển cùng quét nhanh qua mã nguồn để đánh giá và tìm thêm những vấn đề
  • Ước lượng tổng thời gian cần cho code refactoring
  • Định nghĩa và lên kế hoạch việc kiểm thử. Việc này rất quan trọng vì code refactoring phải đảm bảo không thay đổi hành vi của chức năng và hệ thống. Lúc này automation test được ưu tiên bởi khối lượng kiểm thử nhiều. Không nên (thậm chí là nghiêm cấm) thực hiện code refactoring nếu không có kế hoạch kiểm thử tốt.
  • Lên kế hoạch và thực hiện dần, từng phần. Thật tuyệt vời nếu chúng ta có toàn bộ thời gian để thực hiện; nếu không, hãy thực hiện từng phần song song với quá trình phát triển tiếp. Và hãy kiên nhẫn, chúng ta không thể thấy kết quả chỉ sau 1 vài ngày.

Thât ra, code refactoring là công việc rất đơn giản, đến mức người ta dễ dàng bỏ qua code refactoring để nghĩ tới architect refactoring hay structure refactoring. Nhưng theo tôi, khi thực hiện code refactoring tốt, những design pattern sẽ dần được hình thành và từ đó kiến trúc mới cũng sẽ được hình thành. Rất ít khi chúng ta cần tới architect refactoring; và tôi cũng không tham vọng giới thiệu những điều này sớm.

913 total views, no views today

Problem

After a long time in-door researched, Hung found a good approach to attract a girl and he named it “Girl attracting law by Fibonacci approach” that means the number of presents Hung gives to her is increased by Fibonacci sequence. But don’t stop, he extended to version 2 with some customisation by:

T(n+2) = T(n+1) * T(n+1) + T(n)

with T(n) is a number of presents at the nth dating.

Hung of course has a lot of money but wants to trust a girl, so he should give her 0 present at the first and 1 present at the second dating. And following his theory, 5 presents should be given in the 5th dating as explanation below:

1st number  = 0

2nd number = 1

3rd number = 12 + 0 = 1

4th number = 12 + 1 = 2

5th number = 22 + 1 = 5

Hung said that he has meet her 13 times and today he wants to know how many present he should give. Could you help Hung?

Solution

It seems very easy because the Fibonacci is a basic problem we usually do in learning programming. But, please aware that the number in this sequence increase too fast and need a wide range of positive number. In C# or Java, you could use BigInteger type.

 

103 total views, no views today

Following my Code Challenge problem Cute girl decoder, here is the solution:

Solution

It seems very easy to solve this problem by replacing the substring such as j by gi, dz by d, k by khong.

But, there is a trick at “With words, she usually use”, that means k should be replace by khong only if it’s a word that is normally separated by these characters: [space] , . ; ? !

You could find an implementation below in Objective-C, my thank to Nghia Luong for the code contribution.

It looks good but in my opinion, we could make it better with the open design.

Better design

Let see my implementation below as I think it could be better design to extend the implementation in the future. But please try to find some area we can improve 🙂

And the decoded message would be:

chan qua. em mun an nhieu ga quay cho doi gio duoc khong day? Anh co phai la nguoi iu cua em khong day, neu a la nguoi ieu cua em thi phai dua em di an ga quay chu, anh ma hem dua em di em gian a lien doa. The gio anh mun nhu the nao? ket qua ha? ok, neu ma anh khong dua iem di an ga ran thi nguoi dung den gap em lam gii nua, em khong yeu anh nua dau, iu gi ma co moi viec dua di an ga quay cung khong duoc thi yeu lam gi day, chan anh vagi dan ra ay. Ngay hom sau em noi gi a, em van noi la: chan qua. em mun an nhieu ga quay cho doi gio duoc khong day? Anh co phai la nguoi iu cua em khong day, neu a la nguoi ieu cua em thi phai dua em di an ga quay chu, anh ma hem dua em di em gian a lien doa. The gio anh mun nhu the nao? ket qua ha? ok, neu ma anh khong dua iem di an ga ran thi nguoi dung den gap em lam gii nua, em khong yeu anh nua dau, iu gi ma co moi viec dua di an ga quay cung khong duoc thi yeu lam gi day, chan anh vagi dan ra ay. Ngay hom sau nua em noi gi a, em noi day ne: chan qua. em mun an nhieu ga quay cho doi gio duoc khong day? Anh co phai la nguoi iu cua em khong day, neu a la nguoi ieu cua em thi phai dua em di an ga quay chu, anh ma hem dua em di em gian a lien doa. The gio anh mun nhu the nao? ket qua ha? ok, neu ma anh khong dua iem di an ga ran thi nguoi dung den gap em lam gii nua, em khong yeu anh nua dau, iu gi ma co moi viec dua di an ga quay cung khong duoc thi yeu lam gi day, chan anh vagi dan ra ay.

Go further

The idea of Skype plugin just came to make this problem more fun. But do you want to make it go live? I didn’t build it yet, but if you like this idea, I would like to code and share in the next post.

Do you want to see the new Skype plugin? Throw me at least 50 likes 🙂

140 total views, no views today

Long had a new girl friend, congrats to him. He feels very happy by chatting with her everyday although it’s not an easy work. As a 9x cute girl, she uses a lot of teenage chatting words and it usually takes Long more time to read and understand. And of course, it takes him a lot of his brain’s energy :).

To make it easy, Long plans to build a Skype plugin that can translate her sentences to the normal ones. He found that it’s so easy to replace the cute words by the following rules:

  • With words, she usually use
    • k for khong
    • ko for khong
    • ng for nguoi
    • n for nhieu
    • dc for duoc
    • hok for khong
    • ntn for nhu the nao
    • kq for ket qua
  • She also use these characters
    • j for gi
    • w for qu
    • f for ph
    • dz for d
    • z for d

So if she says “chan wa. em mun an n ga way cho doi jo dc hok dzay?“, it is “chan qua. em muon an nhieu ga quay cho doi gio duoc khong day?

Could you help Long to write this plugin. After that, please try to translate her recent message:

chan wa. em mun an n ga way cho doi jo dc hok dzay? Anh co phai la ng iu cua em k zay, neu a la ng ieu cua em thi fai dua em di an ga way chu, anh ma hem dua em di em jan a lien doa. The gio anh mun ntn? kq ha? ok, neu ma anh hok dua iem di an ga ran thi ng dung den gap em lam ji nua, em k yeu anh nua dau, iu j ma co moi viec dua di an ga way cung ko duoc thi yeu lam j dzay, chan anh vaj dan ra ay. Ngay hom sau em noi j a, em van noi la: chan wa. em mun an n ga way cho doi jo dc hok dzay? Anh co phai la ng iu cua em k zay, neu a la ng ieu cua em thi fai dua em di an ga way chu, anh ma hem dua em di em jan a lien doa. The gio anh mun ntn? kq ha? ok, neu ma anh hok dua iem di an ga ran thi ng dung den gap em lam ji nua, em k yeu anh nua dau, iu j ma co moi viec dua di an ga way cung ko duoc thi yeu lam j dzay, chan anh vaj dan ra ay. Ngay hom sau nua em noi j a, em noi dzay ne: chan wa. em mun an n ga way cho doi jo dc hok dzay? Anh co phai la ng iu cua em k zay, neu a la ng ieu cua em thi fai dua em di an ga way chu, anh ma hem dua em di em jan a lien doa. The gio anh mun ntn? kq ha? ok, neu ma anh hok dua iem di an ga ran thi ng dung den gap em lam ji nua, em k yeu anh nua dau, iu j ma co moi viec dua di an ga way cung ko duoc thi yeu lam j dzay, chan anh vaj dan ra ay.

The solution will be updated in 3 days.

63 total views, no views today