메소드를 호출하기 위해 객체를 자주 생성하는 경우 코드 냄새가 나는가?


14

다음과 같은 코드가 많은 코드베이스를 상속했습니다.

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

그리고 sda는 다시는 사용되지 않습니다.

해당 메소드가 실제로 정적 클래스 메소드 여야 함을 나타내는 코드 냄새입니까?


이 클래스는 인터페이스를 구현합니까?
Reactgular

7
정적 메소드를 리팩토링 한 다음 날은 모형 어댑터를 사용하여 단위 테스트를 실행하려는 날이됩니다.
Mike

22
@ Mike : 왜 정적 메서드를 조롱해야합니까? 정적 메소드를 테스트 할 수 없다는이 잘못된 주장에 몹시 피곤합니다. 정적 방법이 상태를 유지하거나 부작용을 작성하는 경우, 즉 당신의 잘못, 당신의 테스트 방법이 아닌 고장.
Robert Harvey

9
제 생각 에는 "모든 것이 클래스 여야합니다"분석의 약점을 보여주는 언어 냄새입니다.
Ben

7
@RobertHarvey : 다른 메소드를 조롱하는 것과 같은 이유로 정적 메소드를 조롱해야 할 수도 있습니다. 단위 테스트 중에 호출하기에는 너무 비쌉니다.
kevin cline

답변:


1

UpdateData가 아마도 'service'클래스에 속해야한다는 아키텍처 냄새라고 생각합니다.

데이터가 Apple 인 경우 AppleAdapter가 서비스 / 비즈니스 인텔리전스 클래스 인 경우 여기서 AppleService는 현재 메소드 외부에 존재하는 AppleAdapter에 대한 싱글 톤 참조입니다.

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);
}

나는 당신이하는 일이 반드시 틀렸다고 생각하지 않지만 SomeDataAdapter가 실제로 어떤 종류의 무국적 비즈니스 서비스를 대표한다면, 싱글 톤이 최선의 방법 일 것입니다. 희망이 도움이됩니다! 제공된 예제는 _appleService가 null이거나 두 개 이상의 스레드에 의해 정확히 동시에 액세스 된 경우 _appleService의 경합을 방지하는 멋진 방법입니다.

그거 알아? SomeDataAdapter가 ADO IDbDataAdapter (거의 확실 함)이면이 전체 응답을 무시하십시오!

:피

원래 질문에 의견을 추가 할 권한이 없지만이 코드가있는 위치를 지정할 수있는 경우

이 코드가 IDbDataAdapter의 사용자 정의 구현을 나타내고 UpdateData가 IDbConnection, IDbCommand를 작성하고 모든 것을 배후에 연결하는 경우 스트림 및 기타에 대해 이야기하고 있기 때문에 코드 냄새가 나지 않을 것입니다 사용이 끝나면 폐기해야 할 것들.


12
도움! 소프트웨어 패턴에 빠져 익사합니다.
Robert Harvey

4
... 또는 의존성으로 주입되었습니다. ;)
Rob

12
간단한 기능 / 절차와 동등한 것을 얻기 위해 싱글 톤과 이중 검사 잠금으로 혼란스럽게하면 코드 냄새가 훨씬 큽니다!
Ben

3

나는이 문제가 그것보다 더 깊어 진다고 생각한다. 정적 메소드로 리팩토링하더라도 단일 정적 메소드를 호출하는 코드를 어디서나 얻을 수 있습니다. 내 의견으로는 코드 냄새 자체입니다. 중요한 추상화가 누락되었음을 나타낼 수 있습니다. 아마도 사전 및 사후 처리를 수행하면서 사이에 일어나는 일을 변경할 수있는 코드를 만들고 싶을 수도 있습니다. 사전 및 사후 처리에는 공통 호출이 포함되며 그 사이에는 구체적인 구현에 따라 달라집니다.


더 깊은 문제가 있음에 동의합니다. 전체 아키텍처를 다시 디자인하지 않고 점진적으로 개선하려고하지만 생각했던 것이 좋은 방법이 아닌 것 같습니다.
Shane Wealti

1

거의. 일반적으로 함수를 전달하고 원하는 언어를 사용하지 못하게됩니다. 어색하고 우아하지 않지만 일류 기능이없는 언어에 갇혀 있다면 할 수있는 일이 많지 않습니다.

