Là DRY là kẻ thù của quản lý dự án phần mềm?


83

Một trong những nguyên tắc cơ bản nhất và được chấp nhận rộng rãi trong phát triển phần mềm là DRY (đừng lặp lại chính mình). Rõ ràng là hầu hết các dự án phần mềm đều yêu cầu một số loại quản lý.

Bây giờ các nhiệm vụ dễ quản lý (ước tính, lịch trình, kiểm soát) là gì? Đúng, các nhiệm vụ lặp đi lặp lại, chính xác các nhiệm vụ nên tránh theo DRY.

Vì vậy, từ góc độ quản lý dự án, thật tuyệt vời khi giải quyết một nhiệm vụ bằng cách sao chép một số mã hiện có 100 lần và thực hiện một số điều chỉnh nhỏ cho mỗi bản sao, theo yêu cầu. Tại mọi thời điểm, bạn biết chính xác bạn đã làm bao nhiêu công việc và còn lại bao nhiêu. Tất cả các nhà quản lý sẽ yêu bạn.

Nếu thay vào đó, bạn áp dụng nguyên tắc DRY và cố gắng tìm một sự trừu tượng hóa ít nhiều loại bỏ mã trùng lặp, mọi thứ sẽ khác. Thông thường có nhiều khả năng, bạn phải đưa ra quyết định, nghiên cứu, sáng tạo. Bạn có thể đưa ra một giải pháp tốt hơn trong thời gian ngắn hơn, nhưng bạn cũng có thể thất bại. Hầu hết thời gian, bạn thực sự không thể nói bao nhiêu công việc còn lại. Bạn là cơn ác mộng tồi tệ nhất của người quản lý dự án.

Tất nhiên tôi đang phóng đại, nhưng rõ ràng có một vấn đề nan giải. Câu hỏi của tôi là: các tiêu chí để quyết định nếu một nhà phát triển làm quá mức DRY là gì? Làm thế nào chúng ta có thể tìm thấy một sự thỏa hiệp tốt? Hoặc có cách nào để khắc phục hoàn toàn tình trạng khó xử này, không chỉ bằng cách tìm một sự thỏa hiệp?

Lưu ý: Câu hỏi này dựa trên cùng một ý tưởng như câu hỏi trước của tôi, Số lượng công việc thường xuyên trong phát triển phần mềm và ảnh hưởng của nó đến ước tính , nhưng tôi nghĩ rằng nó làm cho quan điểm của tôi rõ ràng hơn, rất xin lỗi vì đã lặp lại chính mình :).


96
Hãy cho chúng tôi biết cảm giác quản lý dự án của bạn cảm thấy như thế nào khi đến lúc săn lùng, thay đổi và kiểm tra một cái gì đó trong tất cả 100 trường hợp sao chép và dán. Và đừng quên thời gian bổ sung sẽ được sử dụng để tìm ra lý do tại sao nó bị hỏng vì chỉ có 98 người trong số họ thực sự đã thay đổi.
Blrfl

16
Mặt khác, @Blrfl, mã DRY sớm lên trước khi một sự trừu tượng tốt là rõ ràng thực sự có thể làm giảm năng suất, vì một sự trừu tượng được chia sẻ là một sự phụ thuộc được chia sẻ. Tôi không đồng ý, btw, chỉ ra rằng chắc chắn có một sự cân bằng được tìm thấy.
DêInTheMachine

16
Nguyên tắc ngăn DRY vượt khỏi tầm kiểm soát là nguyên tắc YAGNI (Bạn sẽ không cần nó) .
Philipp

88
Không có vấn đề nan giải. Nếu người quản lý dự án muốn bạn thực hiện nhiều công việc thủ công thừa vì dễ ước tính, thì giải pháp rõ ràng là sa thải người quản lý dự án.
JacquesB

10
Nếu bạn lặp lại chính mình, thì bạn vẫn phải làm tất cả những công việc khó ước tính khác , cộng với một số công việc vô nghĩa. Vậy làm thế nào để giúp dự án?
dùng253751

Câu trả lời:


134

Bạn dường như giả định mục tiêu chính của quản lý dự án là đưa ra các ước tính chính xác. Đây không phải là trường hợp. Mục tiêu chính của quản lý dự án cũng giống như đối với các nhà phát triển: Cung cấp giá trị cho chủ sở hữu sản phẩm.

Về mặt lý thuyết, một sản phẩm sử dụng nhiều quy trình thủ công chậm thay vì tự động hóa có thể dễ ước tính hơn (mặc dù tôi nghi ngờ về điều đó), nhưng nó không cung cấp giá trị đồng tiền cho khách hàng, vì vậy đơn giản là quản lý dự án kém. Không có vấn đề nan giải.

Người ta biết rằng việc ước tính các dự án phần mềm là khó khăn, và nhiều cuốn sách đã được viết và nhiều quy trình đã được phát triển để quản lý nó.

Nếu mục tiêu duy nhất của Thủ tướng là đưa ra các ước tính chính xác, thì nó sẽ dễ dàng. Chỉ cần ước tính 10X và để các nhà phát triển chơi trò chơi cho phần còn lại nếu họ hoàn thành sớm. Điều này thực sự sẽ tốt hơn so với đề xuất của bạn về việc sử dụng công việc bận rộn sao chép để giảm thời gian, vì chơi trò chơi sẽ không làm giảm khả năng bảo trì của sản phẩm.

Nhưng trong thực tế, chủ sở hữu sản phẩm muốn ước tính hữu ích một sản phẩm chất lượng được giao nhanh nhất và rẻ nhất có thể. Đây là những hạn chế thực tế mà một PM sẽ phải điều hướng.

Trong mọi trường hợp, tôi tranh chấp giả định của bạn rằng công việc thủ công lặp đi lặp lại có thể dự đoán được nhiều hơn so với tự động. Tất cả kinh nghiệm cho thấy rằng công việc thủ công lặp đi lặp lại là hơn dễ bị lỗi. Và nếu một lỗi được phát hiện trong mã dán sao chép thì sao? Đột nhiên, chi phí sửa lỗi được nhân lên với số lần lặp lại, khiến cho sự không chắc chắn bùng nổ.


