Giải thích tên dịch vụ trên Amazon Web Service (AWS)

Dịch vụ trên AWS được đặt tên theo 2 kiểu như sau:
  • Tên viết tắt, như: EC2, S3, RDS…
  • Tên của vật thực, như: BeanStalk, Kinesis, Snowball…
Vậy làm sao để nhớ, chỉ có những người đã từng làm việc qua những dịch vụ này mới có thể nhớ nổi. Đối với người mới bắt đầu, việc thích ứng với những cái tên này thật sự gặp nhiều trở ngại. Cùng tôi tìm hiểu xem chúng có những ý nghĩa, và tại sao lại đặt ra như vậy nhé.

STTTên dịch vụViết tắt/giải thíchTên gợi nhớSử dụng
1EC2Elastic Compute CloudAmazon Virtual ServersChứa một số thứ mà user nghĩ đó là computer. Hay gọi nó là máy ảo cho dễ.
2S3Simple Storage ServiceAmazon Unlimited FTP ServerChứa bất kì thứ gì, dân IT gọi là object. Chứa hình ảnh, file tĩnh, html, css, backup, file chia sẻ, còn gọi là persistent storage.
Nhiều lắm! ( > ^-^ < )
3RDSRelational Database ServiceAmazon SQLDatabase thôi, chỉ có điều chứa từ MS SQL, MySQL, PostgresDB, OracleDB, đến MariaDB.
4BeanStalkRepresent the stem of a bean plant, proverbially fast growing and tall.Amazon App ServiceGiống như AppService của Azure. Nói trắng ra là host web app, mobile app. Tự scale, tự HA, lớn lên theo nhu cầu, như “dây đậu” (beanstalk).
5VPCVirtual Private CloudAmazon Virtual Colocated RackTách môi trường AWS ra thành nhiều môi trường nhỏ, gọi là private cloud. Của riêng bạn, không lầm lẫn với bất kì môi trường nào khác, có gateway, có security rule….
6IAMIdentity and Access ManagementUsers, Keys and CertsQuản lý users, key, certs. Tập trung, dễ sử dụng bởi nhiều dịch vụ khác, quản lý dễ hơn. Chỉ vậy thôi đấy.
7SQSSimple Queue ServiceAmazon QueueHàng đợi, dịch sát nghĩa, giữ request lại theo thứ tự, tích hợp với các dịch vụ khác trong AWS như SNS. Giống RabbitMQ.
8SNSSimple Notification ServiceAmazon MessengerGửi thông báo đến điện thoại, email hay SMS gì đấy tùy bạn cấu hình nhé!
9EMRElastic MapReduceAmazon HadooperỨng dụng trong BigData. Tạm gọi là Hadooper
10ECSElastic Container ServiceAmazon Docker as a ServiceChạy container, tất cả xoay quanh containers đều có ở đây.
11KinesisRepresent an undirected movement of a cell, organism, or part in response to an external stimulusAmazon High ThroughputSử dụng trong trường hợp dữ liệu cần đưa đi với tốc độ cao, ví dụ như dùng cho việc phân tích dữ liệu hay lượt like hotgirl trên Facebook chẳn hạn, hoặc là lượt xem MV Lạc Trôi mới của Sơn Tùng.
12SESSimple Email ServiceAmazon Transactional EmailGửi email tự động như “Bạn đã mất tiền ở ví Bitcoin của mình”, hoặc là “Website của bạn đã bị hack”. Cũng có thể dùng để gửi email chúc ngủ ngon cho 100 cô người yêu mỗi đêm, nhưng không khuyến khích.
13EBSElastic Block StoreAmazon EC2 Block StorageĐĩa gắn vào máy ảo (EC2 ở trên) để chạy OS. Tưởng tượng chính là chiếc Samsung SSD 960 Pro vậy hay là Seagate 20GB 7200rpm thời tống cũng được.
14LambdaFunction as a ServiceAWS App ScriptsFunction as a Service, mỗi lần chạy Function là tính tiền, không cần dựng môi trường như máy ảo rườm rà đối với 1 function bé tí, bắt event và thế là execute Function thôi.
15Route53Route DNS (53)Amazon DNS + DomainsQuản lý tất cả những bài toán nào liên quan đến DNS, bao gồm cả việc mua domain mới.
16CloudFrontIn Front of CloudAmazon CDNCDN như Akamai, nhưng ít edge node hơn, hiệu năng chưa ai so sánh giữa CloudFront và Akamai. Chỉ biết là CloudFront dùng để stream các trận đấu của Việt Nam tại U23 Châu Á 2017 vừa rồi thôi. Có xem là có trải nghiệm CloudFront rồi đấy nhé.
17SnowballA ball of snow pressed together in the hands, especially for throwingAWS Big Old Portable StorageDịch vụ chuyển dữ liệu hàng petabyte đến AWS DataCenter, bằng cách shipping phần cứng đến AWS thông qua UPS (công ty chuyển phát hàng hóa).

Nhìn nhận đúng đắn về Testing

