I would like to share with you some tips to deal/prevent NPE in your code:

The BIG IMPORTANT rule: do NOT assign / pass / return null value and keep your code as cohesive as possible.

Programming tips / techniques:
1. Return an empty collections instead of null.
For example:

return Collections.emptyList()


return Collections.emptySet()


return Collections.emptyMap()

2. Return


or “” instead of null

3. Return “UNKNOWN” enum instead of null

4. Check null before executing a variable

5. Null-safe checking technique

if("Hello".equals(hello)) { }

instead of

if(hello != null) {
	if(hello.equals("Hello")) { }


if(hello.equals("Hello")) { }

Principle and Pattern:
6. Null Object Pattern (https://sourcemaking.com/design_patterns/null_object/java-0)
(My favourite pattern belong with Template Method and Bridge)
Instead of

public Manager getManager(ManagerType inType){
	switch(inType) {
		case PROJECT:
			return ProjectManager();
			return DepartmentManager();
	return null;

Let try:

public Manager getManager(ManagerType inType){
	switch(inType) {
		case PROJECT:
			return ProjectManager();
			return DepartmentManager();
	return NullManager();

Design tips:

class NullManager extends Manager {
	// Implement all abstract methods of Manager
	// Override neccessary methods to drive to do "Nothing" or "Default" action.

7. Avoid too many dot syntax. (http://en.wikipedia.org/wiki/Law_of_Demeter)
For example:


Class Variable:
8. Try initializing variable member of class before using it.
Direct initialization

private List<Person> mPersons = new ArrayList<Person>();

Initialize them in class Constructor

public Family() {
	mPersons = new ArrayList<Person>();

Constructor dependency injection

public Family(List<Person> inPersons) {
	mPersons = inPersons;

Provide accessibility through getter and using lazy initialization

public getPersons() {
	if(mPersons == null) {
	mPersons = new ArrayList<Person>();
	return mPersons;

9. Avoid / eliminate method dependency injection (setter)

public setPersons(List<Person> inPersons) {
	mPersons = inPersons;


The Solution to Technical Debt

From http://blog.crisp.se/2013/07/12/henrikkniberg/the-solution-to-technical-debt

By Henrik Kniberg

(related article: Good and Bad Technical Debt – and how TDD helps)
(Translations: Russian)

Are you in a software development team, trying to be agile? Next time the team gets together, ask:

How do we feel about the quality of our code?

Everyone rates it on a scale of 1-5, where 5 means “It’s great, I’m proud of it!” and 1 means “Total crap”. Compare. If you see mostly 4s and 5s, and nothing under 3, then never mind the rest of this article.

If you see great variation, like some 5s and some 1s, then you need to explore this. Are the different ratings for different parts of the code? If so, why is the quality so different? Are the different ratings for the same code? If so, what do the different individuals actually mean by quality?

Most likely, however, you will see a bunch of 2s or worse, and very few 4s and 5s. The term for this isTechnical Debt, although for the purpose of this article I’ll simply call it Crappy Code.

Congratulations, you have just revealed a serious problem! You have even quantified it. And it took you only a minute. Anyone can do this, you don’t have to be Agile Coach or Scrum Master. Go ahead, make it crystal clear – graph the results on a whiteboard, put it up on the wall. Visualizing a problem is a big step towards solving it!

Don’t worry, you aren’t alone, this is a very common problem. <rant>However, it’s also a very stupid, unnecessary problem so I’m baffled by why it is so common.</rant>

Now you need to ask yourselves some tough questions.

Do we want to have it this way?

If not, what do we want the code quality to be? Most developers want a quality level of 4 or 5. Yes, the scale is arbitrary and subjective but it’s still useful.

If opinions vary strongly then you need to have a discussion about what you mean by quality, and where you want to be as a team. You can use Kent Beck’s 4 rules of Simple Code as a reference point. It’s hard to fix the problem if you can’t agree on where you want to be as a team.

What is the cause of this problem?

This is just a rhetorical question, because the answer is clear.

“Things are the way they are because they got that way!” -Jerry Weinberg

Crap gets into the code because programmers put it in! Let me make that crystal clear: Crappy Code is created by programmers. The programmer uses the actual keyboard to punch the actual code into the actual computer. Irregardless of other circumstances, it is the actions of the programmer that determine the quality of the code

The first step in solving technical debt, is to admit and accept this fact.

“but wait, we inherited a bunch of crappy legacy code. We did NOT write it!”

OK, fair enough. The relevant question in that case is: “is code quality improving or getting worse?” Rate that on a 5 point scale (where 1 is “getting worse fast”, 5 is “getting better fast”). Then reapply this article based on that question instead.

Why are we producing crappy code?

The answer will vary. However, I’ve asked it many times and I see some very strong trends.

It’s probably not because you WANT to write crappy code. I’ve never met a developer who likes writing crappy code.

It’s probably not because you don’t know HOW to write clean(ish) code. The skills will vary, but it’s enough that you have a few people in the team with good skills in writing clean code, and a willingness from everyone else to learn. Combine that with a habit of code review or pair programming, and most teams are perfectly capable of writing code that they would rate a 4 or a 5, if they take the time they need.

It may be because of broken window syndrome. Crappy code invites more crappy code, because people tend to adapt their new code to the quality of what’s already there (“when in Rome…”). Once you realize this, you can decide to simply Stop It, and introduce code review or pair programming to police yourselves.

However, the most probable reason for why you are writing crappy code is: Pressure.

I often hear comments like “we don’t have time to write clean code” (<rant>that statement is at worst a lie, at best a lame excuse</rant>). The truth is, you have 24 hours per day just like everyone else, and it’s up to you what you do with it. Face it. You do have time to write clean code, but you decided not to. Now let’s keep examining this concept of Pressure.

Where does pressure come from?

You might want to do a cause-effect analysis of this. Is the product owner pressuring you? Why? Who is pressuring the product owner? Who is pressuring the person who is pressuring the product owner? Draw the chain of pressure.

Then ask yourself. Is this pressure real? Do these people really want us to write crappy code? Do they know the consequence of crappy code (I bet you can list many), and do they really think it is worth it? Probably not. Go ahead, get on your feet and go ask.

Sometimes the cause of the pressure is the programmers themselves. Developing a feature almost always take longer than we think, and we really want to be a Good Programmer and make those stakeholders happy, so the pressure builds up from inside.

NOTE: sometimes there is business sense in writing crappy code.  Sometimes technical debt is Good. We may have a critically important short-term goal that we need to reach at all costs, or we may be building a throw-away prototype to quickly test the market. But that should be the exception, not the norm. If you clean up the mess you made as soon as the short-term goal is reached, or you actually throw away the throw-away prototype, then you won’t end up with a chronic case of Code Crapiness.

Shall we decide to stop this nonsense now?

This it the most important question.

If you are a programmer, the fact that you (as programmer) are responsible for the problem is actually Good News. Because that means you are perfectly capable of Solving the problem. And the solution is simple:

Stop Writing Crappy Code

(Just what the world needs – a new acronym: SWCC™)

“but but but but but…. we don’t have time… the PO bla bla bla, our release date bla bla”

No, spare me the excuses. Just Stop It.

Well OK, you might actually decide to continue writing crappy code. You might decide that this battle is not worth fighting. That’s your decision. If so, at least don’t call yourself an agile development team, and do challenge anyone else who thinks you are agile. One of the fundamental principles of Agile software development is Sustainable Pace. If you are consistently creating Crappy Code, development is going to get slower and slower over time. There is no business sense in this, and it is certainly not agile.

But assuming that you do want to stop, let’s explore what happens.

As a team of programmers, you can take a stand: “We Will Stop Writing Crappy Code”! Write it up on the wall. Shake hands on it. Add “no added technical debt” to your Definition of Done.

Tell the world, and the people who you believe are pressuring you into writing code: “We have been writing crappy code. Sorry about that. We’ll stop now.” Trying saying it loud. Feels good!

Stop Writing Crappy Code

Look at these two curves.

Yes, this is a simplification, but the difference is real. If you Keep Writing Crappy Code, you get slower and slower over time (as you spend more and more of your time wrestling the code). If you Stop Writing Crappy Code, you get a more sustainable pace. But there is velocity cost – you will slow down in the short term.

As team, you decide how much work to pull in – that pull-scheduling principle is fundamental to both Agile and Lean. It’s built into the agile methods. For example, in Scrum Sprint Planning the team chooses how many backlog items to pull into a sprint, same in XP Planning Game. In Kanban, the team has a work-in-progress limit and only pulls in the next item when the current one is Done. Basically, the team has full power and responsibility over quality. Use the power!

In concrete terms: If you are doing Scrum, and you’ve been delivering about 8-10 features per sprint, try reducing that. Only pull in 6 stories next sprint, despite any perceived pressure. Ask yourself at each sprint retrospective. “What is the quality of the code that we produced this sprint (scale 1-5)”. If it is less than 4-5, then pull in fewer stories next sprint. Keep doing that until you find your sustainable pace.

This has business implications of course. The product owner (or whatever you call the person who makes business priorities) will have to prioritize harder. She’s used to seeing 8-10 stories come out of each sprint. Now she will only see 6-7, so she needs to decide which stories NOT to build.

Yes, this will lead to arguments and tough discussions. The real source of pressure (if there was any) will reveal itself. Quality is invisible in the short term, and that needs to be explained. Take the battle! Stand by your decision. If programmers don’t take responsibility for the quality of their code, who will?

Code quality is not Product quality

Code isn’t everything. There’s more people involved in product development than just programmers. There’s business analysts, testers, managers, sysadmins, designers, operations, HR, janitors, and more.

Everyone involved is collectively responsible for the quality of the product being built. That includes not only the code, graphical design, database structure, and static artifacts like that. It includes the whole user experience as well as the business result of the product.

Code quality is a subset of product quality.  You can have great code, but still end up with a product that nobody wants to use because it solves the wrong problem.

What about vice versa – can you have a great product, but crappy code? I hate to admit it but, Yes, technically you can build a great product with crappy code. Somehow teams seem to get away with this sometimes. However, improving and maintaining the product is slow, costly, and painful, because the product is essentially rotten on the inside. It’s a lose-lose proposition and over time the best developers will leave.

What about the Old Crap (a.k.a Legacy Code)?

OK, so you’ve stopped writing crappy code. Congratulations! You’ve stopped accumulating technical debt. You’re still paying interest on your existing debt, but at least the debt has stopped growing.

Next step is to decide – can you live with the existing technical debt, or do you want to do something about it?  If you decide to reduce technical debt, the consequence is that you will slow down even further in the short term, but speed up over the long term. Like this:

Sometimes it’s worth it, sometimes not. The answer is not obvious, it’s a business decision, so make sure you involve the people who are paying for it.

If you decide to reduce your current technical debt, make that a clear decision: “We will Stop Writing Crappy Code, and Gradually Clean Up The Old Code”.

Once you agree on this (and that’s the hard part), there are plenty of techniques for how to do it. Here are two techniques that I’ve seen work particularly well:

  1. Add to your Definition of Done: “Technical debt reduced”. That means whenever you build a feature or touch the code, you leave the code in a better shape than you found it.  Maybe rename a method to make it more clear, or extract some duplicate code to a shared method. Small steps. But if the whole team (or even better, all teams) does this consistently, code quality will noticeably improve within a few months.
  2. For the larger cleanup areas, create a “tech backlog” & reserve time for it. For example, list the top 10 areas of improvement and commit to fixing one every week or sprint, before building any new features.

Just keep in mind that, however you do it, repaying technical debt means Fewer Features in the short term. Adapt your velocity forecasts and release plans accordingly. Just like any investment, there is a short-term cost. Make sure everyone is clear on that.

You need to Slow Down in order to Speed Up.

Final words

Bottom line: code quality is the responsibility of the people who actually write the code (otherwise known as Programmers).

As programmer, you own the problem, and you own the solution. There’s no need to fret or be ashamed of the past. Instead, stand proud and use your power to do something about it – make a loud decision toStop Writing Crappy Code. That will start a chain of events and Good Stuff will likely follow in the long term. It’s hard and it takes courage, but I don’t know any other way to solve technical debt.

Good luck!



Is technical debt always bad?

No. Having some debt can be fine. See my other article Good and Bad Technical Debt (and how TDD helps).

The problem I’m talking about here is chronic, out-of-control, continuously growing debt. I’ve seen so many companies drowning in technical debt, moving painfully slow, losing key developers, and regretting bitterly that they didn’t take code quality seriously from the beginning because it’s so much more expensive to fix it afterwards. Cutting quality gives short term benefits, but the long term is longer than the short term, and most companies do want to survive in the long term.

What is technical debt anyway?

Anything about your code & development environment that slows you down. For example:

  • Unclear, unreadable code.
  • Lack of test automation, build automation, deployment automation, and anything else that could be automated that you do manually today.
  • Duplicate code.
  • Tangled architecture & unnecessarily complex dependencies.
  • Slow, ineffective tools.
  • Uncommitted code & long-lived branches (hides problems that will slow you down later).
  • Important technical documentation that is missing or out-of-date.
  • Unnecessary technical documentation that is being maintained and kept up-to-date.
  • Lack of test environments.
  • Long build-test cycle & lack of continuous integration.

Technical Debt và Legacy System

Technical debt – tạm dịch là “Khoản nợ kỹ thuật” được dùng nhiều trong Software Engineering. Theo Henrik Kniberg, những khoản nợ kỹ thuật là bất cứ thứ gì trong việc viết mã khiến bạn chậm lại về lâu dài. Ví dụ như là mã khó đọc, thiếu (hoặc không có) kiểm thử tự động, mã trùng lặp, hoặc sự liên kết lằng nhằng giữa lớp, mô-đun… (Think of technical debt as anything about your code that slows you down over the long term. Hard-to-read code, lack of test automation, duplication, tangled dependencies, etc. Henrik Kniberg).


Cũng giống như những khoản nợ về tài chính: có vay mới có nợ, có nợ ắt sẽ sinh lãi. Technical debt sinh ra vì nhiều lý do: áp lực kinh doanh, thiếu kỹ năng trong phân tích thiết kế cũng như kỹ năng lập trình, không có các bộ mã kiểm thử dẫn đến việc trì hoãn (hoặc không thể) tái cấu trúc lại mã nguồn… Nếu không được trả, theo thời gian, nợ sẽ đẻ lãi, dẫn đến việc chậm tiến độ, những đoạn mã mới được thêm vào sẽ mất nhiều thời gian và chi phí hơn, mà đa phần trong số đó là chi phí cho việc gỡ rối (debugging) và kiểm thử hồi quy (regression testing).


Nếu bạn đang làm việc với 1 legacy system (có rất nhiều định nghĩa về legacy code, nhưng mình thích nhất định nghĩa của Robert C. Martin: legacy code = code without test) nghĩa là bạn đang mang trên mình món nợ về kỹ thuật. Một đoạn mã được viết cách đây 10 năm cũng gọi là legacy code, một đoạn mã được viết ngày hôm qua cũng gọi là legacy code nếu chúng đều không được “chống lưng” bằng mã kiểm thử. Và nếu bạn vẫn tiếp tục tạo ra những đoạn mã “without test”, cũng tức là bạn đang tự đẻ thêm nợ cho chính system của mình. Điều đó cũng giống như việc bạn thêm vào những đoạn mã khó đọc, mã trùng lặp, hoặc sự kiên kết lằng nhằng giữa lớp, mô-đun… (Có phải mình cũng vừa lặp lại những gì đã nói ở trên?).

Vậy bạn sẽ trả nợ bằng cách nào? Hay thõa hiệp trước món nợ + lãi đang ngày một tăng khi mã mới được thêm vào?
Có hàng tá lý do để biện minh cho việc thõa hiệp, có thể kể ra như: đừng phá vỡ những đoạn mã đã chạy ổn định, hệ thống chúng ta quá phức tạp, do đó cần thêm thời gian để (tìm hiểu) thêm mới hoặc sữa chữa một đoạn mã nào đó (và đảm bảo không phá vỡ những đoạn mã hiện tại). Có một câu ví von khá hay về vấn đề này. “The code may not be pretty, but damnit, it works!” dùng để nói về Duct Tap Programmer – người viết mã chỉ để “chạy được”.
Nếu chọn cách trả nợ, những việc bạn sẽ làm là đừng (hoặc hạn chế) để lại nợ nần cho những thế hệ (mã) phía sau. Và điều đầu tiên đó là Hãy ngừng việc tạo ra những đoạn mã xấu (Stop writing crappy code).


TDD đã khó, TDD cho legacy system còn khó gấp bội. Bài viết dưới đây của Mark Levison bàn về việc những vấn đề gặp phải khi áp dụng TDD trong Legacy System, qua đó trích dẫn 1 số phương pháp của Keith Ray – XP Coach để làm việc với legacy code nhằm giảm (paying down) những khoản technical debt, dựa trên nền tảng cốt lõi là viết mã sạch, tái cấu trúc mã nguồn và bỏ túi SOLID principles.

Xin trích dẫn nguyên văn bài viết bởi Mark Levison từ http://www.infoq.com/news/2009/11/legacy-code

Allan Baljeu was trying to TDD with a legacy C++ code base, he was running into trouble because:

we end up with classes that don’t fully implement the functionality that’s eventually needed, and when others come around to use those classes, and eventually fuller implementations are required, then it turns out that the original design is not adequate, a new design is required, some expectations (tests) need to change and previous uses of the class need to be updated.

He wondered if Big Design Up Front would help solve the problem. George Dinwiddie, Agile Coach, suggested that Alan’s design was trying to tell him something. You have to pay attention to the fundamentals of clean code. You can look at basic coupling and cohesion (i.e. SOLID).

Mike “Geepaw” Hill, Agile Coach, says that in his years of coaching agile teams, one of the following has been at the root of these problems:

  • team is not yet up to speed on refactoring, so your classes aren’t really
  • team is not yet skilled at simplicity, so ditto
  • team is not yet doing aggressive & rapid microtesting (aka unit testing), so changes break tests too often
  • team doesn’t know how to handle cross-team or company-to-public dependencies, e.g. shipping api’s
  • team neither pairing nor open workspacing, dramatically slowing team-wide understanding.
  • team likely has no jiggle-less build
  • team could be using tools from the ’40s

Keith Ray, XP Coach, suggests that with legacy code (i.e. systems with high technical debt) the cost of repaying technical debt dominates the cost of implementing a story. He goes on to offer an approach:

To make the code more well-factored (paying down the technical debt), whenever you need to integrate a new feature into it, you should pay close attention to code smells in both the new code and the old code and consider refactoring to deal with each smell as you recognize it.

You can do refactorings in small safe steps (even in C++) manually. Very closely follow the instructions in Fowler’s book on Refactoring until you learn them by heart. Eclipse with gcc has a few refactorings that actually work: Extract Method and Rename. Rename understands scope, so it is safer than search-and-replace. Extract Method and the other refactorings in Ecipse might be buggy, so be careful when you use them. For things like changing a function signature, “lean on the compiler” to show where changes have to be made.

You also need tests to make sure the refactorings are not damaging the existing features. Feather’s book on working with legacy code has lots of techniques for adding tests to legacy code. On a higher level, code smells are violations of good design principles. For example, the Single Responsibility Principle (SRP) says there should one purpose for every class / method / module. There are principles about coupling and cohesion and managing dependencies, etc. It’s often easier to detect a code smell than it is to apply these abstract principles. “Large Class” and “Large Method” are remedied by “Extract Class” and “Extract Method/Move Method”, though knowing SRP helps in deciding what parts of a class or method should be extracted.

Perhaps the most important design principle is “Tell, don’t ask”: keep functionality and data together…. bad code often has the functionality in one place, and gets the data it needs from other places, creating problems with dependencies and lack of locality — symptomized by “adding a new feature requires changing lots of code”. The code smells “Shotgun Surgery”, “Feature Envy”, “Long Parameter List” are applicable here.

Getting fast feedback will allow more refactoring, which will (eventually) allow faster development of new features. Try to get parallel builds happening (distributed compilation). Try to get smaller source files and smaller header files. Reduce the complexity of header files – use forward declarations, avoid inline code, try to keep only one class per header file / source file. Using the “pimpl” idiom widely can decrease compile time by 10%, but it can also disguise the “Large Class” and “Feature Envy” code smells.

The advantage of refactoring instead of rewriting, is that you always have working code. If your manual and automated tests are good, then you should be able to ship the code, even if it is a half-way state between a bad design and a good design.

Keith also wrote “Refactoring: Small Steps Guaranteed to Help You Clean Up Your Code” an article on refactoring C++ code in Better Software Magazine.

Previously on InfoQ: Dealing with Legacy Code, Uncle Bob On The Applicability Of TDD andMaking TDD Stick: Problems and Solutions for Adopters

Git Is Simpler Than You Think

By Nick Farina


It was about one year ago that we switched to Git. Previously, we used Subversion, through the Mac app Versions, which (rightly) holds an Apple Design Award.

I made the executive decision to leave our comfy world of Versions because it seemed clear that Git was winning the Internet. There was much grumbling from my teammates, who were busy enough doing actual work thank you very much.

But I pressed forward. We signed up for accounts on Github. We learned how to type 'git push' and 'git pull'. We became more confident. Git is just like any other source control system! But it wasn’t long before one of our devs called me over to look at a…situation.

It might as well have printed PC LOAD LETTER. “Falling back to patching base and 3-way merge?” That does not sound good at all. Or maybe it’s completely normal? I type 'git status'.

“Not currently on any branch?!” Now I’ve done it. We’re going to lose all the work he did today. Sweat is beading up on my forehead. Everyone is watching me to see if I can figure this out. After all, I got us into this mess.

Maintenance Required

Git is not a Prius. Git is a Model T. Its plumbing and wiring sticks out all over the place. You have to be a mechanic to operate it successfully or you’ll be stuck on the side of the road when it breaks down. And it willbreak down.

By now we all know how to drive Git. We learned it by typing “git tutorial” into Google. We studied guides, how-tos, cheat sheets.

Did you know the top result for “git tutorial” is this manpage on kernel.org? I will give you a gold star if you can read the whole thing without falling asleep.

So instead let’s pull over, open the hood up, and poke around.

The Basics

We’ll run through some basic commands to make a repository for our examples:

~$ mkdir mysite
~$ cd mysite
~/mysite$ echo "<title>All About Cats</title>" > index.html
~/mysite$ git init
~/mysite$ git add index.html
~/mysite$ git commit -m "First commit, added a title."

Now we have a git repository with one file and one commit, that is to say, one “version”. Let’s make a change and commit a second “version”:

~/mysite$ echo "<center>Cats are cute.</center>" >> index.html
~/mysite$ git commit -a -m "Added some text."
~/mysite$ open index.html 

With me so far? Good.

The Repository

In Git there is no “client” and “server”. A repository is a repository, no matter if it’s on my machine, your machine, or Github.com.

Each repository lives in a single hidden folder called .git. This is in stark contrast to Subversion which infects your source tree with little.svn folders everywhere.

The .git “repository” is more than just metadata and bookkeeping. It’severything. All of your source, all your changes, all your branches, all your commit notes with swear words and in-jokes.

Go ahead, delete your index.html. As long as your .git folder is intact, you can reconstruct it:

~/mysite$ rm index.html
~/mysite$ git checkout -- .
~/mysite$ ls

That would work even if you’d deleted a bunch of subfolders and huge files and whatever. Poof, it’s all back.

This explains why, when you “checkout” (clone) the Ruby on Railsrepository from Github, it takes a surprisingly long time. You’re downloading onto your machine, into your new rails/.git folder, the entire history of Ruby on Rails. Every tiny change from David’s initial commit in 2004, it’s all sitting there on your disk.

This troubled me greatly at first. It’s so inefficient! My precious disk space!

And I can only say that disk space turned out to be a non-issue. But it took me some time. Maybe go take a walk outside, look at some trees, and come back later when you’ve accepted it.

User Interface

Now if you’re a curious person, you’ll likely say “Wait. Go back. Where did you get the line ’git checkout -- .’ from? What does that evenmean?”

To which I’ll respond, “I don’t know. I Googled it.”

And this brings us to Git’s greatest shortcoming, which is that Git’s terminology and syntax is fracking inscrutable.

Git’s overloaded, confusing language is absolutely the only part of it that sucks. They meant well. They chose words that sound familiar, likebranch, checkout, tag, merge. But they often mean different things. Then you get the feeling that, as features were added and rethought, they just picked new unused words as they went along. Stage, fetch, rebase,remotes.

And because of Git’s explosive popularity, it’s a total Emperor-Has-No-Clothes situation. If you’re anything like me, you probably wondered why you were the only stupid person on the planet who didn’t intuitively get Git already. Even the beloved Github, though unaffiliated with Git, is much the same: as overwhelming as it is awesome.

Ultimately, when you look at Git, you don’t see a product that was “designed” holistically. It’s more like a collection of command-line utilities.

A Collection of Command-Line Utilities

This is a much better way to think about Git, and in fact this is what Git originally was. Git started life as a week-long project of Linus Torvalds to replace the old version control system they were using at the time to manage contributions to the Linux kernel.

You can’t design and build a fully-featured distributed version control system in a week. But you can design your data model. And it had better be really, really simple.

So what’s Git’s data model? To answer that, we need to dig into that mysterious .git folder.

The So-Called “Object Database”

In mysite/.git, there is a subfolder called objects. It should contain these folders and files (edited for clarity):

~/mysite $ find .

These files with mangled-looking names are the “objects” in our database for mysite. An object can be either a commit, a tree, a blob, or atag. They’re compressed with zlib, but you can extract and examine them easily.

If we were to extract the object 23/5810…, we would see:

<title>All About Cats</title>

…which is the old version of index.html! So that’s a blob, that is, a particular version of one file. If we extract the object 0d/0321…, we get:

commit 227tree 5b853962ae2f41f608428968f8fffbf72f6cec2b
parent b1a701e38645a3e60bc17a786cdd9062a15b5a21
author Nick Farina <n...@gmail.com> 1315106589 -0700
committer Nick Farina <n...@gmail.com> 1315106589 -0700

Added some text.

…which is a commit object (our last commit).

If you’re following along, you’ll notice that you don’t have an object0d/0321. Your commit will have a different mangled name because your author name and email won’t match mine. You see, the “mangled names” of these files are SHA1 Hashes of their contents. If we computed the hash of the blob <title>All About Cats</title>, we’d get:


Recognize that hash from the 23/5810… filename above? Git chops off the first 2 characters of the hash and uses that as a directory name, so we don’t end up with too many of these little files in one place.

Git calls this “content-addressable” to sound fancy, but really it’s just a naming scheme. See, these “objects” have to be called something, so they might as well be named according to their contents.


Now if you’re reasonably paranoid, you may ask: “What if two different objects compute the same SHA1 hash code? Won’t this happen someday?”

It turns out you’ll never generate two of the same SHA1 hashes. The chances are miniscule. There’s room for all kinds of flowery comparisons like: You’d have to generate more hash codes than the number of stars in the universe before you’d get two of the same!

But my favorite is from Pro Git: “A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night.”


A commit represents a complete version of your code. Look again at the object file representing our last commit:

commit 227tree 5b853962ae2f41f608428968f8fffbf72f6cec2b
parent b1a701e38645a3e60bc17a786cdd9062a15b5a21
author Nick Farina <n...@gmail.com> 1315106589 -0700
committer Nick Farina <n...@gmail.com> 1315106589 -0700

Added some text.

This chunk of text contains enough hints to reconstruct the entire contents and history of our repository as it existed in this version.

The hash 5b8539… is the object containing the state of our tree. A tree object is basically a manifest of files and folders (simplified here):

blob 2d48a74575acab21d702f17f4ecce126b7e34ab0  index.html
blob b8ca7d5cba87d5123182375871234a76d6f78ff2  someotherfile.html  <- example 2nd blob
tree 3182375871234a76d6f78ff2b8ca7d5cba87d512  Documentation       <- example subfolder

This represents the filesystem structure at this point in time. Cleverly, subfolders are represented by pointers to other tree objects. Recursion! The “blob objects” then contain the actual file data like <title>All About Cats</title>.

To get the previous version of our repository, look at the “parent” hash beginning with b1a701 (again, different for you). This is the object containing the previous commit.

So just by starting with our last commit object, we’ve explored the entire contents of our repository.


If we had a thousand objects in our database, it would be pretty hard to guess the hash of our last commit. So we’d better write it down somewhere.

~/mysite$ cat .git/refs/heads/master

This is what a branch is: it’s simply the hash of the last commit scribbled down in a file. It’s a clue, a starting point, sometimes called atip because this represents the tip of the iceberg that is the entire history of the master branch.

And since you can have multiple branches in a repository, we should also remember which one we’re working on right now.

~/mysite$ cat .git/HEAD
ref: refs/heads/master

It’s forehead-slapping simple. Whenever you execute a Git command, it first looks at .git/HEAD to see what our working copy is supposed to be. And that contains a reference to either a branch name or a commit object (that case is a detached HEAD). If it’s a branch name, look at the branch file to see what commit object it is. Then open up the commit object to find all the trees and blobs and parents and it’s turtles all the way down.


One last thing to ponder. Our objects folder contains 6 files. Three for the first version’s commit object, tree, and blob. And three again for the last version’s commit object, tree, and blob.

If you zipped up your entire mysite folder right now and emailed it to me, I could unzip it and make another change to index.html and commit that change to my local copy on disk. Let’s say I changed the line to say<center>Cats are TERRIBLY cute.</center>.

Now I have 9 files in my objects folder. Three more for the commit I just made, its tree and blob.

I want to share my changes with you. So I zip up the 3 object files you don’t have and email them to you.

Are you ready for this? You take my three object files and just dump them into your objects folder. You don’t have to worry at all about overwriting anything, about losing data, about screwing up your repository, because we’ve already established that these file names arecompletely unique. Wolves in the night, remember?

You’ve just manually performed a git fetch, which is the safest operation ever because it’s just collecting someone else’s unique commit files and tossing them into to your database.

In my email, I’ll say “My latest commit is 3bd54c.” So you type “git checkout 3bd54c” and boom you’re looking at my latest changes.

If we emailed back and forth a lot, I might want to add you as a remoteso that Git does the moving of files around for me. And I might scribble down the latest commit hash that I got from you in a file calledorigin/master or something. Sound familiar?


Octobi Wan Catnobi by

For me, understanding the structure of the object database was my Eureka moment for Git. After that, I could start to understand not just how Git worked, but why.

The best way to get yourself out of a Git disaster scenario is to understand what Git is trying to do for you.

And when you understand how Git works, your Google Power will increase tenfold. How did I know to type “git checkout -- .”? Well I just looked online until I found a command that sounded like it did what I would do myself if I had to write some code to poke around the object database.

There’s a lot more to grok about Git from here. Merging, rebasing, and staging come to mind. But it’s not so hard now; it’s all just a bunch of fancy shell scripts anyway.

Những nguyên tắc, những định luật của lập trình mà chúng ta nên có sẵn trong đầu

Nguồn : http://qiita.com/hirokidaichi/items/d6c473d8011bd9330e63

Người dịch : Phan Hoàng Minh (https://viblo.asia/minhp/posts/wpVYRP2kG4ng)


Nguyên tắc Demeter

Còn có tên gọi khác là nguyên tắc “càng biết ít càng tốt”.

Demeter là tên gọi của Nữ thần nông nghiệp, cũng là nữ thần phân phát trong thần thoại Hi Lạp. Tên bà được dùng để đánh dấu sự ra đời của nguyên tắc này, đây có thể xem là một triết lý nền tảng của việc lập trình được sinh ra từ một aspect-oriented programming (AOP) project cùng tên.

Quan điểm cơ bản của nguyên tắc này chính là : tối giản sự hiểu biết của 1 object về cấu trúc, thuộc tính của các object khác ngoài nó (bao gồm các thành phần con).


Nói một cách đơn giản là không được tiếp xúc với thuộc tính, method của các object khác một cách trực tiếp.

#Vi phạm nguyên tắc Demeter

#Không vi phạm nguyên tắc Demeter

Định luật Wirth

“Software gets slower faster than hardware gets faster” – “Tốc độ tiến hóa của phần cứng không bằng tốc độ thoái hóa của phần mềm.”


Có lẽ ý chính của nó là : lập trình ngày càng dùng nhiều tài nguyên phong phú nên framework phải luôn tiến hóa để phục vụ cho việc đó. Suy ra, tốc độ phần cứng dù có tang lên đi nữa thì tốc độ phần mềm cũng chẳng hề thay đổi gì.

Định luật Brook

Đây là một định luật dựa trên kinh nghiệm thực tế : “Đưa thêm người vào 1 project đang chậm, sẽ chỉ khiến nó càng chậm hơn.”

Hay có thể nói theo một cách khác nữa là “Tập hợp 9 bà bầu lại cũng không thể khiến đứa trẻ ra đời sau 1 tháng.”

Luận thuyết cơ bản của định luật này là

  • Cần thời gian để quen với project
  • Công sức dành cho việc communication sẽ tăng


Định luật Conway

“Organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.”

“Một công ty thiết kế hệ thống thế nào cũng sẽ làm ra những thiết kế giống y hệt với thiết kế hệ thống của chính công ty họ.”


Nghiên cứu gần đây chỉ ra rằng hệ thống của công ty là nhân tố ảnh hưởng lớn nhất đến vấn đề phát sinh ra bug của sản phẩm.


Nguyên tắc bất ngờ nhỏ nhất (least astonishment)

Trong trường hợp trên cùng 1 interface có 2 yếu tố hành xử mâu thuẫn với nhau, hoặc cách hành xử không rõ ràng thì cần phải chọn cách hành xử nào gây bất ngờ ít nhất cho người sử dụng.


Đây là 1 nguyên tắc về giao diện người dùng.

Một ví dụ đơn giản :

Trên 1 interface có 2 chức năng :

  • Ấn ctrl+Q để thoát chương trình.
  • Nhập macro (lưu 1 tổ hợp phím mang 1 chức năng nào đó để tiện cho việc sử dụng về sau).

Sẽ có trường hợp user muốn dùng Ctrl+Q cho macro của mình, nên hành xử đúng với nguyên tắc bất ngờ nhỏ nhất chính là : trong khi nhập macro thì ctrl+Q được coi như là tổ hợp phím bình thường, không phải là lệnh tắt chương trình. Đây chính là điều gây bất ngờ ít nhất cho người dùng.

Nguyên tắc Boy Scout

Nguyên tắc của các tổ chức Boy scout chính là : lúc đi phải sạch đẹp hơn lúc đến.

Trong lĩnh vực lập trình thì nguyên tắc đó sẽ được hiểu là “Khi bạn checkin 1 module thì lúc đó nó phải đẹp hơn lúc bạn checkout.”

Nguyên tắc YAGNI

Viết tắt của “You ain’t gonna need it” – Cái (chức năng, phần) ấy rồi sẽ không cần thiết.

Đó là một câu khẩu ngữ nhắc nhở người lập trình rằng trong quy trình eXtreme Programming (lập trình cực hạn) thì : “Chưa phải lúc cần thiết thì chưa được phép làm.”

Nguyên tắc DRY

Viết tắt của “Don’t repeat yourself” – với ý nghĩa là “Đừng lặp lại những gì giống nhau”.


Khi nguyên tắc này được áp dụng tốt, dù ta có thay đổi 1 phần thì những phần không liên quan cũng sẽ không bị thay đổi theo. Hơn nữa, những phần có liên quan sẽ được thay đổi cùng 1 lượt, giúp ích rất nhiều cho cả khâu estimate và khâu thực hiện.

Nguyên tắc KISS

Viết tắt của “Keep it simple, stupid” – “Cứ đơn giản thôi, đồ ngu!”. Đây là 1 triết lí của Hải quân Mỹ.


Những triết lý tương tự có thể kể đến là :

Phương châm dao cạo Okham (Okham’s razor) – “Không đưa ra nhiều giả thiết nếu không cần thiết. Cái gì cần ít giả thiết để chứng minh sẽ không thể chứng minh được bằng nhiều giả thiết.”

Albert Einstein – “Làm cái gì cũng nên đơn giản nhất có thể, nhưng đơn giản quá thì không được”.

Leonardo da Vinci – “Đơn giản nhất chính là tinh xảo nhất”.

Antoine de Saint- Exupéry – “Hoàn hảo, không phải là không thêm vào được nữa, mà là không thể bớt đi được nữa”.

Nguyên tắc SOLID

Tập hợp những nguyên tắc trong lập trình hướng đối tượng. Các chữ cái đầu hợp lại thành SOLID.


SRP (Single Responsibility Principle) – “Một class chỉ được có 1 nhiệm vụ” hay nói cách khác, “nếu muốn chỉnh sửa class thì chỉ được phép có 1 và chỉ 1 lý do”.

OCP (Open/closed principle) – “Mở class khi cần mở rộng nó, đóng class khi cần chỉnh sửa nó”.

LSP (Liskov substitution principle) – “Subtype phải luôn có thể được thay thế bằng supertype”.

ISP (Interface segregation principle) – “Việc dùng nhiều interface cho các client khác nhau, tốt hơn là việc chỉ dùng 1 interface cho cùng lúc nhiều mục đích” hay nói cách khác “Không được phép hạn chế access vào những method mà client không sử dụng”.

DIP (Dependency inversion principle) – “Module tầng trên không được phụ thuộc vào module tầng dưới. Bất cứ module nào cũng phải phụ thuộc vào cái trừu tượng, không phải vào cái cụ thể”.


From https://viblo.asia/Thanh/posts/3ZabG9A5GzY6

By Thanh

I. Khái lược về Scrum


Scrum cơ bản là bộ khung làm việc (framework) hay có thể hiểu nôm na là cách thức làm việc để trở nên “linh hoạt” trong phát triển phần mềm.

Scrum là khung làm việc được sử dụng để quản lý quá trình phát triển các sản phẩm phức tạp. Scrum không phải là một quy trình hay một kĩ thuật cụ thể để xây dựng sản phẩm; hơn thế, nó là một khung làm việc cho phép ta sử dụng nhiều quy trình và kĩ thuật khác nhau. Scrum làm rõ hiệu quả của công tác quản lý và phát triển sản phẩm, từ đó cho phép ta cải tiến nó.

2.Scrum có các tính chất:

  • Scrum (hay agile nói chung) được xếp vào nhóm “Feature-driven development“. Sản phầm được phát triển theo tính năng, chứ không phát triển sản phẩm theo kiến trúc hệ thống.
  • Scrum khác với các mô hình Agile khác ở chỗ nó là mô hình hướng khách hàng (Customer oriented), vai trò của khách hàng trong việc đánh giá sản phẩm rất quan trọng. Chỉ sau mỗi sprint (2-4 tuần) khách hàng sẽ thấy được sự thay đổi của sản phẩm của mình qua đó đưa ra phản hồi sớm để định hướng.
  • Scrum giảm thiểu tài nguyên dành cho việc quản lý mà tập trung nhiều hơn cho những công việc liên quan trực tiếp đến việc làm ra sản phẩm. Bằng cách giảm vai trò quản lý (PM) bằng cách đẩy việc quản lý tới từng người
  • Giảm thời gian dành cho việc viết tài liệu bằng cách tăng thời gian trao đổi trực tiếp. Thông thường khi estimate công việc, thì team estimate cả thời gian dành cho communication để hoàn thành task đó nữa.

Khung làm việc Scrum bao gồm một Nhóm Scrum với các vai trò được phân định rõ ràng, các sự kiện và các quy tắc. Mỗi thành phần trong khung làm việc phục vụ một mục đích rõ ràng và là nòng cốt trong việc sử dụng cũng như thành công của Scrum.


3.Vai trò trong Scrum

Trong Scrum có 3 vai trò: Chủ sản phẩm (Product Owner), Nhóm phát triển, và Scrum Master. Trong Scrum sẽ không có vai trò Quản lý dự án (Project manager) hay Trưởng nhóm kỹ thuật (Technical lead)

  • Product Owner: Là người chịu trách nhiệm cao nhất đối với sản phẩm và nhóm phát triển. Chủ sản phẩm có trách nhiệm làm việc với chủ đầu tư để hiểu yêu cầu về sản phẩm, quản lý những yêu cầu đó, tạo ra những “câu chuyện người dùng” đối với sản phẩm và truyền đạt những thông tin đó đến đội phát triển. Cơ bản là nếu nhóm gặp những vấn đề hay thắc mắc gì liên quan đến sản phẩm, hãy tìm gặp Product Owner.
  • Nhóm phát triển: Là một tập hợp những kỹ sư “liên chức năng”- nghĩa là công việc của họ không cố định ở lập trình, kiểm thử, phân tích hay thiết kế. Tùy theo yêu cầu công việc mà họ sẽ đảm nhận những vai trò tương ứng. Nhóm phát triển được quyền chủ động tổ chức công việc, ước lượng khối lượng công việc và cam kết hoàn thành công việc đã cam kết. Trong Sprint, nhóm phát triển có tiếng nói lớn nhất và những bộ phận khác có nhiệm vụ hỗ trợ những điều kiện tốt nhất để nhóm làm việc hiệu quả
  • Scrum Master: Nhiệm vụ của Scrum Master là giúp mọi người trong nhóm hiểu được Scrum, làm theo Scrum đồng thời hỗ trợ nhóm phát triển để họ có thể toàn tâm toàn ý làm việc. Vừa giống ông chủ vừa giống osin, kiểu vậy. Nếu có ai đó thắc mắc về quy trình trong Scrum, ý nghĩa của Scrum hay những vấn đề liên quan đến Scrum khác, hãy tìm gặp Scrum Master.Image

II. Scrumban là gì?

Scrum là giải pháp tốt nhất cho product và phát triển project. Kanban là giải pháp tốt nhất để hỗ trợ sản xuất. Scrumban là sự kết hợp của Scrum, Kanban và bao gồm toàn bộ những ưu điểm của cả 2 phương thức trên. Nó khuyến khích các đội phải liên tục cải tiến quy trình cùng với phương thức Kanban.

Scrumban được giới thiệu như một quy trình đơn giản để quản lý những project phức tạp. Hiện nay Scrumban được áp dụng tốt nhất khi phát triển trên web, software development hoặc maintenance.


  • Chia công việc thành những list nhỏ, phân tách nhỏ để bàn giao. Sắp xếp danh sách này theo thứ tự ưu tiên và ước lượng tương đối thời gian, công sức bỏ ra cho mỗi item.
  • Chia thời gian thành những khoảng thời gian ngắn, lặp lại thường là từ 1-4 tuần, với khả năng có thể bàn giao code sau mỗi một chu trình.
  • Dựa trên những hiểu biết đã đạt được bằng cách kiểm tra các phiên bản sau mỗi lần lặp, tối ưu hóa các kế hoạch bàn giao và bản cập nhật ưu tiên trong hợp tác với các khách hàng.
  • Đánh giá quy trình bằng cách nhìn lại những gì đã làm sau mỗi chu trình.


Quy trình làm việc

  • Chia công việc thành những phần nhỏ, viết mỗi phần vào một miếng giấy note và dán lên tường
  • Sử dụng tên cột để minh họa vị trí của mỗi item trong quy trình làm việc
  • Giới hạn công việc trong sự phát triển(WIP): Phân công rõ ràng giới hạn cho bao nhiêu item có thể được thực hiện ở mỗi workflow.
  • Ước lượng thời gian quản lý (thời gian trung bình để hoàn thành một item, đôi khi gọi là “cycle time”) và đánh giá quy trình để lập thời gian quản lý sao cho nhỏ nhất và có thể dự đoán.

3.Quy trình làm việc

Kết quả trực tiếp của sự khác biệt này trong các quy tắc là cách mà các work item được xử lý theo thời gian

Trong Scrum, bạn lựa chọn những việc mà bạn sẽ sẵn sàng làm cho sprint sau.

Làm lần lượt theo thứ tự, làm tất cả mọi việc mỗi sprint trong một vài tuần (khoảng thời gian thông thường cho sprint) và chuyển chúng sang trạng thái hoàn thành (cột Done) thì cuối cùng sẽ xử lý hết những sprint còn ở trạng thái chờ


Ở Kanban, bị giới hạn bởi kích thước của hàng đợi, gọi là giới hạn WIP. Điều này có nghĩa là bạn có thế thay đổi items ở hàng đợi bất cứ lúc nào, và không có kết thúc sprint


4.Scrumban = Scrum + Kanban

Sử dụng quy tắc tự nhiên của Scrum là Agile

Sử dụng quy trình phát triển của Kanban để team có thể tiếp tục cải tiến quy trình

Trong Scrumban, chúng ta có thể lập những kế hoạch lặp lại trong những khoảng thời gian đều đặn, đồng bộ với việc đánh giá và có thể xem lại những gì đã làm. Điều này làm giảm đáng kể chi phí.


Lợi ích

  • Chất lượng
  • Đúng thời gian
  • Thời gian quản lý ngắn
  • Tiếp tục cải tiến
  • Ít rủi ro, giảm lãng phí
  • Có thể thêm chức năng vào Scrum khi cần

Khi nào nên sử dụng Scrumban

  • Dự án bảo trì
  • Dự án mà thường xuyên có lỗi không mong đợi

Scrum – First thought

Ở những nơi không sử dụng Scrum hoặc thất bại trong việc áp dụng Scrum thì có hai điều cốt lõi sau:

– Thứ nhất, môi trường out source nên không tự chủ được trong sự linh động về việc phải “tung” sản phẩn của mình ra khi nào.

– Thứ hai, nếu là làm product thì tính cạnh tranh cũng không cao giữa các đối thủ, với tâm lý, nó làm rồi thì mình tìm cái khác để làm, cũng ít làm mô hình cổ phần doanh nghiệp, nên cũng chẳng vấp phải sự hối thúc từ HĐQT, nên cứ làm xong rồi demo luôn, rồi release luôn.



Scrum Framework, ảnh: Bas Vodde et al.

– Và thêm vài cái phụ nho nhỏ đó là thiếu tầm nhìn chiến lược từ phía khách hàng + nhà phát triển và lối mòn trong tư duy phát triển phần mềm theo kiểu hướng kiến trúc hệ thống, không rõ ràng sẽ không dám làm. Chính các điều này đã làm cho sức hút, sức mạnh về sự linh động của Scrum không được trân trọng.

Ngược lại với đó là các nước đang áp dụng rất thành công Scrum, đó là các nước Âu Mỹ, nơi mà Scrum – một framework (khung làm việc) chứ không phải là methodology (phương pháp luận) cho phép ta sử dụng nhiều quy trình và kĩ thuật khác nhau, vai trò của khách hàng trong việc đánh giá sản phẩm rất quan trọng. Chỉ sau mỗi sprint (2-4 tuần) khách hàng sẽ thấy được sự thay đổi của sản phẩm của mình qua đó đưa ra phản hồi sớm để định hướng, sự canh tranh cũng được nâng lên, bạn không cần có một phiên bản phần mềm hoàn hảo, nhưng chỉ cần đủ để nó tiếp cận và định hướng được thị trường đầu tiên.

Khi trực tiếp tham gia (hoặc chứng kiến) các nhóm làm việc dựa trên Scrum, bạn sẽ thấy được sự thay đổi, xoay vòng với tốc độ chóng mặt.

Đó là những cảm nhận đầu tiên về Scrum (hay Agile nói chung) đi từ hướng tiếp cận tại sao họ áp dụng Scrum thành công, còn mình thì không, chứ không phải từ suy nghĩ là làm thế nào để áp dụng nó. :)