21
Tôi hoàn toàn đồng ý với các xác nhận của bạn ở đây nhưng tôi nghĩ cần lưu ý rằng có rất nhiều nhà quản lý dự án tệ hại ngoài kia thực sự thích dự đoán hơn tốc độ hoặc chất lượng. Hầu hết những người không được đào tạo về quản lý dự án đều học những gì họ biết về nó từ những gì họ đã thấy và kinh nghiệm của tôi là các nhà quản lý dự án có thể đối phó với sự không chắc chắn theo cách hợp lý bình tĩnh là rất ít.
JimmyJames

5
@FrankPuffer Tôi đã ở đó. Làm cái đó mất bao lâu? Một lựa chọn ở đây là cung cấp một phạm vi. Đọc về PERT cụ thể về các ước tính 3 điểm vì họ đã biết về điều đó rồi. Tỷ lệ hoàn thành? Đây là điều khó chịu nhất. Cố gắng bỏ qua nhưng nếu bạn không thể nhớ rằng đó là phần trăm thời gian, không phải phần trăm dòng được mã hóa hoặc bất cứ điều gì. Những gì họ thực sự muốn biết là khi nào nó sẽ được hoàn thành? Ngay từ sớm, hãy đưa ra dự đoán thận trọng về từng nhiệm vụ và tinh chỉnh khi bạn đi. Chờ đến phút cuối để nói bạn thêm thời gian sẽ khiến mọi người phát điên.
JimmyJames 16/8/2016

11
Làm cái đó mất bao lâu? Tôi chắc chắn 60% chúng ta có thể hoàn thành nó bằng x, nhưng có 10% khả năng nó sẽ mất gấp năm lần.
David

18
@David: Điều này có thể sẽ khiến PM phát điên vì anh ta biết từ kinh nghiệm rằng 10% cơ hội này xảy ra 80% số lần :)
Frank Puffer

7
Thực tế là nhiều nơi rất thích theo dõi một dự án vào mặt đất sau đó thành công bất ngờ. Các Thủ tướng thường được khen thưởng vì có những dự đoán chính xác để họ có những khuyến khích đồi trụy. Đây là vấn đề chính-đại lý .
Sled

39

Bạn đã đúng - copy-paste hoạt động rất tốt và DRY không có lý do gì khi nhiệm vụ của bạn là tạo ra một chương trình mà mẫu được sao chép hoặc bản sao sẽ không phải duy trì hoặc phát triển trong tương lai. Khi hai thành phần phần mềm này có vòng đời hoàn toàn khác nhau, sau đó ghép chúng lại với nhau bằng cách tái cấu trúc mã chung thành một lib chung mà chính nó đang phát triển nặng có thể thực sự có tác dụng không thể đoán trước cho nỗ lực này. Mặt khác, khi sao chép các phần mã bên trong một chương trình hoặc hệ thống chương trình, tất cả các phần này thường sẽ có cùng vòng đời. Tôi sẽ minh họa bên dưới điều này có nghĩa gì với DRY và quản lý dự án.

Nghiêm túc mà nói, có rất nhiều chương trình như vậy: ví dụ, ngành công nghiệp trò chơi máy tính sản xuất rất nhiều chương trình phải được duy trì trong một thời gian ngắn tối đa vài tháng hoặc một năm, và khi thời gian đó kết thúc, dán sao chép mã cũ từ một trò chơi trước đó trong đó thời gian bảo trì đã hết, vào cơ sở mã của trò chơi mới là hoàn toàn tốt và có thể tăng tốc mọi thứ.

Thật không may, vòng đời của hầu hết các chương trình tôi phải đối phó trong những năm qua rất khác so với điều đó. 98% yêu cầu hoặc yêu cầu sửa lỗi đã đến với tôi là yêu cầu thay đổicho các chương trình hiện có. Và bất cứ khi nào bạn cần thay đổi thứ gì đó trong một phần mềm hiện có, "quản lý dự án" hoặc lập kế hoạch hoạt động tốt nhất khi các nỗ lực kiểm tra và gỡ lỗi của bạn khá thấp - điều đó sẽ không xảy ra nếu bạn thay đổi một thứ gì đó, nhưng do sao chép logic kinh doanh -past bạn dễ dàng quên bạn cần phải thay đổi một tá địa điểm khác trong cơ sở mã là tốt. Và ngay cả khi bạn quản lý để tìm tất cả những nơi đó, thời gian để thay đổi tất cả (và kiểm tra các thay đổi) có thể cao hơn nhiều như thể bạn chỉ có một nơi để thay đổi. Vì vậy, ngay cả bạn cũng có thể ước tính chính xác cho thay đổi, có chi phí cao hơn hàng chục lần so với nhu cầu có thể dễ dàng va chạm với ngân sách của dự án.

TLDR - bất cứ khi nào bạn phát triển một chương trình không cần thiết hoặc chịu trách nhiệm sửa lỗi và bảo trì bản gốc hoặc bản sao, vui lòng sao chép. Nhưng nếu bạn, nhóm của bạn hoặc công ty của bạn hoặc có thể trở nên có trách nhiệm, hãy áp dụng DRY bất cứ khi nào bạn có thể.

Thí dụ

Là một phụ lục, hãy để tôi giải thích "sửa lỗi và bảo trì" nghĩa là gì, và điều này dẫn đến sự khó lường trong việc lập kế hoạch, đặc biệt là trong một sản phẩm, bằng một ví dụ trong thế giới thực. Tôi thực sự đã thấy những điều này xảy ra trong thực tế, có thể không phải với 100 trường hợp, nhưng vấn đề thậm chí có thể bắt đầu khi bạn chỉ có một trường hợp trùng lặp.

Nhiệm vụ: tạo 100 báo cáo khác nhau cho một ứng dụng, mỗi báo cáo trông rất giống nhau, một số khác biệt yêu cầu giữa các báo cáo, một số logic khác nhau, nhưng tất cả đều không có nhiều khác biệt.

Nhà phát triển nhận nhiệm vụ này tạo ra cái đầu tiên (giả sử phải mất 3 ngày), sau một số thay đổi hoặc sửa lỗi nhỏ do QA và khách hàng kiểm tra xong, nó dường như chạy tốt. Sau đó, anh ta bắt đầu tạo báo cáo tiếp theo bằng cách dán sao chép và sửa đổi toàn bộ nội dung, sau đó là báo cáo tiếp theo và với mỗi báo cáo mới anh ta cần trung bình ~ 1 ngày. Rất dễ đoán, thoạt nhìn ...

