Đây có phải là mùi mã không nếu bạn thường xuyên tạo một đối tượng chỉ để gọi một phương thức trên nó


14

Tôi đã thừa hưởng một cơ sở mã nơi có rất nhiều mã giống như thế này:

SomeDataAdapter sda = new SomeDataAdapter();
sda.UpdateData(DataTable updateData);

Và sau đó sda không bao giờ được sử dụng lại.

Có phải đó là một mùi mã chỉ ra rằng các phương thức đó thực sự nên là các phương thức lớp tĩnh thay thế?


Các lớp này có thực hiện bất kỳ giao diện nào không?
Phản ứng

7
Ngày sau khi bạn cấu trúc lại các phương thức tĩnh sẽ là ngày bạn muốn chạy thử nghiệm đơn vị với phiên bản giả của bộ điều hợp dữ liệu.
Mike

22
@Mike: Tại sao bạn cần phải giả định một phương thức tĩnh? Tôi cảm thấy vô cùng mệt mỏi với lập luận ngụy biện này rằng các phương thức tĩnh không thể kiểm chứng được. Nếu các phương thức tĩnh của bạn đang giữ trạng thái hoặc tạo hiệu ứng phụ, đó là lỗi của bạn , không phải lỗi của phương pháp thử nghiệm của bạn.
Robert Harvey

9
Theo tôi, đó là một mùi ngôn ngữ cho thấy sự yếu kém của phân tích "mọi thứ phải là một lớp".
Ben

7
@RobertHarvey: bạn có thể cần phải giả định một phương thức tĩnh với cùng lý do bạn chế giễu bất kỳ phương thức nào khác: quá tốn kém để gọi trong quá trình kiểm tra đơn vị.
kevin cline

Câu trả lời:


1

Tôi sẽ coi đó là một mùi kiến ​​trúc trong UpdateData có lẽ nên thuộc về một lớp 'dịch vụ'.

Trường hợp dữ liệu là một Apple. Trong đó AppleAd CHƯƠNG là lớp dịch vụ / kinh doanh thông minh. Trong đó AppleService là một tham chiếu Singleton đến AppleAd CHƯƠNG tồn tại bên ngoài phương thức hiện tại.

private static volatile AppleAdapter _appleService = null;
private static object _appleServiceLock = new object();
private AppleAdapter AppleService
{
    get
    {
        if (_appleService == null)
        {
            lock (_appleServiceLock)
            {
                if (_appleService == null)
                    _appleService = new AppleAdapter();
            }
        }
        return _appleService;
    }
}

public SomeAppleRelatedMethod(Apple apple)
{
    AppleService.UpdateData(apple);
}

Tôi không nghĩ những gì bạn đang làm là sai nhất thiết nhưng nếu một sốDataAd CHƯƠNG thực sự đại diện cho một loại dịch vụ kinh doanh phi trạng thái nào đó, thì một singleton sẽ là cách thực hành tốt nhất cho nó. Mong rằng sẽ giúp! Ví dụ được cung cấp là cách thức lạ mắt để đảm bảo không có sự tranh chấp của _appleService nếu nó xảy ra là cả null và được truy cập cùng một lúc bởi hai hoặc nhiều luồng.

Bạn biết gì? Nếu someDataAd CHƯƠNG là một IDbDataAd CHƯƠNG của ADO (mà gần như chắc chắn là vậy), hãy bỏ qua toàn bộ phản hồi này!

: P

Tôi không có quyền thêm nhận xét cho câu hỏi ban đầu, nhưng nếu bạn có thể chỉ định nơi mã này tồn tại.

Nếu mã này đại diện cho việc triển khai tùy chỉnh IDbDataAd CHƯƠNG và UpdateData đang tạo IDbConnection, IDbCommand và kết nối nó ở phía sau hậu trường, thì tôi sẽ không nghĩ rằng đó là mùi mã vì bây giờ chúng ta đang nói về luồng và khác những thứ cần được xử lý khi chúng ta sử dụng chúng xong.


12
Cứu giúp! Tôi đang chìm đắm trong các mẫu phần mềm.
Robert Harvey

4
... hoặc được tiêm dưới dạng phụ thuộc. ;)
Rob

12
Lộn xộn với singletons và khóa kiểm tra hai lần để có được một cái gì đó tương đương với một chức năng / thủ tục đơn giản là một mùi mã lớn hơn nhiều đối với tôi!
Ben

3

Tôi nghĩ vấn đề này còn đi sâu hơn thế. Ngay cả khi bạn tái cấu trúc nó thành một phương thức tĩnh, thì bạn sẽ nhận được mã nơi bạn gọi phương thức tĩnh duy nhất ở mọi nơi. Mà theo tôi là mùi mã trong chính nó. Nó có thể cho thấy bạn đang thiếu một số trừu tượng quan trọng. Có thể bạn muốn tạo một mã sẽ thực hiện một số xử lý trước và hậu xử lý trong khi cho phép bạn thay đổi những gì xảy ra ở giữa. Việc xử lý trước và sau đó sẽ chứa các cuộc gọi chung trong khi giữa sẽ phụ thuộc vào việc triển khai cụ thể.


Tôi đồng ý có một vấn đề sâu sắc hơn nhiều. Tôi đang cố gắng cải thiện dần dần mà không cần thiết kế lại kiến ​​trúc đầy đủ nhưng có vẻ như những gì tôi nghĩ không phải là một cách tốt để làm điều đó.
Shane Wealti

