Giảm độ phức tạp của một lớp


10

Tôi đã xem xét một số câu trả lời và tìm kiếm trên Google, nhưng tôi không thể tìm thấy bất cứ điều gì hữu ích (nghĩa là điều đó sẽ không có tác dụng phụ khó xử).

Vấn đề của tôi, một cách trừu tượng, là tôi có một đối tượng và cần thực hiện một chuỗi dài các hoạt động trên nó; Tôi nghĩ về nó như một loại dây chuyền lắp ráp, giống như chế tạo một chiếc xe hơi.

Tôi tin rằng các đối tượng này sẽ được gọi là Đối tượng Phương thức .

Vì vậy, trong ví dụ này, tại một thời điểm nào đó, tôi sẽ có một CarWithoutUpholstery mà sau đó tôi sẽ cần chạy installBackSeat, installFrontSeat, installWoodenInserts (các hoạt động không can thiệp lẫn nhau và thậm chí có thể được thực hiện song song). Các hoạt động này được thực hiện bởi CarWithoutUpholstery.worker () và mang lại một đối tượng mới sẽ là CarWithUpholstery, sau đó tôi sẽ chạy có thể là CleanInsides (), verifyNoUpholsteryDefects (), v.v.

Các hoạt động trong một pha đã độc lập, tức là tôi đã vật lộn với một tập hợp con có thể được thực hiện theo bất kỳ thứ tự nào (ghế trước và sau có thể được cài đặt theo bất kỳ thứ tự nào).

Logic của tôi hiện đang sử dụng Reflection để đơn giản thực hiện.

Đó là, một khi tôi có CarWithoutUpholstery, đối tượng sẽ tự kiểm tra các phương thức được gọi là PerformanceS Something (). Tại thời điểm đó, nó thực thi tất cả các phương thức sau:

myObject.perform001SomeOperation();
myObject.perform002SomeOtherOperation();
...

trong khi kiểm tra lỗi và các công cụ. Mặc dù thứ tự hoạt động không quan trọng, tôi đã chỉ định một thứ tự từ điển trong trường hợp tôi phát hiện ra một số thứ tự là quan trọng sau tất cả. Điều này mâu thuẫn với YAGNI , nhưng chi phí rất ít - một loại đơn giản () - và nó có thể lưu một phương thức lớn đổi tên (hoặc giới thiệu một số phương pháp thực hiện kiểm tra khác, ví dụ như một mảng phương thức) xuống dòng.

Một ví dụ khác

Hãy để chúng tôi nói rằng thay vì xây dựng một chiếc xe hơi, tôi phải lập một báo cáo của Cảnh sát bí mật về ai đó, và gửi nó cho Evil Overlord của tôi . Đối tượng cuối cùng của tôi sẽ là ReadyReport. Để xây dựng nó, tôi bắt đầu bằng cách thu thập thông tin cơ bản (tên, họ, vợ / chồng ...). Đây là Giai đoạn A. Tùy thuộc vào việc có vợ / chồng hay không, sau đó tôi có thể phải tiến hành các giai đoạn B1 hoặc B2 và thu thập dữ liệu về tình dục ở một hoặc hai người. Điều này được thực hiện bởi một số truy vấn khác nhau để các Evil Minions khác nhau kiểm soát cuộc sống ban đêm, camera đường phố, biên lai bán hàng của cửa hàng tình dục và những gì không. Vân vân và vân vân.

Nếu nạn nhân không có gia đình, tôi thậm chí sẽ không tham gia vào giai đoạn GetIn information AboutF Family, nhưng nếu tôi làm vậy, thì việc tôi nhắm mục tiêu vào cha hoặc mẹ hoặc anh chị em (nếu có) là không liên quan. Nhưng tôi không thể làm điều đó nếu tôi chưa thực hiện FamilyStatusCheck, do đó thuộc về giai đoạn trước.

