Father’s day 2017

Ngày của ba –

Hôm nay ngày của ba, cảm xúc đong đầy trong từng lời bài hát  http://www.nhaccuatui.com/bai-hat/doi-chan-tran-y-moan.tjgO6wC00FxM.html

Có những thứ mất đi, rồi con lại tiếc nuối,
Có những thứ thuộc về quá khứ, nhìn lại con lại thấy tự hào …

Những lời dặn của ba, công lao của ba cho 2 đứa, mẹ và cả gia đình.

Ba, âm thầm, lặng lẽ kiên cường, gồng mình chiến đấu vượt qua bao khó khăn đến với bản thân để lo cho cả nhà.

Ba – con yêu ba!

Một ngày xa nhà, KLL 2017June18th

Don’t make things complicated

 

This is the email I received from Edmond (blog) – author of  The Effective Engineer book. I think it’s good to re-share here on my blog.

“It’ll only take me a few hours to implement the feature,” we sometimes say. But after finishing, we find that every few weeks, we’re either fixing a bug with the feature, explaining it to another engineer, or helping answer a question from customer support about how it works. The total investment of time to maintain the feature far exceeds the initial few hours of development.

One of the hardest lessons to internalize in software engineering is the hidden costs of additional complexity. Sometimes, complexity is just inherent in the problem space. Matching passengers and drivers while adjusting prices to balance supply and demand is a complex and hard problem. So is routing questions and answers to the people most likely to answer and read them while scaling a community and maintaining quality. Or developing a rich document editor that works well across all devices and supports real-time collaboration. That’s the inherent complexity that we need to tame for the products to succeed.

But other times, the complexity that we wrestle with is complexity that we introduced ourselves. We wrote code in a new programming language that few people knew and now we have to maintain it. Or we added additional infrastructure because we wanted to try the new, hot technology stack that we read about on Hacker News, but it fails in ways that we didn’t initially expect. Or we introduced a feature that few people use but that consumes a disproportionate amount of our time through fixes and bug reports.

Additional complexity imposes many hidden costs. The decisions we make when building software don’t just determine our current development speed. They also have repercussions on how much time and effort we spend maintaining it going forward.

The Hidden Costs of Complexity

Too much complexity increases cognitive overhead and introduces additional friction to getting things done. It seeps through a team in a number of different ways — most directly through code, system, and product complexity but indirectly through organizational complexity. Let’s look at the hidden costs of these different types of complexity one by one.

Code Complexity

Code complexity doesn’t just grow as a linear function of the number of lines of code — it grows combinatorially. In a complicated codebase, each line of code may interact with and affect many other lines of code. It’s difficult for us to wrap our minds around combinatorial growth, which is why we tend to significantly underestimate the time it takes to complete large software projects.

When code is too complex, it becomes harder to ramp up, harder to reason about it, harder to fix bugs. It’s difficult to untangle the dependencies and data flows to track down the source of errors. Engineers may actively avoid the most complex parts of the codebase, opting to work around it even if it’s the most logical place to make a certain change. Or they may avoid working in those areas all together, even if the work can be high-impact.

System Complexity

Engineers like tinkering with new toys, whether it’s because they’re curious or because they think that a new technology might provide a silver bullet for solving one of their pressing problems. When Pinterest was initially scaling their site back in 2011 to handle rapid growth, they used 6 different storage technologies (MySQL, Cassandra, Membase, Memcache, Redis, MongoDB) across a backend team of only 3 engineers. Each new technology promised on paper to address some limitation of their existing system, but in reality, each new solution just failed in its own special way and took more time and effort to manage and maintain. Eventually, the team learned that it would be simpler to scale by adding more machines rather than more technologies, so they eliminated systems like Cassandra and MongoDB and strengthened the remaining components of their architecture.

Fragmenting infrastructure into too many systems brings many hidden costs. Attention gets splintered across the multiple systems. It becomes harder to pool together resources to build reusable libraries for each system, harder to ramp up new people for pager duty, harder to understand the particular failure modes and performance characteristics of each system. The abstractions for each system end up being weaker because there isn’t as much time invested in each one. When tools and abstractions are too complex or there are too many of them, they become difficult for the team to understand and discover.