Vai trò của bạn trong dự án là gì? Bạn là một PM? PTL? developer? hay là một tester? Từ vị trí của mình, bạn nghĩ công việc kiểm thử (testing) trong dự án nhằm mục đích gì?
Tôi đã làm việc với khá nhiều người, ở nhiều vị trí trong dự án. Dường như, họ không có một định nghĩa rõ ràng về công việc của Test team. Nhớ lại về những dự án mình đã làm việc, những bạn tester mà tôi đã có cơ hội chỉ bảo, hướng dẫn đến với nghề, chưa bao giờ tôi nói với họ một định nghĩa cụ thể nào đó về công việc mà họ đang và sẽ làm. Đâu đó trong quá trình thực hành và trưởng thành với nghề, họ có thể nhận thức được mình đang làm gì, và vô hình chung hình thành một khái niệm nhất định cho bản thân mình về công việc testing trong dự án.
Hãy giúp tôi, tự đặt cho mình câu hỏi: Testing là gì?
Tất nhiên, tôi không thể biết câu trả lời của bạn (trừ khi bạn sẵn lòng hồi đáp lại cho tôi). Thường thì sẽ có một vài quan điểm, nhưng việc nhận thức sai vấn đề có thể ảnh hưởng đến hiệu quả và mục đích công việc của bạn rất nhiều. Vì sao ư? Tôi sẽ chỉ cho bạn thấy.
Một trong số những nguyên nhân quan trọng của chất lượng test kém là thực tế, các kỹ sư phần mềm thường bắt đầu với một định nghĩa sai lầm. Họ có thể cho rằng:
Testing là quá trình chứng minh rằng lỗi không xuất hiện trong chương trình.
hoặc
Mục đích của testing là chỉ ra rằng chương trình đã thực hiện những chức năng dự định một cách chính xác.
hoặc
Testing là quá trình thiết lập sự tin cậy rằng một chương trình đã làm những gì mà nó phải làm.
Có gì sai không? Ừm, có vẻ không sai nhỉ! Nhưng thực ra, những định nghĩa này hoàn toàn ngược.
Khi bạn kiểm thử một chương trình, bạn cần thêm các giá trị cho công việc của mình. Thêm giá trị cho quá trình kiểm thử có nghĩa là làm tăng chất lượng hoặc độ tin cậy của chương trình. Tăng độ tin cậy của chương trình chính là tìm và loại bỏ lỗi.
Do đó, đừng test một chương trình chỉ để cho thấy chương trình đó có làm việc hay không, thay vào đó, bạn nên bắt đầu bằng một giả định, rằng chương trình đó có lỗi (tất nhiên rồi, đây thậm chí có thể gọi là thực tế ấy chứ) và do đó, testing là quá trình tìm ra lỗi nhiều nhất có thể.
Khi đó, một định nghĩa hợp lý sẽ là: Testing là một quá trình thực hiện một chương trình với mục đích tìm ra lỗi.
Nếu so sánh với các định nghĩa như trên đã đề cập, có vẻ như đây là một sự chơi chữ tinh tế, nhưng thực chất, nó tạo nên một sự khác biệt quan trọng trong công việc của bạn.
Đứng về khía cạnh tâm lý, con người thường có xu hướng tập trung vào vào một muc tiêu nào đó. Nếu mục tiêu của chúng ta là chứng mình rằng “lỗi không xuất hiện trong chương trình”, chúng ta sẽ vô thức hướng tới mục tiêu này. Chúng ta sẽ có xu hướng chọn ra những test data có khả năng thấp gây ra lỗi chương trình. Nhưng nếu mục tiêu là để “tìm ra lỗi”, chúng ta sẽ sử dụng những test data có khả năng cao hơn giúp tìm ra lỗi. Như vậy, với mục tiêu thứ hai, testing đã mang lại nhiều giá trị hơn mục tiêu đầu tiên.
Vấn đề thứ hai với định nghĩa như là “Testing là quá trình chứng minh rằng lỗi không xuất hiện trong chương trình” là điều không thể đối với hầu hết các chương trình, kể cả với những chương trình nhỏ.
Một lần nữa, các nghiên cứu tâm lý đã chỉ ra rằng, con người thường làm việc kém đi khi họ được yêu cầu thực hiện một công việc mà theo họ là không thể làm được. Ví dụ, nếu bạn được yêu cầu giải đố ô chữ trên tờ New York Times trong 15 phút (ô chữ của New York Times rất nổi tiếng và được ưa chuộng, thông thường là ô chữ 15×15, các số vào Chủ nhật là ô chữ 21×21), chúng ta sẽ hầu như không thu được kết quả gì sau 10 phút vì hầu hết chúng ta sẽ bỏ cuộc khi cho rằng việc này là không thể. Tuy nhiên, nếu bạn được yêu cầu làm việc này trong 4 giờ, có thể chúng ta sẽ có kết quả nhất định sau 10 phút. Định nghĩa về testing như một quá trình “tìm ra lỗi” có trong chương trình khiến nó trở thành một nhiệm vụ có-thể-thực-hiện-được, do đó vượt qua khỏi vấn đề về tâm lý.
Vấn đề thứ ba với định nghĩa kiểu: “Mục đích của testing là chỉ ra rằng chương trình đã làm những gì nó phải làm” là thực tế, một chương trình làm đúng những gì yêu cầu vẫn có thể có lỗi. Nhưng lỗi cũng xuất hiện khi chương trình không làm đúng như mong muốn. Hoặc khi chương trình làm những việc không được yêu cầu, lỗi cũng có thể tồn tại. Chúng ta sẽ nhìn nhận sâu sắc hơn về lớp lỗi nếu chúng ta xem xét việc kiểm thử chương trình là một quá trình tìm lỗi hơn là một quá trình chứng minh rằng một chương trình sẽ làm đúng những điều mà nó được yêu cầu.
Tóm lại, kiểm thử chương trình nên được nhìn nhận một cách thích hợp là quá trình tìm ra những lỗi tiềm tàng (mà mình giả định là tồn tại) trong một chương trình. Đương nhiên, bạn cũng muốn sử dụng kiểm thử chương trình để thiết lập mức độ tin cậy cho việc chương trình sẽ làm đúng những việc mà nó phải làm và không làm những việc mà nó không nên thực hiện, nhưng mục đích này chỉ đạt được tốt nhất sau khi đã được kiểm tra kỹ càng để tìm ra lỗi.

Sự thật đắng lòng: Đôi khi cắm đầu ngồi code là cách ngu nhất để giải quyết vấn đề

