Khi nói về Design Patterns, gần 100% những người tôi tiếp xúc đều thực hành Singleton như một design pattern phổ biến và dễ nhất (nhiều người chỉ biết/nhớ mỗi Singleton trong GoF). Tôi thường có 2 câu hỏi:

  1. Sử dụng Singleton và static trong class có gì khác nhau?
  2. Có tự tin cài đặt đúng Singleton?

Thường thì mọi người gặp khó khăn ở câu hỏi #1, và rất chắc chắn ở câu hỏi #2. Tôi thấy, #2 khó hơn #1 nhiều, và nếu bạn không tự tin trả lời #2 thì tôi khuyên bạn nên sử dụng static trong class thay vì Singleton. Tại sao? Đọc tiếp nhé.

Sử dụng Singleton và static trong class có gì khác nhau?

Nếu bạn chưa rõ về câu hỏi thì tôi giải thích thêm một chút: Mục đích của Singleton là tạo ra một object duy nhất trên toàn ứng dụng, kéo theo các thuộc tính của nó cũng là duy nhất; điều này hoàn toàn giống / có thể thực hiện bởi thuộc tính static của class – là nơi duy nhất lưu trữ dữ liệu. Ví dụ:

Cả 2 cách cài đặt trên, appId đều chỉ có một nơi duy nhất để lưu trữ và truy xuất giá trị. Sử dụng static theo #2 gọn và tường minh hơn, vậy cần gì Singleton?

Để ý một chút, một cách cài đặt sử dụng class, một cách sử dụng object. Có 2 sự khác nhau giữa class và object trong trường hợp này:

  1. Life-time: Life cycle của class gắn với ứng dụng, life cycle của object gắn với việc sử dụng. Sử dụng static trong class, những thuộc tính này sẽ được load theo class khi chạy ứng dụng; sử dụng Singleton, những thuộc tính này sẽ được load chỉ khi object được khởi tạo. Trong cả 2 trường hợp, thuộc tính không được tự động giải phóng cho tới khi ứng dụng kết thúc. (do object vẫn có reference được giữ bởi self, tồn tại theo class).
  2. Abstraction: Sử dụng static trong class là concrete implement, sử dụng object cho một tầng abstraction nữa nên dễ thay đổi hơn. Ví dụ, chúng ta cần thay đổi AppConfig sang WindowsAppConfig, theo #2, tất cả mọi nơi truy cập tới appId đều phải sửa đổi; theo #1, nơi duy nhất cần thay đổi là AppConfig.getInstance() (có thể không cần thay đổi nếu áp dụng với những design pattern khác như Factory, DI).

Chẳng có gì đặc biệt, lý thuyết thôi. Chính xác, và vì thế bạn vẫn cài đặt Singleton như đã học? Nhưng thử tìm hiểu thêm nhé.

Có tự tin cài đặt đúng Singleton?

Cài đặt Singleton thế nào?

Dễ ợt, có 2 việc:

  1. Đặt constructor là private để object không thể khởi tạo được từ bên ngoài. 
  2. Cung cấp 1 method duy nhất trả về giá trị static 

Code thường được cài đặt như sau:

Có một vài câu hỏi phía dưới.

Chỉ có đúng 1 object được tạo ra?

Bạn có chắc rằng với cách cài đặt trên chỉ có đúng 1 object có thể được tạo ra? Còn cách nào có thể tạo ra object không?

Reflection là một trong những thứ rất hay ho của một số ngôn ngữ (những ngôn ngữ khác nhau có thể có những tên gọi khác nhau: runtime reference…), và cũng là một thứ khó bởi nó nâng abstraction lên mức runtime. Những pattern như Object Mapper hay DI… không dễ cài đặt nếu không có reflection. Thử đoạn code sau nhé.