Tất cả đều hoạt động tuyệt vời ...

  • nếu tôi cần một số thao tác bổ sung, tôi chỉ cần thêm một phương thức riêng tư,
  • nếu hoạt động là phổ biến cho một số giai đoạn tôi có thể có nó được kế thừa từ một siêu lớp,
  • hoạt động đơn giản và khép kín. Không có giá trị từ một hoạt động được bao giờ theo yêu cầu của bất kỳ của những người khác (hoạt động mà làm được thực hiện trong một giai đoạn khác nhau),
  • các đối tượng trong dòng không cần thực hiện nhiều thử nghiệm vì chúng thậm chí không thể tồn tại nếu các đối tượng người tạo của chúng đã xác minh các điều kiện đó ở vị trí đầu tiên. Tức là, khi đặt các chèn vào bảng điều khiển, làm sạch bảng điều khiển và xác minh bảng điều khiển, tôi không cần xác minh rằng một bảng điều khiển thực sự ở đó .
  • nó cho phép thử nghiệm dễ dàng. Tôi có thể dễ dàng giả định một đối tượng một phần và chạy bất kỳ phương thức nào trên nó, và tất cả các hoạt động là các hộp đen xác định.

...nhưng...

Vấn đề nảy sinh khi tôi thêm một thao tác cuối cùng vào một trong các đối tượng phương thức của mình, điều này khiến cho mô-đun tổng thể vượt quá chỉ số phức tạp bắt buộc ("ít hơn N phương thức riêng").

Tôi đã đưa vấn đề lên tầng trên và đề nghị rằng trong trường hợp này, sự giàu có của các phương pháp riêng tư không phải là một thảm họa. Sự phức tạp có, nhưng nó ở đó bởi vì hoạt động rất phức tạp và thực sự nó không quá phức tạp - nó chỉ dài .

Sử dụng ví dụ về Evil Overlord, vấn đề của tôi là Evil Overlord (còn gọi là Người không bị từ chối ) đã yêu cầu tất cả các thông tin về chế độ ăn uống, Minions Dietary của tôi nói với tôi rằng tôi cần truy vấn các nhà hàng, bếp nhỏ, người bán hàng rong, người bán hàng rong không có giấy phép chủ sở hữu, v.v. và Overlord của Evil (phụ) - quen thuộc là Người cũng sẽ không bị từ chối - phàn nàn rằng tôi đang thực hiện quá nhiều truy vấn trong giai đoạn GetDietaryInform.

Lưu ý : Tôi biết rằng từ một số quan điểm, đây không phải là một vấn đề (bỏ qua các vấn đề hiệu suất có thể, v.v.). Tất cả điều đó xảy ra là một số liệu cụ thể là không hài lòng, và có lý do cho điều đó.

Những gì tôi nghĩ tôi có thể làm