해당 객체 중 어느 것도 다른 함수에 대한 인수로 전달되지 않으면 정적 메소드로 바꿀 수 있으며 아무것도 변경되지 않습니다.


또한 정적 메서드가 전달한 객체의 수정 된 버전 (또는 수정 된 복사본)을 반환하도록 할 수도 있습니다.
Robert Harvey

2
"일류 함수가없는 언어에 갇힌 경우": 한 가지 방법 만 사용하는 개체와 일류 함수 (또는 일류 폐쇄) 사이에는 차이가 없습니다. 의회.
Giorgio

4
@Giorgio 이론적으로, 아니오. 언어하지 않는 경우는 실제로, 적어도 그것에 대한 구문 설탕을 가지고, 그 사이의 차이점 fn x => x + 1new Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }};또는 몇 하드 코딩 좁게-유용한 기능에 자신을 제한.
Doval

fn x => x + 1구문 설탕이 될 수 없었 new Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }}습니까? 아마도 이런 종류의 구문 설탕이없는 언어에 갇혀 있다면 의미 할 것입니다.
Giorgio

@Giorgio 오라클에 문의해야합니다. (확실히 Java 8로 변경되었습니다.) 실제로 유용한 것보다 더 많은 구문 설탕이 필요합니다. 미리 선언 된 메소드를 이름으로 전달할 수도 있습니다. 카레도 편리합니다. 언젠가는 기능을 최초 시민으로 취급하는 대신 해킹을 모두 할 가치가 있는지 궁금해해야합니다. 하지만 지금은 주제를 벗어납니다.
Doval

0

보유 상태가 주어진 수업을보다 실용적이고 기능적으로 만들면… 어떤 이유로 명령 디자인 패턴 이 떠 오릅니다. 그 이유는 확실히 로버트 하비가 익사하려는 욕구가 아닙니다.


0

"자주"를 정의하십시오. 얼마나 자주 객체를 인스턴스화합니까? 많이-아마 아닐까요?

시스템에 더 큰 문제가있을 수 있습니다. 정적 상태가되면 객체의 내부 상태가 변하지 않는다는 것을 프로그래머에게보다 명확하게 전달할 수 있습니다.

상태가 엉망이고 첫 번째를 정적으로 만들기 위해 다른 것을 정적으로 시작 해야하는 경우 어떤 부분을 정적으로 해야하는지와 어떤 부분이 정하지 않아야하는지 묻어 야합니다.

, 코드 냄새, 작은 냄새입니다.


0

정적 방법으로 만들고 계속 진행하십시오. 정적 메소드에는 아무런 문제가 없습니다. 사용 패턴이 나타나면 패턴 추상화에 대해 걱정할 수 있습니다.


0

여기서 냄새는 객체에 (최소한) 랩핑 된 절차 코드라는 것입니다.

데이터 테이블에서 해당 작업을 수행 해야하는 이유 가 있어야 하지만 일부 의미를 공유하는 다른 관련 작업 (예 : 공통의 의미가있는)으로 해당 작업을 모델링하는 대신 작성자는 새로운 프로 시저 내에서 새 프로 시저를 분리했습니다. 클래스 & 전화.

기능적 언어에서, 당신이 일하는 방식입니다;) 그러나 OO 패러다임에서, 당신 은 그 연산을 포함한 추상화 를 모델링 하고 싶을 것 입니다. 그런 다음 OO 기술을 사용하여 해당 모델을 제거하고 일부 의미를 유지하는 일련의 관련 작업을 제공합니다.

여기서 주요 냄새는 저자가 클래스를 사용하고 있다는 것입니다. 아마도 컴파일러가 개념 모델로 작업을 구성하지 않고도 클래스가 필요하기 때문입니다.

BTW 는 문제 공간 대신 프로그램 이 모델링되는 것을 볼 때마다주의하십시오 . 디자인이 더 많은 생각으로부터 이익을 얻을 수 있다는 신호입니다. 다시 말해, 클래스가 모두 "xAdaptor"및 "xHandler"및 "xUtility"이며 일반적으로 빈혈 도메인 모델 과 연결되어있는 클래스를 살펴보십시오 . 실제로 구현하려는 개념을 모델링하는 것과는 달리 누군가 편의를 위해 코드를 묶는 것을 의미합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.