Qua bài viết về button trị giá 300 triệu đô, mình thấy các bạn có vẻ hào hứng với những bài viết theo phong cách kể chuyện. Vì vậy, ở bài viết này, mình sẽ bắt đầu bằng cách kể một câu chuyện nho nhỏ về 1 chàng coder nghèo tên K (Gọi là Khoa Khoe Khoang hay Khải gì đó tuỳ bạn).
Tiếp xúc với máy tính từ năm 10 tuổi,  K vô cùng ngạc nhiên trước sức mạnh của cỗ máy vô tri vô giác ấy, và nuôi mơ ước trở thành một lập trình viên. Lên cấp 3, nhờ giỏi Toán, K được vào lớp chuyên Toán của trường. Với niềm đam mê lập trình, K nhanh chóng tiếp cận và thành thạo Pascal, C, giật được vài giải Olympic tin học.
Nhờ điểm cao, K đậu vào một trường đại học công khá danh tiếng. Vào trường, được học thêm Ngôn ngữ lập trình, về Cấu trúc dữ liệu và thuật toán, K càng ngày càng thích code hơn. K code ngày code đêm, cắm đầu vào luyện thuật toán cho thành guru, lúc rảnh rỗi K lại kiếm sách bài tập làm… cho đã thèm. K luôn nộp bài sớm hơn các bạn để thể hiện sự hơn người của mình. Do suốt ngày chỉ biết cắm mặt vào máy tính, K trải qua 4 năm đại học mà vẫn FA…
Tốt nghiệp ra trường, những tưởng một người lập trình tốt, giỏi technical (Như K tự nhận xét mình) sẽ kiếm được việc ngon, lương cao,dễ dàng thăng tiến. Vòng phỏng vấn diễn ra cũng khá suôn sẻ, K trả lời trơn tru một số câu hỏi về technical, nhưng lại ngập ngừng ở 1 số câu hỏi kiểu “Khi có xung đột với thành viên trong nhóm, em xử lý thế nào?” hoặc “Em đã có sản phầm cá nhân nào nổi bật chưa?”.
Đồng nghiệp của K có một thằng tên là H. K rất khinh thằng H này vì nó chỉ tốt nghiệp ĐH dân lập (FPT), đã thế trong giờ làm còn ít ngồi code mà toàn vào stackoverflow, pluralsight, webtretho, lâu lâu còn mở wordpress gõ gõ gì đó, hình như là blog. Thế rồi, vì vài chuyện nhỏ nhặt dưới đây, K dần dần chuyển từ khinh sang ghét và căm thù thằng H :
  • Chuyện thứ nhất: Công ty có một chương trình khá cũ chạy trên một con server cùi bắp. Gần đây, vì lưu lượng sử dụng nhiều, lâu lâu chương trình lại bị OutOfMemoriesException (tràn bộ nhớ). Tự tin với khả năng code của mình, K xin anh team leader source code của chương trình để ngồi optimize lại. Hì hục mất 2 tuần, K chỉ mới optimize được 30% chương trình cho tiết kiệm RAM. Thằng H nghe chuyện, nhanh nhảu đoảng liên hệ với anh team leader và bên IT, lắp thêm 2 thanh RAM 4GB vào con server cũ. Chỉ mất 5 phút, từ đấy chương trình chạy vo vo không còn OutOfMemories nữa.
  • Chuyện thứ hai: Team cần làm một phần mềm về phim ảnh, trích xuất dữ liệu từ Galaxy Cinema, Lotte, CGV. Với tinh thần hăng hái, ham học hỏi, K tự nghiên cứu về web parser để trích xuất thông tin từ các trang này. Do các trang này có dung Ajax, Paging phức tạp, K mất gần 2 tuần để viết và test việc parse dữ liệu từ Galaxy và Lotte. Công sức của K tiếp tục đổ sông đổ biển khi ngay hôm sau, thằng H nhanh nhảu nói với anh team leader: “Anh ơi, bên 123phim nó có API sẵn rồi, có cả Cinebox với 4,5 hãng nữa cơ. Phí chỉ có 50k/tháng thôi, mình liên hệ mua rồi integrate vào nha anh” và anh team leader gật đầu đồng ý.
  • Chuyện thứ ba: K thương thầm một em QC da trắng dáng cao tên ngực khủng tên M cùng công ty. Ngoài làm QC, em còn chuyên đăng hình khoe thân kiêm bán kem trộn làm trắng da trên facebook. Nghe tiếng K code giỏi, em thủ thỉ “Anh K làm cho em cái trang web bán hàng nha, làm đẹp đẹp em thưởng cho <3″. Vốn dại gái, lại tự tin rằng mình giỏi Java thần thánh, K bắt đầu vẽ database, dùng Spring Boot, Heroku để code một trang bán hàng hoành tráng.
  • Hôm sau lên công ty, đang định show giao diện cho em M xem thì K thấy em đang đứng bên cạnh thằng H, mắt long lanh đầy ngưỡng mộ “Anh H giỏi quá, làm web vừa đẹp lại vừa nhanh, em nhờ hôm qua mà giờ đã xong rồi”. Hóa ra thằng ku dùng PHP – thứ ngôn ngữ rẻ tiền, dung framework Magento và chôm đại cái theme có sẵn đâu đó để làm web cho ẻm một cách nhanh chóng. Hết giờ làm, bé M thưởng thằng H bằng cách đi ăn uống, xem phim rùi đi chỗ-mà-ai-cũng-biết-là-chỗ-nào-đấy :”>. Sau hôm đó, K nhìn thằng H bằng ánh mắt mang hình viên đạn.
  • Chuyện cuối cùng: Cay cú với thằng H, K quyết định viết một blog cá nhân để cạnh tranh với nó. Thấy thằng ku dùng wordpress cùi bắp, K quyết tự khẳng địng bản thân bằng cách code luôn một blog và publish mã nguồn lên github cho nó biết mặt. Code gần 3 tháng mà vẫn chưa xong, blog thì chưa viết được dòng nào, còn blog kia của thằng H đã được hơn 200 nghìn lượt xem.