Bây giờ, sau khi 100 báo cáo "sẵn sàng", chương trình đi vào sản xuất thực sự và một số vấn đề xảy ra đã bị bỏ qua trong QA. Có thể có vấn đề về hiệu suất, có thể các báo cáo bị sập một cách thường xuyên, có thể những thứ khác không hoạt động như dự định. Bây giờ, khi nguyên tắc DRY đã được áp dụng, 90% các vấn đề đó có thể được giải quyết bằng cách thay đổi cơ sở mã ở một nơi. Nhưng do phương pháp sao chép-dán, vấn đề phải được giải quyết 100 lần thay vì một lần. Và do những thay đổi đã được áp dụng từ báo cáo này sang báo cáo khác, nhà phát triển không thể nhanh chóng sao chép-dán bản sửa lỗi cho báo cáo đầu tiên sang 99 báo cáo khác. Anh ấy phải xem xét tất cả 100 báo cáo, đọc chúng, dịch thay đổi sang sửa đổi báo cáo, kiểm tra nó và có thể gỡ lỗi từng cái một. Đối với Thủ tướng, việc này bắt đầu trở nên rất khó khăn - tất nhiên anh ta có thể dành thời gian cho việc sửa lỗi "thông thường" (giả sử, 3 giờ) và nhân số này với 100, nhưng thực sự, đây có lẽ là một ước tính sai, một số cách khắc phục có thể là dễ làm hơn người khác, người khác có thể khó hơn. Và ngay cả khi ước tính này là chính xác, việc gỡ lỗi có chi phí cao gấp 100 lần so với mức cần thiết sẽ khiến công ty của bạn tốn rất nhiều tiền.

Điều tương tự sẽ xảy ra vào lần tới khi khách hàng yêu cầu thay đổi màu sắc biểu tượng công ty của mình trong tất cả các báo cáo đó, để làm cho kích thước trang có thể định cấu hình hoặc theo một số yêu cầu mới khác ảnh hưởng đến tất cả các báo cáo theo cách tương tự. Vì vậy, nếu điều đó xảy ra, bạn có thể ước tính chi phí và lập hóa đơn cho khách hàng gấp 100 lần giá mà anh ta sẽ phải trả khi mã đã KHÔ. Tuy nhiên, hãy thử điều này một vài lần và sau đó khách hàng sẽ hủy dự án bởi vì anh ta có thể sẽ không sẵn sàng trả chi phí phát triển cắt cổ của bạn. Và có lẽ tại thời điểm đó, ai đó sẽ đặt câu hỏi tại sao điều này xảy ra và chỉ tay vào người đưa ra quyết định cho chương trình sao chép-dán này.

Quan điểm của tôi là: khi bạn sản xuất phần mềm cho người khác, bạn luôn có ít nhất một khoảng thời gian ngắn để chịu trách nhiệm làm cho công việc hoạt động, sửa lỗi, điều chỉnh chương trình theo các yêu cầu thay đổi, v.v. Ngay cả trong một dự án trường xanh, những điều này các bộ phận có thể nhanh chóng bổ sung nhiều hơn nhiều so với nỗ lực phát triển dự kiến ​​ban đầu. Và đặc biệt khi tất cả các mã được sao chép của bạn nằm trong một sản phẩm, khoảng thời gian chịu trách nhiệm là cho tất cả các phần giống nhau, khác với trường hợp bạn sao chép một số mã cũ từ một dự án đã chết không còn nữa đang bảo trì tích cực.


4
Có lẽ là một câu trả lời tốt nhưng cách quá dài dòng so với các câu trả lời tốt khác.
Vince O'Sullivan

4
Bạn có thể bỏ qua DRY khi "bản sao sẽ không phải được duy trì hoặc phát triển trong tương lai", nhưng mã sẽ không bao giờ được sử dụng nữa thường sẽ tiếp tục được sử dụng lại.
Andy Lester

"Sao chép-dán hoạt động tuyệt vời ..." - không đồng ý! Ngay cả khi chương trình là một lần duy nhất và được đảm bảo không bao giờ phát triển ngoài bản phát hành ban đầu, mã sao chép-dán vẫn khiến việc sửa lỗi được tìm thấy trong quá trình phát triển phiên bản ban đầu của chương trình trở nên khó khăn hơn nhiều. Trừ khi bạn không bao giờ phạm sai lầm, trong trường hợp đó bạn là một Thiên Chúa.
JacquesB

1
@JacquesB: bạn nên đọc câu trả lời của tôi cẩn thận hơn, tôi đã không viết một cái gì đó khác biệt.
Doc Brown

Lập trình máy tính chỉ khác với việc xây dựng các máy giống hệt nhau với một dây chuyền lắp ráp. Huh. Ai đã có thunk nó? Có lẽ chúng ta nên có các lập trình viên làm việc như các PM. Nhưng sau đó chúng ta sẽ cần các lập trình viên là người quản lý. Lập trình viên làm cổ đông. Lập trình viên là khách hàng ... Chụp, chỉ cần dạy mọi người cách lập trình và được thực hiện với nó. (Nói cách khác: những người không phải là chuyên gia sẽ không bao giờ hiểu được những thăng trầm mà các chuyên gia biết đến.)

19

Vì vậy, từ góc độ quản lý dự án, thật tuyệt vời khi giải quyết một nhiệm vụ bằng cách sao chép một số mã hiện có 100 lần và thực hiện một số điều chỉnh nhỏ cho mỗi bản sao, theo yêu cầu. Tại mọi thời điểm, bạn biết chính xác bạn đã làm bao nhiêu công việc và còn lại bao nhiêu. Tất cả các nhà quản lý sẽ yêu bạn.

Xác nhận cơ sở của bạn là không chính xác.

Điều làm cho phần mềm khác biệt với các ngành nghề khác là bạn đang làm một cái gì đó mới mỗi ngày. Rốt cuộc, không có khách hàng nào sẽ trả tiền cho bạn để xây dựng một cái gì đó mà người khác đã làm. Người quản lý dự án có thể thích dự đoán, nhưng ông chủ của họ thích giá trị . Nếu bạn chỉ dán mã sao chép với các biến thể nhỏ, bạn sẽ không cung cấp nhiều giá trị cho công ty.

Cuối cùng , công ty sẽ nhận ra họ có thể làm công việc tương tự trong một phần nhỏ thời gian bằng cách thuê một lập trình viên giỏi. Và nếu họ không, đối thủ cạnh tranh của họ sẽ.


2
Tôi tranh luận hầu hết các ngành nghề kỹ thuật là về "làm một cái gì đó mới mỗi ngày"
BlueRaja - Danny Pflughoeft