Output của đoạn code trên thường sẽ là 2 số nguyên khác nhau, chính là appId. Về lý thuyết, appId chỉ được gán giá trị một lần duy nhất khi khởi tạo object. Như vậy đã có 2 object configappConfig được tạo ra. Điều chúng ta mong muốn là configappConfig là 2 biến cùng tham chiếu tới 1 object trong bất cứ trường hợp nào. Vậy nên giải pháp là kiểm soát constructor.

Chỉ có đúng 1 object được tạo ra?

Bạn có chắc rằng với cách cài đặt trên chỉ có đúng 1 object có thể được tạo ra? Còn cách nào có thể tạo ra object không?

Threading là một trong những thứ rất hay ho nhưng cũng làm đau đầu developer vì nó không đi theo flow thông thường. Thử đoạn code sau nhé.

Hãy thử chạy một vài lần vì cơ hội gặp trường hợp hai số khác nhau được in ra thấp hơn ví dụ trên. Tương tự ví dụ trên, ta có thể khẳng định: có 2 object đã được tạo ra. Sai lầm ở đâu? Hãy để ý method getInstance(), điều gì xảy ra nếu câu lệnh if (self == null) được thực thi đồng thời ở cả threadDownloadthreadUpload? Chúng đều đúng, và câu lệnh tạo object và return vẫn được tiếp tục trên 2 thread độc lập, và trả ra 2 object độc lập. Vậy nên cần phải synchronized việc tạo object.

Chỉ có đúng 1 object được tạo ra?

Bạn có chắc rằng với cách cài đặt trên chỉ có đúng 1 object có thể được tạo ra? Còn cách nào có thể tạo ra object không?

Serializable có thể là một vấn đề. Chúng ta muốn lưu lại cấu hình AppConfig xuống file sau đó load lại khi cần. Thử đoạn code sau nhé.

Bạn sẽ thấy output có dạng này:

Tức là giá trị của object (các properties như appId) được giữ nguyên song object thực chất đã được tạo mới (tìm hiểu thêm về method toString()). Như vậy không đảm bảo 1 object được tạo ra duy nhất trên toàn bộ life cycle của ứng dụng. Vì cơ chế deserialize sẽ tạo mới object. Chúng ta cần sửa thành:

Chỉ có đúng 1 object được tạo ra?

Bạn có chắc rằng với cách cài đặt trên chỉ có đúng 1 object có thể được tạo ra? Còn cách nào có thể tạo ra object không?

Đáng tiếc là vẫn còn, clone thì sao?

Kết

Singleton “chuẩn” nên được cài đặt như sau:

  • Bài viết này tôi lấy cảm hứng từ: https://medium.com/exploring-code/how-to-make-the-perfect-singleton-de6b951dfdb0, viết lại theo cách dễ đọc hơn.
  • Đến đây chắc bạn đã hiểu tại sao tôi khuyến nghị dùng static trong class nếu bạn không thực sự rõ về Singleton. Với class bạn không có vấn đề với serializable và reflection… Điều bạn gặp phải về threading có thể được IDE warning.
  • Hãy nhớ nhé, Singleton không dễ đâu.

419 total views, 38 views today

Ngày hôm qua, tôi có viết 1 status về việc những lập trình viên (LTV) cần phải nhanh hơn nữa. Thật là khó để diễn tả hết lý do trong 1 status ngắn, nên post này tôi hy vọng sẽ nói được nhiều hơn 1 chút.

Thế giới ngày càng khắc nghiệt…

20 năm, 10 năm trước, chuẩn mực của một LTV là gì? Dù là béo phì (LTV Mỹ) hay gầy còm (LTV Việt) thì cũng đều căng thẳng, đầu tóc rối bời, những cặp kính cận lớn và… xa lánh cộng đồng; họ đặt mình vào những căn phòng với thuốc lá, bia, chất kích thích và chỉ giao tiếp với nhau hoặc với máy tính. Chẳng khó để nhận ra một LTV trong đám đông.