Ngoài cái đầu tiên, tất cả các tùy chọn này đều có thể thực hiện được và, tôi nghĩ, có thể phòng thủ được.

  • Tôi đã xác minh rằng tôi có thể lén lút và tuyên bố một nửa phương pháp của mình protected. Nhưng tôi sẽ khai thác điểm yếu trong quy trình thử nghiệm và ngoài việc tự biện minh khi bị bắt, tôi không thích điều này. Ngoài ra, đó là một biện pháp ngăn chặn. Điều gì nếu số lượng các hoạt động cần thiết tăng gấp đôi? Không thể, nhưng sau đó thì sao?
  • Tôi có thể phân chia giai đoạn này một cách tùy tiện thành AnnealObjectAlpha, AnnealObjectBravo và AnnealObjectCharlie và có một phần ba các thao tác được thực hiện ở mỗi giai đoạn. Tôi có ấn tượng rằng điều này thực sự làm tăng thêm độ phức tạp ( thêm N-1 lớp), không có lợi ích gì ngoại trừ việc vượt qua một bài kiểm tra. Tất nhiên tôi có thể cho rằng CarWithFrontSeatsInstalled và CarWithAllSeatsInstalled là các giai đoạn kế tiếp nhau . Rủi ro về phương pháp Bravo sau này được Alpha yêu cầu là nhỏ, và thậm chí còn nhỏ hơn nếu tôi chơi tốt. Nhưng vẫn.
  • Tôi có thể bó các hoạt động khác nhau, tương tự từ xa, trong một lần duy nhất. performAllSeatsInstallation(). Đây chỉ là một biện pháp ngăn chặn và nó làm tăng sự phức tạp của hoạt động đơn lẻ. Nếu tôi cần thực hiện các thao tác A và B theo một thứ tự khác và tôi đã đóng gói chúng bên trong E = (A + C) và F (B + D), tôi sẽ phải giải nén E và F và xáo trộn mã xung quanh .
  • Tôi có thể sử dụng một loạt các chức năng lambda và gọn gàng kiểm tra hoàn toàn, nhưng tôi thấy điều đó thật rắc rối. Tuy nhiên, đây là sự thay thế tốt nhất cho đến nay. Nó sẽ thoát khỏi sự phản ánh. Hai vấn đề tôi gặp phải là có lẽ tôi sẽ được yêu cầu viết lại tất cả các đối tượng phương thức, không chỉ là giả thuyết CarWithEngineInstalled, và trong khi đó sẽ là bảo mật công việc rất tốt, nó thực sự không hấp dẫn lắm; và trình kiểm tra bảo hiểm mã có vấn đề với lambdas (có thể giải quyết được, nhưng vẫn còn ).

Vì thế...

  • Mà bạn nghĩ, là lựa chọn tốt nhất của tôi?
  • Có cách nào tốt hơn tôi chưa xem xét? ( có lẽ tôi nên dọn dẹp và hỏi trực tiếp nó là gì? )
  • Là thiết kế này vô vọng, và tôi nên thừa nhận thất bại và mương - kiến ​​trúc này hoàn toàn? Không tốt cho sự nghiệp của tôi, nhưng viết mã không thiết kế sẽ tốt hơn trong dài hạn?
  • Sự lựa chọn hiện tại của tôi có thực sự là One True Way không, và tôi cần phải chiến đấu để có được số liệu chất lượng tốt hơn (và / hoặc thiết bị) được cài đặt? Đối với tùy chọn cuối cùng này, tôi cần tham khảo ... Tôi không thể vẫy tay với @PHB trong khi lẩm bẩm Đây không phải là số liệu bạn đang tìm kiếm . Cho dù tôi muốn có thể

3
Hoặc, bạn có thể bỏ qua cảnh báo "vượt quá độ phức tạp tối đa".
Robert Harvey

Nếu tôi có thể, tôi sẽ. Bằng cách nào đó, số liệu này đã có được một phẩm chất thiêng liêng của riêng mình. Tôi đang tiếp tục cố gắng và thuyết phục PTB chấp nhận chúng như một công cụ hữu ích, nhưng chỉ là một công cụ. Tôi vẫn có thể thành công ...
LSerni

Là các hoạt động thực sự xây dựng một đối tượng, hoặc bạn chỉ đang sử dụng phép ẩn dụ của dây chuyền lắp ráp bởi vì nó chia sẻ thuộc tính cụ thể mà bạn đề cập (nhiều hoạt động với một thứ tự phụ thuộc một phần)? Điều quan trọng là cái trước gợi ý mẫu xây dựng, trong khi cái sau có thể gợi ý một số mẫu khác với nhiều chi tiết được điền vào.
outis

2
Sự chuyên chế của các số liệu. Số liệu là các chỉ số hữu ích, nhưng thực thi chúng trong khi bỏ qua lý do tại sao số liệu đó được sử dụng là không hữu ích.
Jaydee

2
Giải thích cho những người ở tầng trên sự khác biệt giữa độ phức tạp thiết yếu và độ phức tạp tình cờ. vi.wikipedia.org/wiki/No_Silver_BONS Nếu bạn chắc chắn rằng sự phức tạp vi phạm quy tắc là điều cần thiết, thì nếu bạn tái cấu trúc cho mỗi lập trình viên.stackexchange.com/a/297414/ 51948 bạn có thể trượt quanh quy tắc và lan truyền ra sự phức tạp. Nếu việc đóng gói mọi thứ thành các giai đoạn không phải là tùy ý (các giai đoạn liên quan đến vấn đề) và thiết kế lại làm giảm tải nhận thức cho các nhà phát triển duy trì mã, thì sẽ hợp lý khi làm điều này.
Fuhrmanator