Câu chuyện trên là hư cấu và không dựa trên bất cứ phần trăm sự thật nào (Bác nào thấy nhột thì cứ việc). Hãy khoan chửi em M là con bitch ngực to, hay ông team leader ngu chết mẹ không thấy đươc khả năng của K. Rõ ràng, cùng làm một việc, nhưng H lại hoàn thành một cách nhanh chóng và nhẹ nhàng hơn K. Lý do là vì K tiếp cận vấn đề theo cách của một coder, H lại tiếp cận vấn đề theo cách của một developer.
Với coder, code là thứ tối thượng có thể giải quyết mọi vấn đề. Họ thích tự học những ngôn ngữ/công nghệ mới. Họ là những người tập trung công sức để viết những dòng code thật tốt, chạy thật nhanh, optimize thật kĩ. Họ không thích tái sử dụng code của người khác, mà thích tự code để “học hỏi và phát triển”. Thế nhưng, một trong những sự thật đau lòng của ngành lập trình là đôi khi chả ai quan tâm đến code mình viết cả.
Khác với coder, developer thường tiếp cận vấn đề theo cách khác. Họ cũng có thể code và code giỏi, nhưng họ tập trung trước nhất vào vấn đề  cách giải quyết. Khi có yêu cầu từ khách hàng, họ sẽ phân tích, tìm cách giải quyết phù hợp nhất, ít tốn thời gian và công sức nhất, trước khi bắt tay vào code.
Như slogan “từ coder đến developer” của blog, mình viết để chia sẻ những kiến thức về technical và một vài thứ khác để giúp bạn tiến hóa từ coder lên developer. Giỏi technical sẽ giúp bạn làm một coder giỏi, nhưng chỉ technical không thôi là chưa đủ. Bạn cần phải nhét vào đầu tư duy lập trình, tư duy sản phẩm, tư duy phân tích thiết kế và vô số thứ khác để trở thành một developer đúng nghĩa. Để học được những điều này, hãy like fanpage và theo dõi những bài viết tiếp theo của blog nhé. Thân chào.
Chuyện bên lề, có 1 bạn khá dễ thương phỏng tác câu chuyện của mình theo 1 cách nhìn khác, cũng rất đáng đọc. Chắc cũngđồng cảm với bạn K nên trong truyện này bạn cho K 1 cái happy ending rất đẹp?
Câu chuyện hôm nay kể về một chàng coder H. Cậu đến với tin học hơi muộn, và khi nhận ra mình đam mê tin học thì đã muộn cho việc chuẩn bị thi vào các trường đại học danh tiếng về CNTT. H không giàu, nhưng cũng đủ khá giả để theo đuổi đam mê với đại học FPT.
Vào trường, cậu nhận thấy các trường đại học có vẻ danh tiếng kia dạy thật thiếu bài bản, toàn dạy những thứ lý thuyết, rất thiếu kỹ năng mềm, hay những thứ ứng dụng. Cậu học vừa đủ những môn CTDL, và tập trung hơn vào những môn “thực tế”, tự học lập trình ứng dụng và tham gia các hoạt động ngoại khóa.
Tốt nghiệp ra trường, nhờ vốn kỹ năng mềm cùng khả năng lập trình ứng dụng, cậu được nhận vào công ty. Nhưng khi phỏng vấn, cậu lại bị ngắc ngứ những câu cơ bản về cấu trúc dữ liệu, về nguyên lý lập trình.
Đồng nghiệp của H có một thằng tên K. H rất ghét thắng này vì nó tốt nghiệp đại học “danh tiếng”, lại còn khoe mấy cái giải thưởng tin học toàn mớ lý thuyết vô nghĩa. Hai đứa ngồi gần nhau, cậu lâu lâu ngó sang nó thấy nó cứ cắm cúi viết code, chả quan tâm gì đến thế sự cả. Còn cậu vừa phân bố thời gian để hoàn thành deadline, vẫn có thời gian để lên webtretho, viết blog, lâu lâu gặp bug thì chỉ cần lên stackoverflow là xong. Cậu không thích thằng K và sẽ cố gắng chứng tỏ mình hơn K. Và cậu đã làm được như vậy.
Chuyện thứ nhất – thứ hai – thứ ba – tương tự bài gốc
H rất hài lòng với những gì mình làm được. Còn K vẫn cứ ngồi đó cố gắng viết code hoàn chỉnh cho cái website bán hàng và blog, thật là rỗi việc.
  • Đến một ngày, cái phần mềm cũ rích chạy trên server cùi bắp lại dở chứng. Trưởng nhóm nhận thấy vấn đề diễn ra ngày càng thường xuyên hơn trước, tỉ lệ thuận với lượng dữ liệu đổ vào chương trình càng nhiều theo thời gian, và module gây ra chuyện đó còn được sử dụng ở nhiều chương trình khác nữa. Chẳng lẽ lại phải mua hẳn server mới và một loạt server khác nữa phòng tránh chuyện này? K nhanh nhảu chạy vào và xin tiếp tục dự án **tối ưu hóa code ** đã bị dừng lại trước đó. Trưởng nhóm đồng ý, và dù rất khó khăn nhưng 2 tuần sau K cũng đã hoàn thành. Và tất cả các chương trình sử dụng chung module đó đều chạy nhanh và ổn định hơn trước. K được anh trưởng nhóm hết sức khen ngợi và hứa hẹn sẽ tăng lương vào đợt tiếp theo.
  • 123phim đột ngột dừng hoạt động do kinh doanh thua lỗ. Các api chỉ còn truy cập được trong vòng 1 tháng. May mắn thay, nhờ có **crawler ** trước đây của K, nhóm đã nhanh chóng thay đổi và tích hợp trở lại vào phần mềm.
  • Em QC lắm chuyện đòi H thêm chức năng cho bán hàng, lần này là tích hợp với giaohangnhanh để ẻm đỡ mất công tìm người giao hàng, nhập đơn hàng bằng tay. Chết thật, H lâu lắm có đụng đến Magento đâu cơ chứ, lại chả có module nào trên mạng, mà cái theme cũng là hàng mua biết customize sao bây giờ. QC giận H và chạy sang nhờ K. K (dù rất ghét con nhỏ này) vui vẻ nhận lời vì K nắm rất rõ code của mình và việc chỉnh sửa không quá tốn thời gian lắm. Từ đó con nhỏ QC này suốt ngày bám lấy K mà quên H.
H tức giận vì K càng ngày càng được nhóm đề cao và cả em QC cũng đổ theo hắn nữa. Giờ H chỉ còn một blog. Chậc, 200k lượt xem, tên K kia đến bao giờ mời đạt được. Hắn chỉ có lèo tèo vài bài viết chán ngòm về kỹ thuật. Đến một hôm, K xin phép nghỉ việc. H mừng lắm, cuối cùng cái gai trong mắt cũng chịu đi.
Lại nói về K. Cái blog mà K chăm chút, viết blog dù ít nhưng chất lượng may mắn được một nhà tuyền dụng để mắt tới. Và công ty của nhà tuyển dụng này thuộc hàng top thế giới. K nhận được thư mời, dù rất đắn đo và lo lắng nhưng cậu quyết định thử sức. Bất ngờ thay, công ty nọ chỉ toàn hỏi những câu hỏi liên quan đến giải thuật, tư duy mà không hỏi bao nhiêu về công nghệ cả, và họ nói rằng họ rất ấn tượng với những giải thưởng tin học K đạt được. Tự tin với kiến thức nền tảng của mình, K trả lời xuất sắc hầu hết câu hỏi của nhà tuyển dụng. K nhanh chóng được đề nghị vào làm với một mức lương và môi trường làm việc mà mọi dev đều mơ ước.
Pham Huy Hoang
(Blog toidicodedao.com)

Đừng để bị Design Patterns “dắt mũi”

Design Patterns có thể trở thành đồng minh tốt nhất khi được sử dụng một cách chính xác. Tuy nhiên, nếu dùng sai thì nó có thể sẽ hại đời chúng ta! Vậy nên ta cần phải tìm hiểu để làm thế nào sử dụng chúng một cách chính xác.
Vì design pattern là một giải pháp được xác định trước cho một vấn đề cụ thể, đã được chứng minh qua thời gian và được biết đến bởi software community, nên bạn cần áp dụng nó ngay khi bạn có cơ hội, càng sớm càng tốt.
  Depositphotos_29100055_l-2015-1-768x768
Tuy nhiên, làm sao biết khi nào tốt nhất để sử dụng một design pattern? Bài viết dưới đây sẽ cho các bạn hiểu rõ hơn về tầm quan trọng trong việc đánh giá khả năng của những thay đổi trong các phần code, cũng như hiểu được mục đích của pattern mà chúng ta đang sử dụng. Từ đó bạn sẽ dễ dàng đưa ra quyết định phù hợp.
Có 3 điều mà tôi muốn đề cập đến. Hãy cùng xem nhé!