Ngày nay, thật khó để nhận ra một LTV trong đám đông. Tôi xin lỗi, song dấu hiệu duy nhất để tôi nhận ra những đồng nghiệp của mình là họ thường mang theo laptop. Vậy thôi. Những LTV ngày nay, họ quá giống một người bình thường với áo thun, quần jeans, đầu vuốt keo, đôi khi cùng khuyên tai hay quần tụt.

Công bằng mà nói, những LTV ngày nay đang có cuộc sống xã hội phức tạp hơn. 20 năm trước, LTV là những người đi tiên phong trong ngành CNTT với chỉ số IQ bắt buộc phải nằm trong top 10% nhân loại, họ luôn phải giải quyết những bài toán khó đòi hỏi nền tảng khoa học tốt; và họ tạo cho mình 1 đặc quyền: tách ra khỏi đời sống xã hội. Giờ đây, như xu thế của mọi ngành công nghiệp phát triển khác, việc lập trình trở nên đại chúng hơn, và LTV dần mất chất hơn. Họ bị kéo trở lại đời sống xã hội bình thường.

Và góc nhìn của LTV cũng buộc phải thay đổi. Cảm giác của LTV cũng buộc phải thay đổi. 20 năm trước, LTV vui mừng vì viết ra 3 dòng code giúp tiết kiệm được 1KB bộ nhớ sau 1 tuần trăn trở. Giờ đây, LTV vui mừng vì tạo ra sản phẩm giúp ích tới hàng ngàn người dùng. Hệ quy chiếu thay đổi, và thước đo cũng đã thay đổi. LTV thay vì đặt mình trong một không gian riêng, chiêm ngưỡng vẻ đẹp của những đoạn code về mặt khoa học thuần tuý; giờ họ buộc phải gắn mình với đời sống kinh doanh phức tạp hơn: Tiết kiệm 1KB bộ nhớ chẳng có ý nghĩa gì nếu nó không mang lại giá trị cho người dùng. 20 năm trước, những LTV được coi là tệ hại nếu không biết cách tiết kiệm thêm 10KB bộ nhớ. Ngày nay, những LTV được coi là thiếu đạo đức nếu viết ra những dòng code tuy tối ưu nhưng khiến đồng nghiệp khó hiểu. Tất nhiên, ở đâu đó trên thế giới, hệ quy chiếu truyền thống vẫn tồn tại, nhưng nó đang ít dần đi.

Và rồi những LTV truyền thống cảm thấy thất vọng, họ thấy thật nực cười khi phải quan tâm tới những giá trị mang lại cho khách hàng, bực bội khi phải quan tâm tới lợi nhuận của doanh nghiệp. Không, tôi muốn làm thế này, vì nó chạy rất nhanh, vì nó là thử thách, vì tôi muốn giải quyết bài toán này... Họ bị stress khi bị lôi trở lại đời sống xã hội phức tạp, nơi những giá trị kinh doanh là thứ họ chưa bao giờ muốn biết. Tôi chỉ muốn lập trình thôi, trời ơi. – một LTV gào lên và ngay lập tức ông chủ của anh ta sẽ đáp lại: Anh bạn à, một bức ảnh đẹp phải được đo bằng view và like chứ không phải vì nó tuân theo tỉ lệ vàng. Thế đấy.

Nhưng thế giới cũng đang đẹp hơn…

Những LTV chân chính có cảm giác rằng LTV không còn là một nghề cao quý và đáng trân trọng khi mà công việc lập trình được bình dân hoá đến mức #kids_can_code và luôn bị cuốn theo giá trị kinh doanh của doanh nghiệp. Song không thể phủ nhận rằng, cuộc sống của họ đang tốt dần lên chính nhờ những điều đó. Họ biết thêm nhiều kiến thức, kỹ năng mới, hoà nhập hơn đồng nghiệp và xã hội. Họ có thời gian để tập gym, quan tâm tới thời trang, những show ca nhạc… thay vì chỉ vùi đầu trong những đoạn code và chất kích thích.