12
@ BlueRaja-DannyPflughoeft: Không thực sự. Làm việc như một kỹ sư điện tử / điện tử, tôi có thể làm chứng rằng hầu hết các ngành kỹ thuật quy mô lớn (những dự án đòi hỏi phải vận hành như đóng tàu và máy điện) là về việc đảm bảo mọi người làm gì đó đã thử và thử nghiệm đúng cách. Đó là những gì doanh nghiệp coi là "kỹ thuật". Làm một cái gì đó mới là "R & D"
slebetman

3
@slebetman Có lẽ bạn vừa không nhận thấy tất cả công việc mà quản lý của bạn đang làm; ngay cả khi bạn làm điều tương tự lặp đi lặp lại, môi trường luôn thay đổi - bạn không có mẫu nhà máy điện mà bạn có thể giao cho khách hàng và được thực hiện với nó, bạn cần thực hiện khảo sát, tìm ra cách cung cấp nguyên liệu thô cho nhà máy và mang sản phẩm ra ngoài, quản lý tất cả các nguyên liệu thô để xây dựng và giải quyết các vấn đề cung cấp và thiếu hụt công việc và hàng triệu thứ khác. Có vẻ như công việc mẫu (như nhiều nỗ lực phần mềm làm), nhưng thực sự không phải vậy.
Luaan

1
@Luaan: Vâng, nhưng không ai trong số đó đang làm một cái gì đó mới. Tất cả bọn họ đang "làm một cái gì đó chúng ta biết cách làm". Phát triển phần mềm là khác nhau. Chủ yếu bởi vì trong phần mềm, không giống như các dự án kỹ thuật vật lý, chúng tôi có xu hướng gói gọn những thứ chúng tôi đã biết cách làm trong thư viện nên chúng tôi không phải "làm khảo sát" theo cách thủ công, v.v. Chúng tôi chỉ cần nhập thư viện cho nó và sử dụng nó .
slebetman

2
@slebetman Hầu như tất cả các phần mềm đang được viết là "một cái gì đó chúng tôi biết cách làm". Thư viện cũng sống trong một môi trường luôn thay đổi. Và bạn không có 100% kiến ​​thức và kinh nghiệm với toàn bộ thư viện, và tất cả các phụ thuộc của thư viện đó và các phụ thuộc khác mà bạn có, và có rất nhiều hệ thống và cấu hình phần cứng kỳ lạ chỉ đơn giản từ chối hoạt động theo cách một hệ thống hợp lý nên công việc. Đóng gói là tuyệt vời, nhưng nó vẫn đắt như địa ngục và cần hàng tấn khảo sát. Và kỹ thuật cũng được đóng gói - các khối đúc sẵn, IC, v.v.
Luaan

12

Lập trình cắt và dán cuối cùng dẫn đến phần mềm bị bỏ rơi. Tôi là một nhà thầu trên một hệ thống đặt hàng dịch vụ hữu tuyến từ một công ty điện thoại rất lớn. Hệ thống đã được cắt và dán quảng cáo vì tất cả các thử nghiệm đều là thủ công và họ không muốn thay đổi bất kỳ mã làm việc nào. Sự cải tiến nhỏ nhất có thể dẫn đến một bản sao mới của hàng trăm dòng mã. Ban đầu ứng dụng được viết để xử lý các tài khoản của tối đa mười hai dòng vật lý. Tất nhiên giới hạn này đã được thực hiện ở hàng trăm vị trí trong mã. Sau khoảng bốn năm, doanh nghiệp đã hỏi nhóm cần những gì để xử lý các tài khoản lớn hơn. Họ ước tính khoảng 18 triệu đô la. Vào thời điểm đó, dự án đã được chuyển cho một đội ngoài khơi để bảo trì tối thiểu. Đội ngũ hiện tại đã bị sa thải.

Các tổ chức nghĩ rằng cách này đang bị nghiền nát bởi các công ty có công nghệ tốt hơn.


Nó nghĩ rằng nó là bộ não tốt hơn, hơn là công nghệ tốt hơn. Công nghệ đến từ bộ não, phải không? Bất cứ điều gì đã xảy ra với "Nghĩ thông minh hơn, không khó hơn"?

10

Một câu châm ngôn bị lãng quên áp dụng ở đây là quy tắc 3 . Điều này khẳng định rằng bạn có thể sao chép mã một lần, nhưng ngoài ra nó nên được thay thế bằng mã chung.

3 có vẻ như là một số tùy ý nhưng một kịch bản phổ biến là dữ liệu và logic được sao chép trong một ứng dụng và cơ sở dữ liệu. Một ví dụ thường được trích dẫn là nơi có bảng tra cứu trong cơ sở dữ liệu và phía máy khách liệt kê. Sự khác biệt trong mô hình không cho phép điều này được lưu trữ dễ dàng ở một nơi duy nhất và vì vậy thông tin thường xuất hiện ở cả hai nơi.

Mặc dù thật tuyệt khi có mã DRY, có thể đôi khi logic nghiệp vụ đưa ra một ngoại lệ và do đó bạn phải tạo hai hoặc nhiều bit mã từ nguồn đã chung trước đó.

Vậy lam gi? Mã cho hiện trạng (sau tất cả, YAGNI ). Trong khi mã nên được viết để dễ sửa đổi, viết cả một chiếc chuông và còi cho một thứ gì đó có thể không cần thiết chỉ là làm tổn thương tiền bạc.


6
Lưu ý rằng điều này không có nghĩa là bạn nên nhận xét rằng bạn đã sao chép mã (ở cả hai nơi) để bạn biết nếu bạn sắp sao chép lại, bạn không nên!
Đánh dấu

3
Tôi đã thực hiện điều này trong trường hợp hai lớp cần cùng một phương thức nhưng hầu như không liên quan - giống như anh em họ xa. Tôi đã phải thêm các phụ thuộc vào gần một chục lớp để chúng thực sự chia sẻ mã. Vì vậy, tôi đã làm như những gì Mark đề xuất - sao chép phương pháp và cũng để lại một bình luận lớn, rõ ràng chỉ ra vị trí khác cho phương pháp đó.
Jeutnarg 17/8/2016

@MarkHurd Yep - điểm tuyệt vời ...
Robbie Dee

8