Nếu bạn biết áp dụng các nguyên tắc thiết kế object-oriented, design pattern sẽ tự khắc xuất hiện một cách tự nhiên

Tôi tin rằng việc biết các nguyên tắc thiết kế object-oriented và áp dụng tốt như SOLIDKISS và YAGNI thì sẽ quan trọng hơn nhiều so với design pattern. Nếu bạn áp dụng những nguyên tắc này, design pattern sẽ tự nhiên mà xuất hiện.
Ví dụ bạn đang mở một app nhỏ đang hiển thị một bản nhạc và giả sử bây giờ chúng tôi sẽ chỉ vẽ các nốt nhạc. Trong số các class khác nhau của hệ thống, chúng ta sẽ thực hiện như sau:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php class NoteDrawer { public function drawHalfNote() { $this->drawNoteHead('white');
        $this->drawStem();
    }

    public function drawQuarterNote()
    {
        $this->drawNoteHead('black');
        $this->drawStem();
    }
}
Như bạn có thể thấy thì có sự trùng lặp rõ ràng ở đây. Sự khác biệt duy nhất đó chính là trong tham số áp dụng cho các phương pháp drawNoteHead. Cách tốt nhất để thoát khỏi sự trùng lặp thì cần phải làm như sau:
  1. Tạo một phương thức drawNote chung chung và copy đoạn giữa từ một trong những chức năng sẵn có.
  2. Biến đổi các tham số của phương pháp drawNoteHead thành một phương pháp mới. Sau đó, phương pháp này có thể được ghi đè bởi các children classes, vì vậy father class giữ basic logic và children classes giữ sự khác biệt.
  3. Thay thế tất cả drawHalfNote và drawQuarterNote với phương pháp drawNote mới của child class tương ứng.
Tiếp theo nhé!
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php abstract class NoteDrawer { public function drawNote() { $this->drawNoteHead($this->getHead());
        $this->drawStem();
    }

    abstract protected function getHead();
}

class HalfNoteDrawer extends NoteDrawer
{
    protected function getHead()
    {
        return 'white';
    }
}

class QuarterNoteDrawer extends NoteDrawer
{
    protected function getHead()
    {
        return 'black';
    }
}
Vẫn có thể có những giải pháp khác, nhưng ta cần hiểu mình muốn gì, đó là: loại bỏ sự trùng lặp code.
Hmm, bạn đoán được đó là gì không?
Bạn vừa apply Template pattern rồi đó!
Chỉ cần như thế mà không phải nghĩ gì nhiều. Đó chính là lợi ích của nguyên tắc thiết kế object-oriented.
Bạn có thể không biết hết design pattern trên thế giới này, nhưng miễn là bạn biết nguyên tắc thiết kế object-oriented tốt, thì bạn không cần phải lo nghĩ gì nhiều.
Tất nhiên, nếu bạn biết về Template pattern, bạn có thể nhìn thấy nó ngay lập tức. Đây chính xác sẽ là kịch bản hoàn hảo cho các template pattern khi bạn apply pattern phù hợp. Rõ ràng, chúng cũng sẽ làm cho cuộc sống của bạn dễ dàng hơn.

Nhiều khi bạn chẳng cần nó đâu~

Đôi khi chúng ta nhìn vào một đoạn code xấu xí, chúng ta sẽ lập tức nhận ra chỉ có pattern “cứu cánh” và làm cho nó tốt hơn.
Nhưng điều gì sẽ xảy ra nếu nó có tác dụng và bạn không cần phải thay đổi nó?
Hãy quay lại ứng dụng hiển thị bản nhạc lúc nãy, nhưng với một kịch bản hơi khác một chút. Hãy tưởng tượng rằng mình muốn tạo ra một class cho từng loại khóa của âm nhạc. App này sẽ hỗ trợ tất cả các khóa nhạc dựa trên 3 điều cơ bản: C, F và G.
Ta có một chức năng trong code mà sẽ trả về đúng các khóa của âm nhạc. Nó trông như thế này:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

function getClef($note, $octave)
{
    switch ($note) {
        case 'C':
            switch ($octave) {
                case 1: return new C1Clef();
                case 2: return new C2Clef();
                case 3: return new C3Clef();
                case 4: return new C4Clef();
                case 5: return new C5Clef();
                default: throw new UnknownClefException();
            }
        case 'F':
            switch ($octave) {
                case 3: return new F3Clef();
                case 4: return new F4Clef();
                case 5: return new F5Clef();
                default: throw new UnknownClefException();
            }
        case 'G': 
            switch ($octave) {
                case 1: return new G1Clef();
                case 2: return new G2Clef();
                default: throw new UnknownClefException();
            }
        default: throw new UnknownClefException();
    }
}
Bạn đã thấy có vài code xấu xí và có thể là bạn đang cưc kỳ muốn chỉnh sửa cấu trúc của nó lại phải không? Có lẽ bạn đang nghĩ đến việc áp dụng Factory Method pattern vì nó phù hợp và chắc chắn làm cho code sạch hơn.
Nhưng mà nếu tôi nói với bạn rằng đoạn code này sẽ không bao giờ thay đổi thì sao nhỉ?
Tôi không phải là một nhạc sĩ, vì vậy tôi có thể sai, nhưng có vẻ không thực tế khi trong tương lai sẽ phát minh thêm các nốt nhạc mới (???) Nếu không bổ sung các nốt nhạc mới thì không việc gì phải thay đổi đoạn code này.
Không có  chuyện code “dỏm” vì nếu nó chạy tốt thì bạn không cần phải thay đổi nó làm gì, cấu trúc lại code (với một design pattern hoặc các kỹ thuật khác) chỉ làm phát sinh chi phí không cần thiết mà thôi.

Chi phí của việc áp dụng design pattern

Có rất nhiều design pattern khác nhau, nhưng hầu hết trong số đó đều có điểm chung: khi bạn apply, bạn cần phải đặt ra một số cấu trúc. Nói cách khác, bạn cần phải add class và (hoặc) tương tác code.
Trong ví dụ đầu tiên, cấu trúc này bao gồm một abstract class được mở rộng thêm bởi hai children class. Hơn nữa, để cho các code cũ sử dụng các class mới, bạn cũng cần phải thêm các update không liên quan trực tiếp đến các design pattern.

Làm sao bạn có thể biết khi nào dùng design pattern là tốt nhất?