Product Complexity

Product complexity can result from an ill-defined vision or an untempered ambition leading to a lack of product focus. This desire to be great at many things instead of just one core area sometimes manifests itself in an inability to concisely explain the purpose of a product to new users. Product complexity leads to more code and system complexity — teams add more code and more infrastructure to support new features. When a product has a wide surface area, adding a new feature or modifying an existing one requires expending a large amount of effort to understand and accommodate the olds ones.

An overly complex product means that there are more code branches, more issues to think through, more bug reports that the team needs to address. Engineers and data scientists need to analyze more variables and do more one-off reports, rather than focusing on understanding core user behavior. Engineers need to invest more time to ramp up on the feature space and be productive. Everyone ends up context switching between more projects. And the time spent maintaining all these features is time not spent re-investing in the code, repaying technical debt, or strengthening abstractions.

Organizational Complexity

Code, system, and product complexity in turn breed organizational complexity. Teams need to hire more people to tackle and maintain everything that’s been built. Larger teams mean more communication overhead, more coordination, and lower overall efficiency. The hiring process itself, with all the interviews and debriefing, can consume large portions of the team’s time. And, of course, all the new hires have to be trained and onboarded.

The alternative to hiring more people is splitting the engineering organization into smaller teams — perhaps even creating one-person teams — to cover the large code, system, and product surface area. This reduces the communication overhead, but one-person teams have their own costs. It’s easier to encounter roadblocks that completely stall the sole person on a project, and because there are fewer people to share those troughs with, the experiences can be more detrimental to morale. There are fewer opportunities to work with other people, which can hurt workplace happiness and employee retention. Unless everyone is conscious and proactive about asking for feedback, individuals might receive less feedback about their work because there are fewer people who share the same project context. The reduced feedback can lead to lower quality code or inadvertent complexity being introduced into the codebase or infrastructure.

How to Fight Complexity

Tony Hoare suggested in his 1980 Turing Award lecture, “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.” Having discussed how the non-obvious deficiencies due to complexity can hurt us, how do we go about defending ourselves against these costs?

Here are some strategies you can use:

Optimize for simplicity. Resist the urge to add more complexity. Reason through the maintenance costs. Ask yourself whether the complexity introduced by tackling the last 20% of the problem is worth it, or whether the 80% solution suffices.

Define a mission statement for your team or product to align focus. In Team Geek, Brian W. Fitzpatrick and Ben Collins-Sussman explained how they had mentored the Google Web Toolkit (GWT) team and encouraged them to write down a mission statement. The ensuing debate over the content and style of the mission statement revealed that the lead engineers didn’t actually agree on the product direction! They were forced to confront and reconcile their differences and ultimately came up with, “GWT’s mission is to radically improve the web experience for users by enabling developers to use existing Java tools to build no-compromise AJAX for any modern browser.” How much fragmentation of efforts would have followed if they hadn’t hammered out the differences sooner?

Compose large systems from simpler building blocks. Google is an example of an organization that focuses on building strong, core abstractions that then become widely adopted for a wide variety of applications. They have basic building blocks like Protocol Buffers, the Google File System, and Stubby servers for remote procedure calls. On top of those building blocks, they’ve built other abstractions like MapReduce and BigTable. And on top of those, thousands of applications including large-scale web indexing, Google Analytics site-tracking, Google News clustering, Google Earth data processing, Google Zeitgeist data analysis, and many more are then built.