Câu trả lời:


15

Chuỗi hoạt động dài có vẻ như là lớp riêng của nó, sau đó cần các đối tượng bổ sung để thực hiện các nhiệm vụ của nó. Có vẻ như bạn đang ở gần giải pháp này. Thủ tục dài này có thể được chia thành nhiều bước hoặc nhiều giai đoạn. Mỗi bước hoặc giai đoạn có thể là lớp riêng của nó trưng ra một phương thức công khai. Bạn sẽ muốn mỗi giai đoạn để thực hiện cùng một giao diện. Sau đó, dây chuyền lắp ráp của bạn theo dõi một danh sách các giai đoạn.

Để xây dựng trên ví dụ lắp ráp xe hơi của bạn, hãy tưởng tượng Carlớp:

public class Car
{
    public IChassis Chassis { get; private set; }
    public Dashboard { get; private set; }
    public IList<Seat> Seats { get; private set; }

    public Car()
    {
        Seats = new List<Seat>();
    }

    public void AddChassis(IChassis chassis)
    {
        Chassis = chassis;
    }

    public void AddDashboard(Dashboard dashboard)
    {
        Dashboard = dashboard;
    }
}

Tôi sẽ bỏ qua việc triển khai một số thành phần, như IChassis, SeatDashboardvì lợi ích của sự ngắn gọn.

Các Carkhông chịu trách nhiệm cho việc xây dựng chính nó. Dây chuyền lắp ráp là, vì vậy hãy gói gọn nó trong một lớp:

public class CarAssembler
{
    protected List<IAssemblyPhase> Phases { get; private set; }

    public CarAssembler()
    {
        Phases = new List<IAssemblyPhase>()
        {
            new ChassisAssemblyPhase(),
            new DashboardAssemblyPhase(),
            new SeatAssemblyPhase()
        };
    }

    public void Assemble(Car car)
    {
        foreach (IAssemblyPhase phase in Phases)
        {
            phase.Assemble(car);
        }
    }
}

Sự khác biệt quan trọng ở đây là CarAssembler có một danh sách các đối tượng pha lắp ráp thực hiện IAssemblyPhase. Bây giờ bạn đang xử lý rõ ràng với các phương thức công khai, nghĩa là mỗi giai đoạn có thể được kiểm tra và công cụ chất lượng mã của bạn sẽ hạnh phúc hơn vì bạn không nhồi nhét quá nhiều vào một lớp. Quá trình lắp ráp cũng chết đơn giản. Chỉ cần vòng qua các giai đoạn và cuộc gọi Assembleđi qua trong xe. Làm xong. Các IAssemblyPhasegiao diện cũng là chết đơn giản chỉ với một phương pháp nào đơn mà phải mất một đối tượng xe:

public interface IAssemblyPhase
{
    void Assemble(Car car);
}

Bây giờ chúng ta cần các lớp cụ thể thực hiện giao diện này cho từng giai đoạn cụ thể:

public class ChassisAssemblyPhase : IAssemblyPhase
{
    public void Assemble(Car car)
    {
        car.AddChassis(new UnibodyChassis());
    }
}

public class DashboardAssemblyPhase : IAssemblyPhase
{
    public void Assemble(Car car)
    {
        Dashboard dashboard = new Dashboard();

        dashboard.AddComponent(new Speedometer());
        dashboard.AddComponent(new FuelGuage());
        dashboard.Trim = DashboardTrimType.Aluminum;

        car.AddDashboard(dashboard);
    }
}