Đó là câu hỏi triệu đô! Điều đó phụ thuộc vào 2 thứ: đoạn code đó sẽ thay đổi thế nào về sau, và mục đích của pattern là gì.

Khả năng thay đổi của những đoạn code.

Những ví dụ chúng ta đã xem chứng tỏ sự quan trọng của việc xem xét những thay đổi để đi đến quyết định có dùng design pattern hay không.
Trong ví dụ đầu, nó thật sự là cần thiết để dùng pattern. Bởi vì sau cùng chúng ta không thể dừng lại ở bản nhạc mà chỉ có nốt 1/2 và 1/4, đúng vậy không? Và do việc thêm nhiều loại nốt nhạc sẽ lặp lại nhiều code hơn, nên template pattern cần phải được áp dụng để tránh lặp code.
Trong ví dụ thứ 2, thì lại là điều hoàn toàn ngược lại. Vì chúng ta giả thiết một cách an toàn là không có thêm khóa và nốt nhạc, nên doạn code này không cần phải thay đổi, và vì vậy không cần sử dụng design pattern.

Mục đích của pattern

Sẽ là không đủ nếu chỉ biết một pattern được triển khai thế nào; chúng ta cũng cần biết lý do đằng sau sự tồn tại của pattern đó.
Nói một cách khác, chúng ta cần biết một pattern được tạo ra để làm gì. Chúng ta cần hiểu một cách toàn diện về loại bài toán mà nó giải quyết. Nếu chúng ta biết điều này, sẽ dễ dàng hơn cho chúng ta để biết khi nào hợp lý để dùng nó.
Để đưa ra quyết định dùng design pattern hay không, có 2 cuốn sách tôi muốn giới thiệu:
  • Head First Design Patterns: Nếu bạn chưa nghe về design patterns hoặc mới bắt đầu, đây là cuốn sách bạn phải đọc. Nó giải thích các design pattern được sử dụng nhiều nhất theo cách rất dễ hiểu.
  • Design Patterns: Elements of Reusable Object-Oriented Software: Đây là một cuốn kinh điển và cũng là cuốn phải đọc. Nó được viết như là danh mục các design pattern hay dùng, được tổ chức theo 3 nhóm chính: creational, structural, and behavioral.
Thật không may, có một vấn đề nữa mà chúng ta thường gặp phải là nhận biết và áp dụng pattern. Khi bạn viết code từ đầu, sẽ dễ dàng để nhận ra sự cần thiết của 1 pattern. Tuy nhiên, khi bạn viết tiếp một đống code cũ, sẽ khó hơn để sử dụng design pattern.
Bạn cần phải chắc chắn bạn hiểu đầy đủ về đoạn code trước khi thay đổi. Đây sẽ là cách dễ nhất hoặc là kinh nghiệm đau đớn nhất tùy thuộc vào đoạn code viết mạch lạc hay rối rắm ra làm sao.
May mắn cho chúng ta, có một cuốn sách nữa có thể giúp xử lý vấn đề này: Refactoring to Patterns. Cuốn này sẽ cho bạn biết làm thế nào để sử dụng code có sẵn và tích hợp design patterns vào nó.
Những cuốn sách trên và nhiều cuốn khác nữa được giới thiệu trong các bài viết của John mà tôi rất muốn giới thiệu đến bạn.

Kết

Conclusion-768x432
Design patterns không phải là mục tiêu tối thượng của việc lập trình. Thực tế, tôi không nghĩ có điều đó. Chúng đơn giản là một công cụ mà có thể làm cho code của chúng ta gọn gàng hơn và dễ hiểu cũng như bảo trì khi được ứng dụng đúng.
Vậy thì bạn nghĩ khi nào nên dùng design pattern, và khi nào thì không? Hãy cho chúng tôi biết ý kiến của bạn. Comment bên dưới!
(simpleprogrammer.com)

Tại sao các Developer là Tester “dỏm” và làm sao khắc phục?

5 lý do khiến các developer là không phải Tester “trời sinh”
1.Con nhà mình – Con nhà người ta
Khi đứng trong một căn phòng đông người, nếu ai đó bước lên và hỏi: “Ai trong đây có đứa con xấu xí?” 95% sẽ im lặng. Nhưng nếu hỏi rằng: “Ai trong đây có một người bạn có đứa con xấu xí?” thì số người giơ tay sẽ rất rất rất nhiều.
Hiện tương tương tự xảy ra với các developer khi được yêu cầu test những dòng code của chính mình. Họ có xu hướng không thể nhận ra lỗi sai của mình, trong khi nếu đó là của người khác, họ không những có thể tìm ra, xác định lỗi mà còn sửa được chúng.
2. Developer thường đơn giản hóa những vấn đề phức tạp
Các Dev thường tập trung vào việc biến những bài toán phức tạp với những yêu cầu rối mù thành những task nhỏ và có thể hành động được (actionable), rồi lại “dịch” chúng thành những dòng code nhỏ. Ví dụ, đề bài yêu cầu tạo ra một nút bấm để người dùng đăng ký dung trial, họ sẽ chuyển những yêu cầu đó thành các dòng và biến cái nút đó trở nên dùng được.
Testing thì hoàn toàn ngược lại. Task của một tester cần phải lấy những tính năng đơn giản và suy nghĩ về những kịch bản phức tạp mà có thể làm “sập” hết mọi thứ chỉ vì bugs.
3. Tập trung vào những “kịch bản lạc quan”
Một lần nữa, các developer luôn suy nghĩ về cách khiên mọi thứ xảy ra, hoặc đạt được kết quả mà họ muốn thông qua những dòng code. Trong khi đó, với testing, chúng ta cần phải xác định và tìm ra những lúc mà mọi thứ không làm việc trơn tru như chúng ta mong muốn.
Một phần quan trọng của testing là tìm ra điểm yếu của hệ thống và trong hệ thống để có thể sửa chúng. Phần lớn developers đều quan tâm đến việc giải quyết vấn đề chứ không phải vẽ ra thêm vấn đề. Chính điều này khiến họ không thể có tư duy của tester: phá hoại thay vì xây dựng.
4. Bỏ qua những chi tiết nhỏ trong tổng thể
Tester có xu hướng tìm những thứ có thể bẻ gẫy pattern. Coder lại có xu hướng tìm hoặc tạo ra pattern.
5. Thiếu kiến thức End-to-end và góc nhìn của người dùng
Phần lớn các doanh nghiệp đều không bỏ ra nhiều thời gian hay nỗ lực để khiến giúp các developer hiểu được người sử dụng sản phẩm của họ. Các developer luôn chỉ làm việc họ được thuê để làm: viết code và phát triển sản phẩm mới, và câu chuyện về việc thấu hiểu khách hang lại được để lại cho Quản lý Sản phẩm.
Vậy nên chẳng lạ gì khi nhiều lần các developers không thể biết được các mà người dùng của họ sử dụng hệ thống. Do đọ họ sẽ không dành thời gian để dự đoán những nguy cơ có thể xảy ra khi người dùng sử dụng hệ thống của họ
Trở thành một developer-tester giỏi?
Rõ ràng là chẳng developer nào giỏi test tự nhiên. Tuy nhiên, vẫn có nhiều cách để thay đổi điều đó.
  1. Ngừng xem testing là “bới lông tìm vết”