Clearly define interfaces between modules and services. Decoupling modules and services reduces the combinatorial complexity that can otherwise grow out of a pile of code. At Amazon, Jeff Bezos decreed in 2002 that the company would move toward a service-oriented architecture and that all teams would communicate with each other only through service-level interfaces. While the transformation came with its own set of huge development costs, it enforced separation of code and logic behind services and facilitated the creation of its now highly successful Amazon Web Services.
Periodically pay off technical debt. We’re always building software under incomplete information. As a codebase grows organically in response to changing conditions, entropy also increases. The increased complexity becomes a tax on future development. Budgeting time in development schedules can help reduce that cost. Many engineers and teams budget that time between projects, but holding one-off events can also help. At Quora, I once organized a Code Purge Day where engineers focused on deleting unused code in the codebase. We tracked the progress of code purging on a leaderboard, which made it much more fun than deleting code on your own.

Use data to prune unused features. At Yammer, when engineers or product managers found that enhancing a feature or preserving it in a code refactor would take a non-trivial amount of effort, they would look at usage data to see if the feature was actually used. If not, they’d decide with the team whether they ought to just cut the feature to reduce overall work. This strategy reduces product debt in a similar way to how simplifying code reduces technical debt.

Group ongoing projects around themes. This enables teammates to share the same context as each other, which makes it easier to engage in design discussions, review code, or build reusable libraries. All of these activities help provide checks and balances that individual engineers may other introduce.
When we build software for a school course, we get an oversimplified view of the world — the costs of maintaining any complexity disappear at the end of a class. But in our careers, poor software decisions can impose a tax for years to come.

Don’t complicate things.

-Edmond

P/S: @ iPrice, my current company, we are following agile methodology, improving and strengthen our team everyday 😉

We currently have operation in 7 countries in SEA:

  1. Singapore
  2. Indonesia
  3. Philippines
  4. Hong Kong
  5. Thailand
  6. Vietnam
  7. Malaysia

kết hợp cat grep awk khi xử lý log file trong linux

cat grep awk là những lệnh hay dùng và cực kỳ tiện lợi khi làm việc với log file.

Trong phạm vi bài viết này, giả sử tôi có một đống log file với content như sau

example-log-file
example-log-file

Và tôi muốn, in nội dung của đống log trên vào một file khác csv chẳng hặn, nội dung file csv như trên nhưng thay dấu “:” bằng tab

Có rất nhiều cách, lệnh sed chẳng hạn, nhưng trong bài này tôi muốn kết hợp cat grep awk để xử lý và dùng cờ(flag) F để replace “:” thành tab.

Và câu lệnh sẽ như sau:

Khi đó ta có nội dung file csv như sau:

result
result

Hope this will help 😉

Lảm nhảm cuối tuần

Cuối tuần, rảnh rỗi, vô tư gẫm nghĩ lung tung. Chuyện này, đan chuyện kia, đan đến chuyện học guitar, học tập, viết lách. Túm lại là lảm nhảm …

Hồi nhỏ, lúc còn nhỏ, còn vô tư lắm – lúc đó lớp 2 hay lớp 3 gì đó, một bài tập làm văn ghép chữ “hoa phượng” và “đỏ chói”. Tôi nối từ đỏ chói sang hoa phượng, thế là ra từ “đỏ chói hoa phượng”. Tôi bần thần không hiểu tại sao mọi người ồ lên cười và make laugh on me (làm trò cười) với cách nối từ vô tư hồn nhiên như cô tiên đó. Tôi cũng suy nghĩ mấy năm liền và đến nay tôi cũng nghĩ what wrong with that, what the hell matter with that way of thinking? Tôi nghĩ chả có gì sao, và tôi thấy tự hào vì mình đã bị cười một cách vô cớ (ko hợp lý).