Nhưng không có nghĩa là những LTV chân chính muốn mất đi không gian riêng. Họ vẫn muốn và vẫn cần có những không gian để không quan tâm tới giá trị kinh doanh, rời xa những ồn ào hiện tại và quay trở lại niềm vui chỉ với những dòng code. Đấy là lý do hàng loạt những website như topcoder, projecteuler, hackerrank… ra đời cùng hoạt động Code Retreat, Code Kata… Và doanh nghiệp cũng ngày càng chú trọng đến những hoạt động như Hackathon nơi họ cố gắng tạo ra một không gian để nhân viên của mình được làm  những LTV chân chính dù chỉ 1 vài lần trong năm.

Cũng giống như mọi ngành nghề khác, nhiều LTV không muốn nghề nghiệp của mình bị bình dân hoá; nhưng số nhiều và toàn xã hội lại hưởng lợi khi công việc này trở thành đại chúng với những con người cân bằng giữa công việc và đời sống xã hội. Nhưng cuộc chơi giờ là vậy, những LTV, hãy sống cân bằng, biết cách giao tiếp với đồng nghiệp, quan tâm tới những chỉ số kinh doanh và giá trị mang lại cho khách hàng. Nhưng đừng quên rằng, vẫn còn đó những nơi cho chúng ta không gian để chỉ quan tâm tới kỹ thuật, chỉ sống như một LTV chân chính. Hãy tìm lấy không gian để sống như một LTV chân chính nếu bạn thực sự là một LTV chân chính 🙂

1,574 total views, 2 views today

Follow the topic The most important job is recruiting, I want to share my view on the level of developer. It may be not meet your idea, but to know the differences can give you a deep level you want to go on.

There are at least 4 levels as follow i think:

Coders. They can figure out it, your idea or detail specification with flow. It’ll work, easy like drink a beer, but it won’t be pretty or usable in large scale environment.

Hackers. Don’t mix it with the black hat/white hat hackers. In this case, they are the folks with skillful, with detailed understanding of (some) area deeply, or they can hack into the core of framework, can do some crazy things with tricks.

Programmers. Ok, they write code with understand of algorithms, workflow. They can work alone and well, they can do some incredible things.

Developers. Are the best of all, can use lots of different systems and languages and get them to communicate with each other. They have deep and broad knowledge, from hardware to software, they are true and broad professionals, they can work with people, transfer knowledge and communicate well.

I’ve more than 10 years working experience, have good connection, know a lot of people who working in IT related field in Vietnam … but i know only some true developer. I’m pretty sure that “Your Education” won’t get you hired, especially in A level candidate, it depends on your experience, your skill set and what you can bring to their business, what they’ll receive if hire you. To be honest, if you are closer to one of above level already, you can get an idea of which direction to head and do the best of you.

And now, let me ask some questions:

1. What is the differences between Game Developer and Game Programmer ? Why the game companies always want hire game developer instead of game programmer ?

Game development involves managing all of the different jobs that need to be done, it’s not only coding, it needs skill and tools to build up a game, and it’s not easy. They need the real developer, who can make system run, who can lead the game programmer to code.

2. What is fullstack Developer ? Why company still want to hire .NET Web Developer ?

For me, fullstack developers who are familiar with the entire stack (from hard ware to software, from environment to business logic) … and they know how to make thing easier for those around them. They don’t care about languages, platforms or environment.

I read many job posting in Internet, it’s too funny that some companies want to hire .NET Web Developer, Java/PHP Web Developer. If you want to hire developer, don’t care about the language, just simple like “1 back-end developer, 1 front-end developer or mobile developer. Expect on their skill on back-end or front-end, don’t expect on their skill on programming language. If you just want people who can work with .NET, hire a coder / hacker, they can do almost your idea.

And again, what’s the difference ??? 🙂

381 total views, no views today