public class SeatAssemblyPhase : IAssemblyPhase
{
    public void Assemble(Car car)
    {
        car.Seats.Add(new Seat());
        car.Seats.Add(new Seat());
        car.Seats.Add(new Seat());
        car.Seats.Add(new Seat());
    }
}

Mỗi giai đoạn riêng lẻ có thể khá đơn giản. Một số chỉ là một lót. Một số có thể chỉ chói mắt thêm bốn chỗ ngồi, và một số khác phải cấu hình bảng điều khiển trước khi thêm nó vào xe. Sự phức tạp của quá trình rút ra dài này được chia thành nhiều lớp, có thể tái sử dụng, có thể dễ dàng kiểm tra.

Mặc dù bạn nói rằng thứ tự không quan trọng ngay bây giờ, nó có thể trong tương lai.

Để hoàn thành việc này, chúng ta hãy xem quy trình lắp ráp xe hơi:

Car car = new Car();
CarAssembler assemblyLine = new CarAssembler();

assemblyLine.Assemble(car);

Bạn có thể phân lớp CarAssembler để lắp ráp một loại xe hoặc xe tải cụ thể. Mỗi pha là một đơn vị trong một tổng thể lớn hơn, giúp sử dụng lại mã dễ dàng hơn.


Là thiết kế này vô vọng, và tôi nên thừa nhận thất bại và mương - kiến ​​trúc này hoàn toàn? Không tốt cho sự nghiệp của tôi, nhưng viết mã không thiết kế sẽ tốt hơn trong dài hạn?

Nếu quyết định những gì tôi viết cần viết lại là một vết đen trong sự nghiệp của tôi, thì tôi sẽ làm việc như một người đào mương ngay bây giờ, và bạn không nên nghe theo lời khuyên của tôi. :)

Kỹ thuật phần mềm là một quá trình vĩnh cửu của việc học, áp dụng và sau đó học lại. Chỉ vì bạn quyết định viết lại mã của mình không có nghĩa là bạn sẽ bị sa thải. Nếu đó là trường hợp, sẽ không có kỹ sư phần mềm.

Sự lựa chọn hiện tại của tôi có thực sự là One True Way không, và tôi cần phải chiến đấu để có được số liệu chất lượng tốt hơn (và / hoặc thiết bị) được cài đặt?

Những gì bạn đã vạch ra không phải là One True Way, tuy nhiên hãy nhớ rằng các số liệu mã cũng không phải là One True Way. Mã số liệu nên được xem là cảnh báo. Họ có thể chỉ ra các vấn đề bảo trì trong tương lai. Chúng là hướng dẫn, không phải là luật. Khi công cụ đo lường mã của bạn chỉ ra điều gì đó, trước tiên tôi sẽ điều tra mã để xem liệu nó có thực hiện đúng các nguyên tắc RẮN hay không . Nhiều lần tái cấu trúc mã để làm cho nó RẮN hơn sẽ đáp ứng các công cụ đo lường mã. Đôi khi nó không. Bạn phải lấy các số liệu này theo từng trường hợp.


1
Vâng, tốt hơn nhiều sau đó có một lớp thần.
BЈовић

Cách tiếp cận này hoạt động, nhưng chủ yếu là vì bạn có thể lấy các yếu tố cho xe mà không cần thông số. Điều gì nếu bạn cần để vượt qua chúng? Sau đó, bạn có thể ném tất cả những thứ này ra khỏi cửa sổ và suy nghĩ lại về quy trình, bởi vì bạn không thực sự có một nhà máy sản xuất ô tô với 150 thông số, điều đó thật tệ.
Andy

@DavidPacker: Ngay cả khi bạn phải tham số hóa một loạt các công cụ, bạn cũng có thể gói gọn nó trong một loại lớp Cấu hình nào đó mà bạn chuyển vào hàm tạo của đối tượng "trình biên dịch". Trong ví dụ xe này, màu sơn, màu nội thất và vật liệu, gói trang trí, động cơ, và nhiều thứ khác có thể được tùy chỉnh, nhưng bạn không nhất thiết phải có 150 tùy chỉnh. Bạn có thể sẽ có một tá hoặc hơn, cho vay chính nó cho một đối tượng tùy chọn.
Greg Burghardt