Từ cái vụ nối từ, tôi bị mang tiếng dốt Văn, chậm tiếp thu 😉 – có lẽ chính điều này tích luỹ đôi khi khiến tôi tự kỷ ám thị. Lớn lên hơn xíu, những năm đầu đại học, trong xóm trọ, nhóm bạn tứ xứ mỗi thằng mỗi tài lẻ, trong đó có ngón đàn của ku Hưng (nhà hắn ở Huế, giờ hấn đàn cho Hari uôn j đó, nghe bảo cụng nổi tiếng lắm) làm tôi mê mẩn, tôi quyết mua cây đàn tầm sư học đàn, ngày ngày qua học mót, cuối cùng cũng đàn mót được mấy bài. Mấy bài ni tôi dùng đi dùng lại để thả thính từ đó đến giờ … Có điều liên quan ở đây, khi tôi mua cây đàn về nhà, có người ủng hộ, có người không, có người bảo tay chân to ngắn như vậy làm sao đàn được, tôi chả tự kỷ ám thị mình, vì tôi biết rất nhiều người vẫn đàn được cho dù họ không có tay, thế là đến nay tôi vẫn tự học mót đàn qua mạng và qua bạn bè theo cách của mình. Tôi đang tập bài Cannon in D (bài mà tôi thích nhất), và tôi thấy tốc độ học của mình nhanh hơn, cải thiện đáng kể so với 6 năm trước.

Nhảy qua chuyện tiếng Anh, những ngày đầu bắt đầu đi làm, với vốn tiếng Anh ít ỏi, đủ xài, không biết bao nhiều lần ngắc ngứ, cứng học khi tranh luận với bạn bè, hoặc trao đổi công việc với đồng nghiệp. Mỗi lần như thế tôi lại có động lực luyện tập hơn, tôi lên youtube xem đi xem lại các clip về luyện âm, đọc nhiều bài báo tiếng Anh … Tuy nhiên vẫn không hiệu quả. Có lẽ do sai phương pháp. Tôi chạy qua một vài trung tâm để học, nhưng vẫn không hiệu quả, sau đó tôi có qua trung tâm anh ngữ thượng đỉnh ở đường Cao Thắng quận 3 và luyện phát âm ở đó. Vì sao lại luyện phát âm, vì khi bạn biết cách phát âm chuẩn thì bạn sẽ nghe chuẩn, từ đó tôi luyện âm đến líu lưỡi, méo miệng nhưng vẫn chả ăn thua, vẫn cái thổ ngử ăng lê (như ku Hiếu – bạn cùng trường đại học hay nói hắn). Nhưng được cái trình nghe được cải thiện, và nói chuyện có vẻ người nghe hiểu được ý mình (hoặc có thể họ giả vờ hiểu cho qua). Tôi tiếp tục hành trình luyện tập tiếng Anh hằng ngày qua mạng, nào là hellochao (luyện phát âm, ngữ pháp), tắm anh văn, nói chung là ép xung bản thân, vẫn không hiệu quả, tôi chuyển qua hướng tiếp cận theo kiểu tập gym, tập nhẹ ít nhưng đều đặn điều độ, đến giờ tôi đã tự tin chém gió tiếng Anh, nghĩ ra mấy trò cười để chọc mấy em Tây, bơm câu – xen ngang(góp vui) lời xếp khi xếp làm trò cười trước đám nhân viên. Tôi nhớ có lần (lúc đó mới ra “truồng”) – đi làm công ty hư máy lạnh, thấy chị bạn ra mồ hôi, tôi buột miệng vô tư hỏi “are you hot?” (ý tôi là chị có thấy nóng không). Chị đỏ mặt trả lời(cười) – “yeahh, I  am hot, little bit sexy – no – yah – and sexy”. Tôi bần thần không hiểu tại sao? Mấy anh bạn nói nhỏ giải thích là phải hỏi “do u feel hot” (chị có thấy nóng hok) – đại loại là dùng sai cấu trúc. Từ đó, khi đụng đến từ hot, tôi rất cẩn thận khi hỏi.