Trong câu hỏi của bạn, bạn chỉ liệt kê ba chức năng của quản lý dự án - ước tính, lập lịch và kiểm soát. Quản lý dự án là về việc đạt được các mục tiêu trong các ràng buộc của dự án. Các phương pháp được sử dụng để đạt được các mục tiêu trong các ràng buộc của một dự án là khác nhau đối với các dự án phần mềm so với nhiều loại dự án khác. Ví dụ, bạn muốn các quy trình sản xuất có tính lặp lại cao và được hiểu rõ. Tuy nhiên, phát triển phần mềm chủ yếu là công việc tri thức- đó là việc không thường xuyên và đòi hỏi phải suy nghĩ hơn là tuân theo các hướng dẫn và quy trình cứng nhắc. Các kỹ thuật được sử dụng để bắt đầu, lập kế hoạch, thực hiện, giám sát và kiểm soát và đóng dự án phần mềm sẽ cần tính đến loại công việc cần thực hiện trong dự án phần mềm - cụ thể là công việc không thường xuyên không thể thực hiện được để hướng dẫn cụ thể và thủ tục.

Tôi nghĩ vấn đề khác là bạn đang dùng DRY, một khái niệm liên quan đến việc lặp lại thông tin và cố gắng áp dụng nó vào việc quản lý các nhiệm vụ. DRY chỉ đơn giản nói rằng bạn chỉ nên có một đại diện thông tin có thẩm quyền. Các nhà quản lý dự án nên nắm lấy điều này, vì điều đó có nghĩa là mọi người sẽ biết nơi để tìm thông tin, việc truyền đạt các thay đổi sẽ dễ dàng và các thay đổi có thể được kiểm soát và quản lý tốt. DRY, thông qua các phần có thể tái sử dụng, giúp giảm chi phí dài hạn, giúp duy trì lịch trình dài hạn và cải thiện chất lượng - ba phần cho Tam giác quản lý dự án . Cần phải có một sự đầu tư về thời gian và tiền bạc để tạo ra DRY một cách hiệu quả, nhưng công việc của người quản lý dự án là đánh đổi thời gian, chi phí, tiến độ và chất lượng.


Chắc chắn, phát triển phần mềm là công việc tri thức. Trên thực tế, tôi thậm chí sẽ không coi ví dụ đầu tiên của mình (sao chép / dán) là phát triển phần mềm theo nghĩa chặt chẽ. Tuy nhiên, việc quản lý loại công việc này khó khăn hơn nhiều, vì vậy, Thủ tướng, ngay cả khi ông có nền tảng phát triển và biết tất cả những điều này, trong vai trò là một Thủ tướng, ông có xu hướng bỏ qua nó. (Tôi không nói rằng đây là một điều tốt, nó chỉ là những gì tôi đã quan sát nhiều lần. Tôi cũng không nghĩ rằng những Thủ tướng đó là ngu ngốc hay bất tài. Nó giống như vai trò đôi khi buộc họ phải hành động như thế này. )
Frank Puffer

3
@FrankPuffer Tôi không đồng ý rằng vai trò của người quản lý dự án buộc người đó phải đưa ra quyết định cụ thể. Nó nhiều khả năng là một lực lượng giáo dục hoặc tổ chức. Từ những gì tôi đã thấy, hầu hết giáo dục quản lý dự án tập trung vào các kỹ thuật quản lý dự án truyền thống hơn (có lẽ vì chúng thường được áp dụng cho nhiều dự án hơn) so với kỹ thuật quản lý dự án phần mềm. Điều này có thể đổ vào các tổ chức mong đợi điều này và không xem xét các kỹ thuật khác để quản lý các dự án công việc tri thức như phát triển phần mềm.
Thomas Owens

2
@FrankPuffer Chắc chắn nó khó hơn, nhưng nó cung cấp nhiều giá trị hơn. Nếu sếp của sếp bạn đủ thông minh, anh ta sẽ thoát khỏi người quản lý cố gắng "làm mọi thứ dễ dàng hơn cho bản thân" và tìm một người thực sự có thể làm công việc của mình. Đừng hiểu sai ý tôi, nếu làm cho mọi thứ dễ dàng hơn cung cấp giá trị, hãy thực hiện nó - nhưng trong những gì bạn mô tả, điều này gần như chắc chắn gây bất lợi cho giá trị cuối.
Luaan

4

Viết mã mới chỉ là một phần nhỏ của nhiệm vụ

Đề xuất của bạn sẽ giúp việc ước tính phần viết mã mới ban đầu dễ dàng hơn. Tuy nhiên, để thực sự mang đến bất cứ điều gì mới (cho dù đó là một hệ thống hoàn toàn mới, việc bổ sung tính năng hoặc thay đổi chức năng) làm điều này là không đủ và chỉ là một công việc thiểu số - các ước tính được thấy trong tài liệu nói rằng trong thực tế điều này một phần là khoảng 20% ​​-40% tổng số công việc.

Vì vậy, phần lớn công việc (bao gồm điều chỉnh sự phát triển ban đầu của bạn với những gì thực sự cần thiết, tích hợp, kiểm tra, viết lại, kiểm tra lại) không dễ ước tính hơn; chỉ khác, cố tình tránh DRY chỉ làm cho phần đó lớn hơn, khó hơn và với ước tính thay đổi nhiều hơn - lỗi đó hoặc cần thay đổi đòi hỏi phải thay đổi tất cả các phần nhân bản có thể không xảy ra, nhưng nếu có, thì ước tính của bạn sẽ hoàn toàn sai

Bạn không có được ước tính tốt hơn bằng cách cải thiện chất lượng ước tính của bạn về một phần nhỏ công việc nhưng làm cho nó tồi tệ hơn trên một phần lớn công việc; Vì vậy, nó không thực sự là một sự đánh đổi mà là một tình huống thua lỗ khi bạn có năng suất kém hơn nhưng ước tính cũng tệ hơn.


Đó là một điểm hay. Tuy nhiên, DRY hoặc các nguyên tắc tương tự cũng áp dụng cho các nhiệm vụ khác như thử nghiệm hoặc tích hợp. Hầu hết mọi thứ có thể được thực hiện một cách máy móc, không cần suy nghĩ nhiều hoặc theo những cách thông minh hơn. Các giải pháp thông minh thường nhanh hơn nhiều nhưng chúng có nguy cơ thất bại. Thêm vào đó, bạn phải đặt một lượng công việc hợp lý vào chúng trước khi nhận được bất kỳ kết quả nào.
Frank Puffer