Một đội giỏi đòi hỏi cả developer và tester phải test. Bước đầu tiên để trở thành tester giỏi hơn là quên đi thực tế rằng bạn đang “test”. Test không phải là một công việc “ghê gớm”, và cũng không phải là một công việc dễ dàng. Nếu bạn muốn trở nên giỏi test, hãy bắt đầu bằng việc xem việc này là nghiêm túc, y như những công việc thường ngày khác của bạn và đảm bảo bạn dành đủ thời gian cho việc test.
2. Thấu hiểu những điểm yếu và giới hạn của mình với tư cách một developer
Nhận thức được “điểm mù” của chính mình là tiền đề cho việc phát triển. Biết được điểm mạnh và yếu của mình sẽ giúp bạn làm việc tốt hơn. Nếu có điều gì bạn cần học hỏi them, hãy học. Nếu bạn cần nhờ ai đó giúp đỡ, hãy mạnh dạn nhờ. Chẳng có gì là đáng xấu hổ khi nhờ người khác tư vấn hay giúp đỡ.
3. Lên kế hoạch code theo những khó khăn bạn gặp phải
Test đòi hỏi việc lên kế hoạch để đảm bảo bạn đang làm đúng và không bị “lạc đề”. Dưới đây là một số ví dụ:
  • Đừng test code của chính mình: như đã nói, developer luôn làm tốt nhất khi test của người khác, và cũng hãy nhờ người khác test những dòng code của chính bạn.
  • Trước khi test, hãy NGHĨ! Hãy nghĩ về cả những kịch bản tốt và xấu, nghĩ về cách mà người dùng sẽ sử dụng hệ thống, phân tích sản phẩm và tìm xem những điểm yếu.
  • Có checklist: Hãy đảm bảo rằng bạn sẽ viết ra những gì mà bạn muốn test trước khi bắt đầu để đảm bảo bạn không lỡ mất điều gì quan trọng một khi bạn vào việc.

Gulp: Vũ khí bí mật của một web developer (P.2)

Tiếp nối phần 1 cũng là phần cuối cùng trong series Gulp: Vũ khí bí mật của một web developer, chúng tôi sẽ hướng dẫn bạn về Optimizing Built Assets và Cache Busting.
Optimizing Built Assets
Bạn sẽ cần 2 plugin mới. Để thêm vào, bạn sẽ chạy lệnh sau:
npm install --save-dev gulp-clean-css gulp-minify
Plugin đầu tiên sẽ rút gọn CSS, sử dụng clean-css package và plugin thứ hai sẽ rút gọn JavaScript, sử dụng UglifyJS2 package. Đầu tiên, chúng ta sẽ load 2 package này gulpfile.js:
var minify = require('gulp-minify');
var cleanCss = require('gulp-clean-css');
Sau đó sử dụng khi thao tác trước khi viết output:
.pipe(minify())
.pipe(cleanCss())
gulpfile.js sẽ như thế này:
var gulp = require('gulp');
var concat = require('gulp-concat');
var minify = require('gulp-minify');
var cleanCss = require('gulp-clean-css');
 
gulp.task('pack-js', function () { 
 return gulp.src(['assets/js/vendor/*.js', 'assets/js/main.js', 'assets/js/module*.js'])
  .pipe(concat('bundle.js'))
  .pipe(minify())
  .pipe(gulp.dest('public/build/js'));
});
 
gulp.task('pack-css', function () { 
 return gulp.src(['assets/css/main.css', 'assets/css/custom.css'])
  .pipe(concat('stylesheet.css'))
  .pipe(cleanCss())
   .pipe(gulp.dest('public/build/css'));
});
 