Lại nhảy qua chuyện viết lách, chém gió sử sách, địa lý. Thời con đi học – văn sử địa cực kỳ không thích và là ác mộng ban ngày mỗi khi kiểm tra bài 5′ mỗi tiết, tôi tìm đủ mọi cách để lẩn tránh nó, bao nhiêu là chiêu trò (nào là đi giả vờ đau bụng, đi toilet …) tuy nhiên, những quả trứng vẫn tròn trịa trong bảng điểm và có khi cho luôn vào cả sổ đầu bài. Sau này, có cơ hội đi nhiều, đọc nhiều mới thấy tầm quan trọng của Văn, sử, địa. Học tốt văn, cách viết lách của bạn sẽ mượt mà, trôi chảy hơn. Sử, nếu có vốn sử tốt, bạn chém gió đa chiều hơn, sâu hơn, khi nói chuyện có cả tá chủ đề để nói kết hợp với Địa. Một phần bây giờ tôi thích sử địa có lễ nhờ vào những ngày tháng vật vờ thời phổ thông? (cảm ơn vì những năm tháng vật vờ, vô tư đó).

Dài quá, chả biết là mình đang viết cái gì, cơ mà mục đích chính là tản mạn suy nghĩ cuối tuần về tự kỷ ám thị, vượt qua định kiến, chê bai. Tôi nghĩ ở góc độ nào đó, định kiến, chê bai chính là động lực để mỗi cá nhân phát triển. Khi nghe cảm thấy rất khó chịu, nhưng ngầm lại thầm cảm ơn họ những người cho ta (định kiến, chê bai). Nếu không có những ý kiến nghe rất xương thì sao có động lực để luyện tập? Mà luyện tập thế nào nhỉ, chả có công thức nào cả, tất cả là do bản thân, tuy nhiên vẫn có những công thức chung để chúng ta tham khảo.

Tập nốt bài Cannon in D rồi đi bơi thôi 😉 À mà không, xem clip này – ôi sao dễ thương quá đi mất

https://www.facebook.com/long.ky.anh/posts/10207016736616473?notif_t=feedback_reaction_generic¬if_id=1494058204642017 – ahihi

p/s1: đọc lại, chả hiểu mình viết cái quái gì, lủng củng, lóc chóc, bài đặt thêm mấy từ đờ heo, đờ hiếc kiểu nửa tây, nửa ta … etc – mà sao phải tự xoắn mình thế nhỉ, mình thích thì mình viết thôi, ơ sao lại phải xoắn 😉

p/2: con người ai cũng có những điểm giới hạn và khuyết điểm, điều đó không có nghĩa là bản thân bạn không thể vượt qua nó. Nếu bạn thích, quyết tâm và lì đòn,  thì không gì là không thể. (Cơ mà đôi khi chuyện tình cảm nó lại hơi ngược – đối với tôi, tôi nghĩ đó là vì duyên chưa đến thôi 😉 – hehe)

Sáu phép tịnh tiến của Inamori Kazuo

Tôi may mắn được đọc cuốn “Cách Sống” của tác giả Inamori Kazuo. Tôi nghĩ đọc đi đọc lại và trích dẫn lại những đoạn hay từ cuốn sách sẽ giúp tôi nhớ lâu hơn và biết đâu được ai đó vô tình lướt qua blog sẽ biết nó.

1. Nỗ lực để không thu kém người khác
Đi sâu vào nghiên cứu học hỏi nhiều hơn người khác và duy trì nghiêm túc quá trình này. Nếu có thời gian kêu ca phàn nàn thì hãy sử dụng nó để nỗ lực tiến lên phía trước dù chỉ là một chút (vài mm)
2. Khiêm tốn, không tự mãn
Khiêm thu ích, tức là khiêm tốn thì hạnh phúc sẽ đến. Đức khiêm tốn sẽ giúp thanh lọc tâm hồn. Sông sâu sóng lặng, lúa chín cúi đầu.
3. Nhìn lại bản thân mỗi ngày
Kiểm tra xem xét lại hành động và suy nghĩ của mình hàng ngày, xem mình có suy nghĩ nào ích kỷ không. Nỗ lực sửa chữa sai sót của mình.
4. Cảm ơn đời đã cho mình được sống
Luôn suy nghĩ: Được sống trên cõi đời này đã là một hạnh phúc lớn lao. Nuôi dưỡng tấm lòng biết ơn dù là từ những điều nhỏ nhặt nhất.
5. Nhân hậu, vị tha
Làm việc thiện, suy nghĩ về người khác, để tâm vào mọi lời nói hành động, yêu thương mọi người. Người làm việc thiện nhiều sẽ được đền đáp, đúng như câu: “Nhà tích thiện, luôn thịnh vượng”.
6. Không để cảm tính chi phối, không quá dằn vặt trăn trở
Không kêu ca, bất mãn, lo lắng, trăn trở, dằn vặt những chuyện không đâu.