Nhưng chỉ thêm cấu hình sẽ thách thức mục đích của vòng lặp đẹp, đó là một sự xấu hổ to lớn, bởi vì bạn sẽ phải phân tích cấu hình và gán nó cho các phương thức thích hợp để trả lại cho bạn các đối tượng thích hợp. Vì vậy, bạn có thể sẽ kết thúc với một cái gì đó khá giống với thiết kế ban đầu.
Andy

Tôi hiểu rồi. Thay vì có một lớp và năm mươi phương thức, tôi thực sự sẽ có năm mươi lớp nạc lắp ráp và một lớp phối hợp. Cuối cùng kết quả có vẻ như nhau, hiệu năng cũng khôn ngoan, nhưng bố cục mã sạch hơn. Tôi thích nó. Sẽ khó xử hơn một chút khi thêm các thao tác (tôi sẽ phải thiết lập chúng trong lớp của chúng, cộng với việc thông báo cho lớp điều phối; tôi thấy không có cách nào dễ dàng để thoát khỏi sự cần thiết này), nhưng tôi vẫn rất thích nó. Cho phép tôi một vài ngày để khám phá phương pháp này.
LSerni

1

Tôi không biết nếu điều này là có thể với bạn, nhưng tôi đang suy nghĩ về việc sử dụng một cách tiếp cận theo hướng dữ liệu hơn. Ý tưởng là bạn nắm bắt một số biểu thức (khai báo) của các quy tắc và ràng buộc, hoạt động, phụ thuộc, trạng thái, v.v ... Sau đó, các lớp và mã của bạn chung chung hơn, được định hướng theo các quy tắc, khởi tạo trạng thái hiện tại, thực hiện các hoạt động để thay đổi trạng thái, bằng cách sử dụng khai báo quy tắc và thay đổi trạng thái thay vì sử dụng mã trực tiếp hơn. Người ta có thể sử dụng khai báo dữ liệu trong ngôn ngữ lập trình hoặc một số công cụ DSL hoặc công cụ logic hoặc công cụ logic.


Một số hoạt động thực sự được thực hiện theo cách này (như danh sách các quy tắc). Để giữ ví dụ về xe hơi, khi lắp đặt hộp cầu chì, đèn và phích cắm, tôi không thực sự sử dụng ba phương pháp khác nhau, nhưng chỉ có một phương pháp, phù hợp với điều kiện điện hai pin, và đưa Danh sách ba danh sách cầu chì , đèn và phích cắm. Rất tiếc, phần lớn các phương pháp khác rất tiếc là không dễ dàng tuân theo cách tiếp cận này.
LSerni

1

Bằng cách nào đó vấn đề nhắc nhở tôi về sự phụ thuộc. Bạn muốn một chiếc xe trong một cấu hình cụ thể. Giống như Greg Burghardt, tôi sẽ đi với các đối tượng / lớp cho từng bước / vật phẩm / Tấn.

Mỗi bước khai báo những gì nó thêm vào hỗn hợp (những gì nó provides) (có thể là nhiều thứ), nhưng cũng là những gì nó yêu cầu.

Sau đó, bạn xác định cấu hình bắt buộc cuối cùng ở đâu đó và có một thuật toán xem xét những gì bạn cần và quyết định những bước nào cần thực hiện / những phần nào cần được thêm vào / những tài liệu nào cần được thu thập.

Các thuật toán độ phân giải phụ thuộc không quá khó. Trường hợp đơn giản nhất là mỗi bước cung cấp một thứ và không có hai thứ nào cung cấp cùng một thứ và các phụ thuộc rất đơn giản (không có 'hoặc' trong phần phụ thuộc). Đối với các trường hợp phức tạp hơn: chỉ cần nhìn vào một công cụ như debian apt hoặc một cái gì đó.

Cuối cùng, xây dựng chiếc xe của bạn sau đó giảm xuống những bước có thể có và để CarBuilder tìm ra các bước cần thiết.

