Lý lịch
Tôi đang làm việc trên một dự án C # đang diễn ra. Tôi không phải là lập trình viên C #, chủ yếu là lập trình viên C ++. Vì vậy, tôi đã được giao cơ bản dễ dàng và tái cấu trúc các nhiệm vụ.
Mã là một mớ hỗn độn. Đó là một dự án lớn. Vì khách hàng của chúng tôi yêu cầu phát hành thường xuyên với các tính năng mới và sửa lỗi, tất cả các nhà phát triển khác đã buộc phải áp dụng phương pháp vũ phu trong khi mã hóa. Mã này rất không thể nhầm lẫn và tất cả các nhà phát triển khác đồng ý với nó.
Tôi không ở đây để tranh luận liệu họ đã làm đúng. Khi tôi tái cấu trúc, tôi tự hỏi liệu tôi có đang thực hiện đúng cách không vì mã được cấu trúc lại của tôi có vẻ phức tạp! Đây là nhiệm vụ của tôi là ví dụ đơn giản.
Vấn đề
Có sáu loại: A
, B
, C
, D
, E
và F
. Tất cả các lớp có một chức năng ExecJob()
. Tất cả sáu triển khai đều rất giống nhau. Về cơ bản, lúc đầu A::ExecJob()
đã được viết. Sau đó, một phiên bản hơi khác được yêu cầu được thực hiện B::ExecJob()
bằng cách sao chép-dán-sửa đổi A::ExecJob()
. Khi một phiên bản hơi khác được yêu cầu, C::ExecJob()
đã được viết và như vậy. Tất cả sáu triển khai có một số mã chung, sau đó một số dòng mã khác nhau, sau đó lại một số mã phổ biến, v.v. Đây là một ví dụ đơn giản về việc triển khai:
A::ExecJob()
{
S1;
S2;
S3;
S4;
S5;
}
B::ExecJob()
{
S1;
S3;
S4;
S5;
}
C::ExecJob()
{
S1;
S3;
S4;
}
Trường hợp SN
một nhóm các tuyên bố chính xác giống nhau.
Để làm cho chúng trở nên phổ biến, tôi đã tạo một lớp khác và di chuyển mã chung trong một hàm. Sử dụng tham số để kiểm soát nhóm câu lệnh nào sẽ được thực thi:
Base::CommonTask(param)
{
S1;
if (param.s2) S2;
S3;
S4;
if (param.s5) S5;
}
A::ExecJob() // A inherits Base
{
param.s2 = true;
param.s5 = true;
CommonTask(param);
}
B::ExecJob() // B inherits Base
{
param.s2 = false;
param.s5 = true;
CommonTask(param);
}
C::ExecJob() // C inherits Base
{
param.s2 = false;
param.s5 = false;
CommonTask(param);
}
Lưu ý rằng, ví dụ này chỉ sử dụng ba lớp và các câu lệnh đơn giản hóa. Trong thực tế, CommonTask()
hàm trông rất phức tạp với tất cả những kiểm tra tham số đó và còn nhiều câu lệnh nữa. Ngoài ra, trong mã thực, có một số CommonTask()
chức năng trông.
Mặc dù tất cả các triển khai đang chia sẻ mã chung và các ExecJob()
chức năng trông có vẻ dễ thương hơn, nhưng vẫn tồn tại hai vấn đề đang làm phiền tôi:
- Đối với bất kỳ thay đổi nào
CommonTask()
, tất cả sáu tính năng (và có thể nhiều hơn trong tương lai) đều cần được kiểm tra. CommonTask()
đã phức tạp rồi Nó sẽ trở nên phức tạp hơn theo thời gian.
Tôi đang làm điều đó đúng cách?