Để tránh tình trạng đó, cần phải toàn tâm toàn ý bắt tay vào công việc để không ân hận gì.

Ngoài sáu điều trên có có những điều hay khác mà tôi từng được đọc từ Kinh Phật, cuốn Đạo Đức Kinh, Triết lý Vô Vi của Lão Tử, triết lý của Lý Tiểu Long, góc nhìn của Albert Einstein về cuộc sống, triết lý sống của Steeve Jobs, nhiều và rất nhiều điều hay mà tôi rất muốn viết trên blog của mình (mục chuyện đời).

Link cuốn sách: http://www.hoangcuong.online/cach-song.html

pagekit-formmaker extension event handler

pagekit-formmaker is a good extension of pagekit cms for dealing with user feedback

https://github.com/Bixie/pagekit-formmaker

Beside good functionality, there are quite lots configurable options when playing with this extension. For eg: if you wanna add a Cc email after client submit a feedback

Well, let’s take a look at their code, in this line

it triggers an event after saving client’s submission to the database, there is an event name formmaker.form.submission

Then, just need to edit index.php file (line 106) https://github.com/Bixie/pagekit-formmaker/blob/master/index.php#L106

In events section, implement the handler for formmaker.form.submission event

That’s it! Hope this help 😉

Site using pagekit cms: hoaphuonghotel.com

ISP – interface segregation principle in SOLID

Interface segregation principle (ISP) – tạm dịch: chả biết dịch sao cho sát nghĩa ??, cái từ segregation dịch ra là tách rời ra. Interface thì khỏi phải giải thích rồi nhỉ 🙂 – anw, let’s move on …

Nguyên tắc này được diễn giải theo nguyên bản tiếng anh theo Uncle Bob
“Client should not be forced to implement an interface that it doesn’t use” – tức là các lớp con (derived classes) không nên hiện thực những phương thức (method) mà nó không cần dùng đến.

Nghe lùng bùng, và khó hiểu, mình lấy lại cái ví dụ mà mình xem ở laracast để minh hoạ trong bài viết này.

Ta có 1 interface WorkerInterface, một class HumanWorker, AndroidWorker. Trong interface WorkerInterface ta có 2 phương thức (work and sleep).
Các bạn có thể thấy ngay là AndroidWorker phải hiện thực phương thức sleep khi implements WorkerInterface – điều này thực tế không bao giờ xảy ra, vì android worker là cỗ máy thì ko ngủ ??

Xét diagram sau:

class diagram 1
class diagram 1

Có thể thấy rằng AndroidWorkerimplements sleep function thì không hợp lý lắm. Tuy nhiên, có thể by pass điều bất hợp lý này bằng cách return null khi implements phương thức này. Nhưng chỉ là giải pháp work-around

Trong terminal bạn chạy: php inversion-principle.php sẽ có output như sau:

php cli 1
php cli 1

Giải pháp:

Để khắc phục ta thử tách riêng 2 functions (sleep, work) trong WorkerInterface thành 2 interfaces (segregation) – với mục đích là AndroidWorker không “bị” phải implements hàm sleep. Khi đó ta có diagram sau:

class diagram 2
class diagram 2

So far seem so good laH ^^ ??. Ta xét thử đoạn code sau:

–> như các bạn thấy đấy, chúng ta lại vi phạm OCP (open closed principle) khi thiết kế như trên. Vậy thì phải làm sao nhỉ, chúng ta thử thêm một hàm (phương thức, method) trung gian beManaged qua một interface trung gian ManagableInterface như diagram sau:

class diagram 3
class diagram 3