Tuy nhiên, một điều quan trọng là bạn phải tìm cách để CarBuilder biết về tất cả các bước. Cố gắng làm điều này bằng cách sử dụng một tập tin cấu hình. Thêm một bước bổ sung sau đó sẽ chỉ cần thêm vào tệp cấu hình. Nếu bạn cần logic, hãy thử thêm DSL trong tệp cấu hình. Nếu vẫn thất bại, bạn bị kẹt khi xác định chúng trong mã.


0

Một vài điều bạn đề cập nổi bật là 'xấu' với tôi

"Logic của tôi hiện đang sử dụng Reflection để đơn giản thực hiện"

Thực sự không có lý do cho việc này. Bạn có thực sự sử dụng so sánh chuỗi các tên phương thức để xác định chạy gì không?! Nếu bạn thay đổi thứ tự, bạn sẽ phải thay đổi tên của phương thức?!

"Các hoạt động trong một giai đoạn đã độc lập"

Nếu họ thực sự độc lập với nhau, điều đó cho thấy rằng lớp của bạn đã đảm nhận nhiều hơn một trách nhiệm. Đối với tôi, cả hai ví dụ của bạn dường như cho vay một số loại

MyObject.AddComponent(IComponent component) 

cách tiếp cận sẽ cho phép bạn phân chia logic cho mỗi opperation thành lớp hoặc lớp riêng của nó.

Trong thực tế tôi tưởng tượng họ không thực sự độc lập, tôi tưởng tượng rằng mỗi người kiểm tra trạng thái của đối tượng và sửa đổi nó, hoặc ít nhất là thực hiện một số loại xác nhận trước khi bắt đầu.

Trong trường hợp này, bạn có thể:

  1. Ném OOP ra khỏi cửa sổ và có các dịch vụ hoạt động trên dữ liệu được hiển thị trong lớp của bạn tức là.

    Dịch vụ.AddDoorToCar (Xe hơi ô tô)

  2. Có một lớp trình xây dựng để xây dựng đối tượng của bạn bằng cách tập hợp dữ liệu cần thiết trước và trả lại đối tượng đã hoàn thành tức là.

    Car = CarBuilder.WithDoor (). WithDoor (). WithWheels ();

(logic withX một lần nữa có thể được chia thành các trình con)

  1. Đưa phương pháp tiếp cận chức năng và chuyển các chức năng / phân định thành một phương thức sửa đổi

    Car.Modify ((c) => c.doors ++);


Ewan nói: "Ném OOP ra khỏi cửa sổ và có các dịch vụ hoạt động trên dữ liệu được hiển thị trong lớp của bạn" --- Làm thế nào điều này không hướng đối tượng?
Greg Burghardt

?? không phải, đó là một lựa chọn không OO
Ewan

Bạn đang sử dụng các đối tượng, có nghĩa là "hướng đối tượng". Chỉ vì bạn không thể xác định một mẫu lập trình cho mã của mình không có nghĩa là nó không hướng đối tượng. Các nguyên tắc RẮN là một quy tắc tốt để đi theo. Nếu bạn được thực hiện một số hoặc tất cả các nguyên tắc RẮN, thì đó là hướng đối tượng. Thực sự, nếu bạn đang sử dụng các đối tượng và không chỉ chuyển các cấu trúc xung quanh sang các thủ tục hoặc phương thức tĩnh khác nhau, thì nó là hướng đối tượng. Có một sự khác biệt giữa "mã hướng đối tượng" và "mã tốt". Bạn có thể viết mã hướng đối tượng xấu.
Greg Burghardt

đó là 'không phải OO' vì bạn đang phơi bày dữ liệu như thể nó là một cấu trúc và hoạt động trên nó trong một lớp riêng biệt như trong một thủ tục
Ewan

Tôi chỉ thêm bình luận hàng đầu để thử và ngăn chặn điều không thể tránh khỏi "đó không phải là OOP!" bình luận
Ewan
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.