Không có "nguy cơ thất bại", có một sự chắc chắn của thất bại. Mọi thứ sẽ thất bại sớm hay muộn. Bạn chỉ cần chọn chiếc xe tang đắt tiền và lái xe nhanh như thế nào.

4

DRY là hữu ích nhưng nó cũng được đánh giá quá cao. Một số người có thể đưa nó đi quá xa. Điều mà nhiều nhà phát triển không nhận ra là bất cứ khi nào bạn triển khai DRY để sử dụng cùng một phương pháp cho hai mục đích khác nhau (một chút), bạn sẽ giới thiệu một loại khớp nối rất chặt chẽ giữa các mục đích sử dụng khác nhau. Bây giờ mỗi khi bạn thay đổi mã cho trường hợp sử dụng đầu tiên, bạn cũng phải kiểm tra xem nó có hồi quy trường hợp sử dụng thứ hai không. Nếu đây là những trường hợp sử dụng độc lập rộng rãi, thì rất có thể liệu chúng có nên được kết hợp chặt chẽ hay không - có lẽ chúng không nên.

Việc sử dụng quá mức DRY cũng có thể dẫn đến các phương thức của Thiên Chúa bùng nổ phức tạp để xử lý tất cả các trường hợp sử dụng khác nhau mà chúng được đặt, khi các phương pháp nguyên tử nhỏ hơn sao chép một số mã sẽ dễ duy trì hơn nhiều.

Tuy nhiên, tôi sẽ đề nghị rằng câu hỏi không thực sự phù hợp ở cấp quản lý dự án. Một người quản lý dự án thực sự sẽ không muốn quan tâm đến mức độ chi tiết thực hiện này. Nếu họ là quản lý vi mô. Thực sự ... làm thế nào mọi thứ được thực hiện là trách nhiệm của nhà phát triển và lãnh đạo kỹ thuật. Quản lý dự án quan tâm nhiều hơn đến những gì được thực hiện và khi nào .

EDIT: mỗi bình luận, tôi đồng ý tuy nhiên trong trường hợp làm cho việc ước tính thời gian phát triển dễ dàng hơn , tránh DRY đôi khi có thể làm giảm số lượng không chắc chắn. Nhưng tôi tin rằng đây là một vấn đề không đáng kể liên quan đến các câu hỏi cấp bách hơn về (1) bao lâu cho đến khi các yêu cầu kinh doanh được đáp ứng, (2) khoản nợ kỹ thuật nào được đưa lên tàu trong quá trình và (3) rủi ro đối với tổng chi phí quyền sở hữu các lựa chọn kiến ​​trúc được thực hiện - có nên đi DRY hay không trong nhiều trường hợp là lựa chọn thiết kế nên dựa trên rủi ro / phần thưởng cho các yếu tố đó, hơn là việc cung cấp cho người quản lý dự án thông tin chính xác hơn một chút .


Tất nhiên người quản lý dự án không nên đối phó với các chi tiết thực hiện. Đó không phải là quan điểm của tôi. Quan điểm của tôi là, tùy thuộc vào cách nhà phát triển thực hiện một cái gì đó, anh ta ít nhiều có thể cung cấp thông tin cần thiết cho quản lý dự án.
Frank Puffer

Nó không có nghĩa đối với tôi để làm hỏng / hạn chế sản phẩm hoặc xây dựng nợ kỹ thuật chỉ đơn giản là để có thể báo cáo về nó tốt hơn. Giá trị của báo cáo chắc chắn phải là những đơn đặt hàng có cường độ thấp hơn giá trị của chất lượng công việc. Nhưng YMMV
Brad Thomas

Có lẽ các lập trình viên nên được trả đơn đặt hàng có cường độ lớn hơn các nhà quản lý?

2

Tôi nghĩ rằng bạn đang hiểu nhầm DRY.

Hãy sử dụng một ví dụ:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

public Class B
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }

    public int Add(int x, int y)
    {
        return x + y;
    }
}

so với

public Class C : A
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

Bằng cách thay thế lớp B bằng C, chúng tôi đã tuân thủ nguyên tắc DRY và giảm trùng lặp mã. Nhưng chúng tôi đã không tăng những ẩn số hoặc rủi ro cho dự án (trừ khi bạn chưa bao giờ thực hiện thừa kế trước đó).

Tôi nghĩ những gì bạn muốn nói khi bạn nói về DRY là một cái gì đó giống như một nhiệm vụ thiết kế. I E:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

!!!Yêu cầu mới! Một số khách hàng cần có khả năng nhân đôi !!