Mấu chốt của giải pháp này là: cả 2 class HumanWorkerAndroidWorker đều implements phương thức beManaged của ManagableInterface. Khi override hàm này trong các class con, chúng ta kiểm soát việc gọi hay không gọi các phương thức (override) từ các interfaces khác

Phương án trên,  còn gọi là ISP – Interface Segregation Principle. Hi vọng bài viết này sẽ giúp các bạn có thêm tham khảo về ISP trong SOLID principles

Source code demo: https://github.com/nguyentienlong/isp-in-solid/tree/master

Bài viết liên quan:

  1. http://longka.info/blog/2016/01/24/single-responsibility-trong-solid-principle/ (S)
  2. http://longka.info/blog/2016/04/29/contextual-binding-in-laravel-and-o-in-solid-principles/ (O)
  3. http://longka.info/blog/2015/10/26/a-note-about-solid-principles-demo-in-symfony2/ (SOLID)

References:

  1. Laracast tutorial
  2. https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
  3. Dependency relation in uml: https://vaughnvernon.co/?page_id=31

 

Contextual binding in laravel and how to make your code meet O in SOLID principles

Sometimes, we meet these kind of use cases or features when doing web application programming:

1 – multiple type of report to generate

2-  multiple type of discount to handle

3- multiple type of payment to handle

I recently faced with this use case when doing a freelance project for my customer.

The requirement for this use case is that we have 2 types of reporting: human resources reporting and accounting reporting. And, for quick and dirty we have simple solution for this as below (we use laravel framework 5)

In routes.php, I added this line

type can be: hr or accounting

and the ReportController controller file, in this file based on type of $type variable, we will call the correspond function.

and we simple have the ReportRepository

now, try php artsian serve, and go to localhost:

http://localhost:8000/report/hr or http://localhost:8000/report/accounting

accounting report
accounting report
hr-report-eg
hr-report-eg

The idea for this simple solution is that:

  • In ReportController.php, I injected ReportRepository class into
  • For each type of report (report/accounting or report/hr), the instance $report (type of ReportRepository) will call correspond function with the type of report.

The problem with this way is that it violated Open for extension and close for modification (O) rule in SOLID principle ( I have an article about SOLID principle here ) . For e.g: In case, you have another type of report, you must go to the controller and add more if condition, and add more code for the new report type in ReportRepository as well.

By following the O in SOLID principle, you can reduce if condition, separating the of concern of type of report into another class (in this case, I used laravel fw – so the class file is ApplicationServiceProvider), decoupling code dependency and easy for testing (mocking the interface is alway easy).

So, let’s implement new way that follow O in SOLID principle.

The idea for this way is:

  • For each type of report, there will be an implementation of function show of ReportRepositoryInteface interface.
  • Injecting ReportRepositoryInteface into each controller for each type of report
  • Binding based context ( type of report) in AppServiceProvider class

I hope it much easier for you to understand the second implementation with this diagram ( not actually class diagram)

class diagram for example use case
class diagram for example use case

First, we need ReportRepositoryInterface.php file

then, AccountingReportRepository.php

and HrReportRepository.php

Then, how to make those code work in laravel framework, yah, laravel >5 support contextual binding here https://laravel.com/docs/5.1/container#contextual-binding

adding 2 lines into the routes.php file

It is more reasonable to consider report is an action in AccountingController or HrController ?? 🙂

AccountingController.php

HrController.php

Then, you just need to bind the concrete class to abstract class just in contextual. The logic is as it is:

when AccountingController need ReportRepositoryInterface give it AccountReportRepository
when HrController need ReportRepositoryInterface give it HrReportRepository

and, just need to add the code in register function of AppServiceProvider (github code)

github code for this tutorial (it may contain code of another tutorial):

https://github.com/nguyentienlong/laravel_sandbox_validation/tree/context-binding/

reference:

https://laracasts.com/discuss/channels/general-discussion/what-do-you-think-about-contextual-binding-ioc-laravel-5

@todo: write a demo test code for the repository