1

Loại. Điều đó thường có nghĩa là bạn muốn truyền một chức năng xung quanh và ngôn ngữ bạn chọn sẽ không cho phép bạn. Đó là loại vụng về và không hay, nhưng nếu bạn bị mắc kẹt trong một ngôn ngữ không có chức năng hạng nhất, bạn sẽ không thể làm được gì nhiều.

Nếu không có đối tượng nào được chuyển qua làm đối số cho các hàm khác, bạn có thể biến chúng thành các phương thức tĩnh và không có gì thay đổi.


Điều đó cũng có nghĩa là bạn muốn phương thức tĩnh trả về một phiên bản đã sửa đổi (hoặc bản sao đã sửa đổi) của một đối tượng bạn đang truyền cho nó.
Robert Harvey

2
"nếu bạn bị mắc kẹt trong một ngôn ngữ không có chức năng hạng nhất": Không có sự khác biệt giữa một đối tượng chỉ có một phương thức và chức năng hạng nhất (hoặc đóng cửa hạng nhất): Chúng chỉ là hai chế độ xem khác nhau của cùng một Điều.
Giorgio

4
@Giorgio Về mặt lý thuyết, không. Trong thực tế, nếu ngôn ngữ của bạn không ít nhất có một đường cú pháp cho nó, nó là sự khác biệt giữa fn x => x + 1new Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }};hoặc giới hạn mình vào một vài chức năng mã hóa cứng và hẹp-hữu ích.
Doval

Tại sao không fn x => x + 1thể là cú pháp đường cho new Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }}? Ok, có thể bạn có nghĩa là nếu một người bị mắc kẹt trong một ngôn ngữ mà không có loại cú pháp này.
Giorgio

@Giorgio Bạn sẽ phải hỏi Oracle. (Cấp, cuối cùng đã thay đổi với Java 8). Lưu ý rằng bạn cần nhiều cú pháp hơn là thực sự hữu ích - bạn cũng muốn có thể truyền các phương thức được khai báo trước theo tên. Currying cũng sẽ có ích. Tại một số điểm, bạn phải tự hỏi liệu có đáng để có tất cả các hack đó thay vì coi các chức năng là công dân đầu tiên. Nhưng bây giờ tôi đang lạc đề.
Doval

0

Nếu nhà nước nắm giữ làm cho một lớp nhất định trở nên tiện dụng hơn, thì chức năng có thể tái sử dụng thì không. Đối với một số lý do, mẫu thiết kế lệnh xuất hiện trong tâm trí; lý do đó chắc chắn không phải là mong muốn khiến Robert Harvey bị chết đuối.


0

Xác định "thường xuyên." Làm thế nào thường xuyên bạn khởi tạo đối tượng? Rất nhiều - có lẽ là không?

Có khả năng vấn đề lớn hơn để lo lắng trong hệ thống của bạn. Đi tĩnh sẽ truyền đạt rõ ràng hơn cho lập trình viên rằng trạng thái bên trong của đối tượng không thay đổi - thật tuyệt.

Nếu trạng thái đang bị rối tung và bạn phải bắt đầu làm cho những thứ khác tĩnh để làm cho điều đầu tiên tĩnh, thì bạn phải hỏi những phần nào cần phải tĩnh và những phần nào không.

Vâng, đó là một mùi mã, chỉ là một mùi nhỏ.


0

Làm cho nó một phương pháp tĩnh và di chuyển trên. Không có gì sai với các phương thức tĩnh. Khi một mô hình sử dụng xuất hiện thì bạn có thể lo lắng về việc trừu tượng hóa mô hình.


0

Mùi ở đây là đây là mã thủ tục được bọc (tối thiểu) trong các đối tượng.

Phải có lý do tại sao bạn muốn thực hiện thao tác đó trên bảng dữ liệu, thay vì mô hình hóa hoạt động đó với các hoạt động liên quan khác có chung một số ngữ nghĩa (nghĩa là có một ý nghĩa chung), tác giả chỉ tạo ra một quy trình mới bên trong một quy trình mới lớp & gọi nó.

Trong một ngôn ngữ chức năng, đó là cách bạn làm mọi thứ;) nhưng trong mô hình OO, bạn muốn mô hình hóa một số trừu tượng bao gồm hoạt động đó. Sau đó, bạn sẽ sử dụng các kỹ thuật OO để đưa ra mô hình đó và cung cấp một tập hợp các hoạt động liên quan để bảo tồn một số ngữ nghĩa.

Vì vậy, mùi chính ở đây là tác giả đang sử dụng các lớp, có thể là do trình biên dịch yêu cầu nó, mà không tổ chức các hoạt động thành một mô hình khái niệm.

BTW xem ra bất cứ lúc nào bạn thấy chương trình được mô hình hóa thay vì không gian vấn đề . Đó là một dấu hiệu cho thấy thiết kế có thể được hưởng lợi từ nhiều suy nghĩ hơn. Nói cách khác, coi chừng các lớp là "xAdaptor" và "xHandler" và "xUtility", và thường được gắn với một mô hình miền thiếu máu . Điều đó có nghĩa là ai đó chỉ gói mã lên để thuận tiện, trái ngược với việc thực sự mô hình hóa các khái niệm mà họ muốn thực hiện.

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.