gulp.task('default', ['pack-js', 'pack-css']);
Hãy chạy gulp một lần nữa. Bạn sẽ thấy rằng tập tin stylesheet.css được lưu ở định dạng rút gọn, và file bundle.js vẫn còn lưu như cũ. Lúc này, bạn cũng có bundle-min.js đã được lược giản. Bạn chỉ cần file rút gọn và lưu dưới định dạng bundle.js, vì vậy bạn sẽ modify code với các thông số sau:
.pipe(minify({
 ext:{
  min:'.js'
 },
 noSource: true
}))
Theo tài liệu gulp-minify plugin (https://www.npmjs.com/package/gulp-minify), nó sẽ đặt tên theo mong muốn cho các phiên bản rút gọn, và lệnh cho các plugin không tạo ra các phiên bản chứa original source. Nếu bạn xóa các nội dung của build directory và chạy gulp từ command line một lần nữa thì bạn sẽ kết thúc chỉ với hai tập tin được rút gọn. Bạn đã vừa triển khai xong minification phase của build process.
Cache Busting
Tiếp theo, chúng ta sẽ thêm cache busting và sẽ cần phải cài đặt một plugin như sau:
npm install --save-dev gulp-rev 
Require trong gulp file:
var rev = require('gulp-rev');
Sử dụng các plugin cần phải có sự khéo léo. Đầu tiên, chúng ta phải dẫn minified output thông qua plugin. Sau đó, bạn cần phải lệnh các plugin một lần nữa sau khi đã ghi các kết quả vào đĩa. Plugin đổi tên các file với  hash tag độc đáo, và nó cũng tạo ra manifest file. Manifest file là map được sử dụng bởi application để xác định filename mới nhất trong HTML code. Sau khi modify gulp file, dòng code kết thúc sẽ hiển thị như thế này:
var gulp = require('gulp');
var concat = require('gulp-concat');
var minify = require('gulp-minify');
var cleanCss = require('gulp-clean-css');
var rev = require('gulp-rev');
 
gulp.task('pack-js', function () { 
    return gulp.src(['assets/js/vendor/*.js', 'assets/js/main.js', 'assets/js/module*.js'])
        .pipe(concat('bundle.js'))
        .pipe(minify({
            ext:{
                min:'.js'
            },
            noSource: true
        }))
        .pipe(rev())
        .pipe(gulp.dest('public/build/js'))
        .pipe(rev.manifest())
        .pipe(gulp.dest('public/build'));
});
 
gulp.task('pack-css', function () {
    return gulp.src(['assets/css/main.css', 'assets/css/custom.css'])
        .pipe(concat('stylesheet.css'))
        .pipe(cleanCss())
        .pipe(rev())
            .pipe(gulp.dest('public/build/css'))
        .pipe(rev.manifest())
        .pipe(gulp.dest('public/build'));
});
 
gulp.task('default', ['pack-js', 'pack-css']);
Hãy xóa các nội dung của build directory và chạy gulp một lần nữa. Lúc này, chúng ta sẽ thấy có hai file với hash tags với mỗi filename, và manifest.json đã lưu vào public/build. Nếu mở manifest file, bạn sẽ thấy rằng nó chỉ có một reference đến một trong các minified và tagged file. Mỗi task viết một manifest file riêng biệt, và một trong số nó sẽ kết thúc việc ghi đè.
Bạn cần phải modify task với các thông số bổ sung để tìm kiếm các manifest file đang tồn tại, và để merge new data vào đó. Hơi phức tạp một chút, nên bạn có thể xem đoạn code bên dưới:
var gulp = require('gulp');
var concat = require('gulp-concat');
var minify = require('gulp-minify');
var cleanCss = require('gulp-clean-css');
var rev = require('gulp-rev');
 
gulp.task('pack-js', function () {
    return gulp.src(['assets/js/vendor/*.js', 'assets/js/main.js', 'assets/js/module*.js'])
        .pipe(concat('bundle.js'))
        .pipe(minify({
            ext:{
                min:'.js'
            },
            noSource: true
        }))
        .pipe(rev())
        .pipe(gulp.dest('public/build/js'))
        .pipe(rev.manifest('public/build/rev-manifest.json', {
            merge: true
        }))
        .pipe(gulp.dest(''));
    });
 
gulp.task('pack-css', function () { 
    return gulp.src(['assets/css/main.css', 'assets/css/custom.css'])
        .pipe(concat('stylesheet.css'))
        .pipe(cleanCss())
        .pipe(rev())
        .pipe(gulp.dest('public/build/css'))
        .pipe(rev.manifest('public/build/rev-manifest.json', {
            merge: true
        }))
        .pipe(gulp.dest(''));
});
 
gulp.task('default', ['pack-js', 'pack-css']);
Đầu tiên, chúng ta dẫn output đến rev.manifest (). Điều này tạo ra các tagged file đã có trước đó. Bạn đang cung cấp desired path của rev-manifest.json, và buộc rev.manifest () phải merge các file hiện có (nếu nó tồn tại). Sau đó, gulp nhận lệnh để viết manifest vào directory, tại thời public/build. Path issue là do bug và sẽ được mô tả chi tiết hơn trên GitHub.
Lúc này, bạn đã có automated minification, tagged file và manifest file. Tất cả những điều này sẽ cho phép bạn deliver file một cách nhanh chóng hơn cho người dùng, và cache busting sẽ xuất hiện bất cứ khi nào chúng ta thực hiện những sửa đổi (modifications). Tuy nhiên, chúng ta vẫn còn hai vấn đề.
Vấn đề đầu tiên là nếu chúng ta thực hiện bất kỳ sửa đổi nào trong các source file, tagged file mới sẽ được tạo ra, nhưng những tagged file cũ vẫn còn ở đó. Vì vậy, chúng ta cần một số cách để xóa tự động các minified file. Hãy giải quyết vấn đề này bằng cách sử dụng plugin cho phép xóa file:
npm install --save-dev del
Require trong đoạn code và xác định hai task mới, mỗi task phân định cho từng loại source file:
var del = require('del');
 
gulp.task('clean-js', function () {
 return del([
  'public/build/js/*.js'
 ]);
});
 
gulp.task('clean-css', function () {
 return del([
  'public/build/css/*.css'
 ]);
});
Sau đó, hãy đảm bảo các task đã chạy xong trước khi có 2 task chính:
gulp.task('pack-js', ['clean-js'], function () {
gulp.task('pack-css', ['clean-css'], function () {
Nếu bạn chạy gulp một lần nữa sau sửa đổi này, bạn sẽ chỉ có các minified file mới nhất.
Vấn đề thứ hai là chúng ta không muốn cứ phải tiếp tục chạy gulp mỗi khi có sự thay đổi. Để giải quyết điều này, bạn sẽ cần phải xác định watcher task:
gulp.task('watch', function() {
 gulp.watch('assets/js/**/*.js', ['pack-js']);
 gulp.watch('assets/css/**/*.css', ['pack-css']);
});
Thay đổi definition của default task:
gulp.task('default', ['watch']);
Nếu bây giờ bạn chạy gulp từ command line thì nó sẽ không còn hoạt động nữa. Lý do bởi vì gulp đã lệnh cho watcher task theo dõi các source file khi có bất kỳ thay đổi nào, và chỉ build khi nó phát hiện một sự thay đổi. Nếu bạn cố gắng thay đổi source file và xem lại console một lần nữa, bạn sẽ thấy task ack-js và pack-cs chạy tự động cùng với dependency.
Bây giờ, tất cả chúng ta phải làm là load flie manifest.json trong application và nhận tagged filename từ đó. Cách mà bạn làm phụ thuộc vào ngôn ngữ back-end và technology stack. Tuy nhiên, bạn có thể load manifest thành array hoặc object. Sau đó xác định helper function để lệnh cho versioned assets từ manner template:
gulp(‘bundle.js’)
Một khi làm được điều đó, bạn sẽ không phải lo lắng về sự thay đổi tagged filename nữa. Từ đó, bạn sẽ có thể tập trung vào viết code chất lượng hơn.
Kết luận
Hy vọng rằng điều này sẽ giúp bạn phát triển các build process trong các application của riêng mình.
Hãy nhớ rằng Gulp chỉ là một trong những công cụ có thể được sử dụng cho mục đích này, và vẫn có rất nhiều công cụ khác như Grunt, Browserify, và Webpack. Chúng khác nhau về mục đích và phạm vi của vấn đề mà chúng có thể giải quyết. Trong số đó có thể giải quyết các vấn đề mà Gulp không làm được, chẳng hạn như bundling JavaScript module with dependency loaded on demand.

The Ultimate XP Project

  (Bài chia sẻ của tác giả  Ryo Amano ) Trong  bài viết  số này, tôi muốn viết về dự án phát triển phần mềm có áp dụng nguyên tắc phát triển...