// Use class B for new clients!!
public Class B
{
    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

so với

public Class A // Version 2
{
    public int Multiply(int x, int y)
    {
        return Multiply(x as double, y as double);
    }

    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

Ở đây (giả sử nó hoạt động), chúng tôi đã thiết kế một giải pháp có thể giải quyết cả yêu cầu cũ VÀ yêu cầu mới, về cơ bản là cố gắng tạo ra một mô hình toán học của vấn đề thực tế hoặc quy tắc kinh doanh. Trong cuộc sống thực, hệ thống mà chúng ta đang lập mô hình rõ ràng sẽ phức tạp hơn nhiều, mô hình của chúng ta sẽ không phù hợp chính xác, và các trường hợp cạnh và kết quả không mong muốn sẽ mất thời gian để tìm và sửa.

Vậy, chúng ta nên lấy B hoặc A phiên bản 2 trong trường hợp này?

  • B sẽ cụ thể hơn với thay đổi được yêu cầu thực tế với ít tác dụng phụ hơn và dễ ước tính hơn và nhanh hơn để thực hiện.

  • Phiên bản 2 sẽ dẫn đến mã ít tổng thể hơn trong tương lai và sẽ là giải pháp thanh lịch hơn

Một lần nữa tôi sẽ nói rằng nó liên quan đến chất lượng của các đặc điểm kỹ thuật và yêu cầu.

Nếu chúng ta có các thông số kỹ thuật rất rõ ràng bao gồm các trường hợp cạnh và khả năng tương thích ngược thì chúng ta có thể chắc chắn rằng chúng ta hiểu hệ thống đủ tốt để cấu trúc lại mô hình mà không tạo ra lỗi.

Nếu chúng tôi có một yêu cầu khẩn cấp cho một khách hàng trong đó yêu cầu duy nhất là hành vi đó thay đổi cho khách hàng đó mà không xem xét hệ thống tổng thể; sau đó 'cải thiện' mô hình bằng cách tái cấu trúc A mang một rủi ro đáng kể. Cả hai phá vỡ các khách hàng khác hoặc vượt quá thời hạn vì không có thêm thời gian cần thiết để thiết kế và thử nghiệm giải pháp.


7
Tôi không đồng ý. Kế thừa không phải là thứ bạn làm một lần và sau đó làm chủ nó. Có rất nhiều cạm bẫy. Có nhiều lý do tại sao thành phần nên được ưu tiên hơn thừa kế. Vậy chúng ta phải đưa ra quyết định: Thừa kế? Thành phần? Thứ gì khác? Quyết định này có lẽ sẽ khó khăn trong thế giới thực. Trong ví dụ thứ hai cũng có rất nhiều lựa chọn thay thế. Thế còn thuốc generic / mẫu? Quặng có thể một số phương pháp chức năng sử dụng lambdas? Một lần nữa: Rất nhiều khả năng mỗi trong số đó sẽ có ý nghĩa cụ thể.
Frank Puffer

4
Vấn đề là trong ví dụ đầu tiên, bạn nên loại bỏ mã trùng lặp thông qua bất kỳ phương thức nào. nhưng cùng một mã thực thi một trong hai cách. Vì vậy, không có thay đổi chức năng. Trong ví dụ thứ hai, bạn thay đổi cách tiếp cận với thứ gì đó mà bạn hy vọng là có hiệu quả nhưng thực tế là mã khác
Ewan

1
Tôi đã ở trong một tình huống mà "yêu cầu khẩn cấp" của bạn là tiêu chuẩn. Công ty tôi làm việc đã tạo ra các hệ thống dữ liệu tùy chỉnh cho nhiều khách hàng khác nhau. Đầu tiên, họ tạo ra một hệ thống với Cobol, sau đó sao chép nó cho khách hàng tiếp theo, v.v., cho đến khi họ có 100 khách hàng. Bây giờ họ đã có một công việc trong tay để cố gắng thực hiện các cải tiến và cập nhật có hệ thống. Tôi đã làm việc trên một hệ thống có thể sao chép hành vi của hầu hết các hệ thống này, bằng cách sử dụng một bộ mã nguồn duy nhất, nhưng các tùy chỉnh được lưu trữ trong dữ liệu cấu hình. Chúng tôi không thể làm mọi thứ và một số thứ không thể thêm vào.

1

Đoạn văn theo đoạn văn

Một trong những nguyên tắc cơ bản nhất và được chấp nhận rộng rãi trong phát triển phần mềm là DRY (đừng lặp lại chính mình). Rõ ràng là hầu hết các dự án phần mềm đều yêu cầu một số loại quản lý.

Chính xác.

Bây giờ các nhiệm vụ dễ quản lý (ước tính, lịch trình, kiểm soát) là gì? Đúng, các nhiệm vụ lặp đi lặp lại, chính xác các nhiệm vụ nên tránh theo DRY.

Nhiệm vụ lặp đi lặp lại nên được tự động hóa, bắt buộc . Chúng nhàm chán, dễ bị lỗi, khi làm bằng tay.

Vì vậy, từ góc độ quản lý dự án, thật tuyệt vời khi giải quyết một nhiệm vụ bằng cách sao chép một số mã hiện có 100 lần và thực hiện một số điều chỉnh nhỏ cho mỗi bản sao, theo yêu cầu. Tại mọi thời điểm, bạn biết chính xác bạn đã làm bao nhiêu công việc và còn lại bao nhiêu. Tất cả các nhà quản lý sẽ yêu bạn.

Tôi nghĩ bạn có thể thay đổi từ "thích ứng" bằng "cấu hình". Xem xét bạn có một lỗi trong đoạn mã này được cho là sẽ được sao chép. Một lỗi xuất hiện trong các điều kiện cụ thể. Nếu nó không được sửa trong nguồn gốc và nó được sao chép thì sẽ có rất nhiều nơi cần sửa. Điều này có thể là xấu, nhưng sau đó ai đó phải:

  • đầu tiên sửa mã trong nguồn ban đầu;
  • sửa mã ở mọi nơi khác;
  • hãy chắc chắn rằng đó là tất cả những nơi Khi bạn nói điều này phải được thực hiện với người quản lý, ít nhất anh ta sẽ ghét ai đó.

Nếu thay vào đó, bạn áp dụng nguyên tắc DRY và cố gắng tìm một sự trừu tượng hóa ít nhiều loại bỏ mã trùng lặp, mọi thứ sẽ khác. Thông thường có nhiều khả năng, bạn phải đưa ra quyết định, nghiên cứu, sáng tạo. Bạn có thể đưa ra một giải pháp tốt hơn trong thời gian ngắn hơn, nhưng bạn cũng có thể thất bại. Hầu hết thời gian, bạn thực sự không thể nói bao nhiêu công việc còn lại. Bạn là cơn ác mộng tồi tệ nhất của người quản lý dự án.

Loại bỏ trùng lặp dẫn đến một điểm thất bại. Nếu một cái gì đó thất bại, bạn có thể khá chắc chắn nơi này xảy ra. RẮN và các mẫu thiết kế có mặt để giúp khắc phục chính xác vấn đề đó. Thời hạn quá ngắn có xu hướng kích động phong cách thủ tục "mã hóa". Đầu tư nhiều thời gian hơn vào một dự án để tạo ra thứ gì đó có thể tái sử dụng nghĩa là nên có ít thời gian dành cho dự án tiếp theo khi tính năng này sẽ được sử dụng lại, nhưng nó phải được cấu hình ngay từ đầu.

Tất nhiên tôi đang phóng đại, nhưng rõ ràng có một vấn đề nan giải. Câu hỏi của tôi là: các tiêu chí để quyết định nếu một nhà phát triển làm quá mức DRY là gì? Làm thế nào chúng ta có thể tìm thấy một sự thỏa hiệp tốt? Hoặc có cách nào để khắc phục hoàn toàn tình trạng khó xử này, không chỉ bằng cách tìm một sự thỏa hiệp?

Rất nhiều người chỉ ra rằng không có vấn đề nan giải ở đây. Có và không.

Nếu bạn có một cái gì đó thử nghiệm cao mà chưa bao giờ được thực hiện - không có vấn đề nan giải. Mặt khác, nếu bạn có một cái gì đó phải được thực hiện lại, như hệ thống đặt phòng mới, bạn đã có sự trừu tượng, chỉ phụ thuộc vào những gì bạn cần.

Tôi nghĩ vấn đề nan giải là - chúng ta có nên thực hiện một cái gì đó trong một tính năng, nếu nó không có khả năng được yêu cầu. Thực hiện một cái gì đó khi được yêu cầu. Không ai cần một cơ sở hạ tầng khổng lồ sẽ không được sử dụng.


Thực hiện một cái gì đó đơn giản, nhanh chóng ngay bây giờ, bởi vì điều đó đã được yêu cầu. Sau này, khi cách thức phức tạp là cần thiết, nỗ lực ban đầu là không có gì, phải bắt đầu lại. Người quản lý không thích điều này. Như thể bạn nói, "Thời gian lái xe về phía tây là vô ích nếu bây giờ chúng ta cần đi về phía đông." Nhưng đi khắp thế giới lần đầu tiên chỉ để chúng ta có thể đi về phía đông cũng là lãng phí thời gian.

1

đây hoàn toàn không phải là về thiết kế để tái sử dụng trong tương lai hoặc về nguyên tắc YAGNI. Đó là về việc lặp lại mã trong gói công việc hiện tại.

Nó hoàn toàn là về thiết kế. Có thể không sử dụng lại mỗi se, nhưng thiết kế dù sao.

Các tiêu chí để quyết định nếu một nhà phát triển đang lạm dụng DRY là gì?

Kinh nghiệm và môi trường / tình huống hiện tại của bạn. Đối với một vấn đề nhất định, bạn sẽ có được ý thức mạnh mẽ về Nguyên tắc Prado khi bạn thử mức độ KHÔ lớn hơn. Sau đó đột nhiên cân nhắc quản lý đến chơi. Thời gian, mục tiêu, khách hàng, quản lý mã dài hạn (có người nói nợ kỹ thuật ), v.v. sẽ thông báo kế hoạch tấn công của bạn.

Làm thế nào chúng ta có thể tìm thấy một sự thỏa hiệp tốt?

Uh ... thiết kế? Tái cấu trúc là thiết kế, nó được cho là. Phạm vi của DRYing có thể dễ dàng mở rộng như một siêu tân tinh từ vòng lặp, đến phương thức, đến lớp (es). Đã từng trải qua rồi. Nhưng bạn không thể thực sự biết cho đến khi bạn nghiên cứu vấn đề - đây là thiết kế.

Làm thế nào nó có thể không phải là một vấn đề thiết kế? Bạn phải xem xét vấn đề rộng rãi hơn mã trùng lặp ngay lập tức. Đây là một hoạt động thiết kế cho dù đó là mã hiện có hay một tờ giấy trắng; cho dù đó là "phương thức trích xuất" hay tạo các lớp và mô-đun mới.

Phần kết

... câu hỏi được đề cập và câu trả lời của nó không bao gồm khía cạnh quản lý dự án.

Quản lý điển hình, bỏ qua thời gian thiết kế. Về mặt lý tưởng, chúng ta sẽ thiết kế tính lặp đi lặp lại dư thừa trước khi mã hóa. Thay vào đó, ban quản lý cho rằng sự phát triển (và sửa lỗi) là một sự kiện Olympic duy nhất - mã hóa - khi thực tế nó là một môn phối hợp. Và họ đo đến 1/1000 giây vì họ nghĩ đó là tất cả tương tự.

Nếu thay vào đó, bạn áp dụng nguyên tắc DRY và cố gắng tìm một sự trừu tượng hóa ít nhiều loại bỏ mã trùng lặp, mọi thứ sẽ khác.

Tôi đã có kinh nghiệm này: "Tôi đã dành hai ngày để viết hàng này (của một mẫu GUI) và hai giờ để viết phần còn lại của mẫu." Ý tôi là tôi đã dành thời gian để xác định các lớp có thể sử dụng lại - DRY là một hiệu ứng phụ tự nhiên - hàng biểu mẫu GUI và trong đó có một số lớp khác. Sau khi gỡ lỗi, chúng được sử dụng, riêng lẻ và trong thành phần, trong suốt hình thức được mã hóa rất nhanh và thử nghiệm đặc biệt nhanh chóng mặc dù sự phức tạp xây dựng. Và nó đã bay qua thử nghiệm chính thức với tỷ lệ lỗi thấp đáng kinh ngạc.

Hầu hết thời gian, bạn thực sự không thể nói bao nhiêu công việc còn lại. Bạn là cơn ác mộng tồi tệ nhất của người quản lý dự án.

Tôi cũng không biết nhưng tôi tin rằng nỗ lực thiết kế phía trước sẽ được đền đáp. Tất cả chúng ta đều nói điều này nhưng đặc biệt là quản lý không tin tưởng nó. Quản lý sẽ nghĩ rằng tôi đang làm phiền "Hai ngày và bạn thậm chí chưa có 2% số tiền được mã hóa!"

Trong một trường hợp, chúng tôi mắc kẹt với súng của mình khi quản lý nói rằng "bạn đang dành quá nhiều thời gian cho thiết kế, hãy bắt đầu." Và đồng nghiệp nói rằng "đó là quá nhiều lớp học." Chà, một dự án phụ ít phức tạp hơn dự kiến ​​sẽ mất khoảng 1 tháng (tôi nghĩ đó là dự đoán sân bóng OK) nhưng mất 5 tháng. 3 tháng trong số đó đã được thử nghiệm / sửa chữa vì đó là một POS. "Nhưng chúng tôi không có thời gian để thiết kế!". Họ thực sự đã nói rằng.

Câu hỏi của tôi là: các tiêu chí để quyết định nếu một nhà phát triển làm quá mức DRY là gì? Làm thế nào chúng ta có thể tìm thấy một sự thỏa hiệp tốt? Hoặc có cách nào để khắc phục hoàn toàn tình trạng khó xử này, không chỉ bằng cách tìm một sự thỏa hiệp?

Hiển thị quản lý làm thế nào nó hoạt động ra. Nắm bắt một số dữ liệu. So sánh với các công việc khác, đặc biệt là các đồng nghiệp của bạn, những người làm công việc gấp rút tát. Cái đống thất bại đó dường như luôn thua cuộc đua, bị mắc kẹt trong bài kiểm tra và sau đó sau khi phát hành trở lại nhiều lần để sửa nhiều lỗi hơn.


"Đo bằng micromet, đánh dấu bằng phấn, cắt bằng rìu."
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.