문제

나는 C#의 프로젝트를 진행하고 있습니다. 이전 프로그래머는 객체 지향적 프로그래밍을 몰랐기 때문에 대부분의 코드는 거대한 파일 (4-5000 줄에 대해 이야기하고 있음)에 수십에 걸쳐 수십 개의 메소드가 있지만 한 번의 클래스에 불과합니다. 그러한 프로젝트를 리팩토링하는 것은 큰 사업이기 때문에 지금은 반면에 살았습니다.

코드 파일 중 하나에서 메소드가 사용될 때마다 클래스가 인스턴스화되고 메소드가 개체 인스턴스에서 호출됩니다.

이런 식으로 수행 할 때 눈에 띄는 성과 처벌이 있는지 궁금합니다. 모든 방법을 정적으로 "지금"정적으로 만들어야하며, 가장 중요한 것은 응용 프로그램이 어떤 식 으로든 이익을 얻을 수 있습니까?

도움이 되었습니까?

해결책

에서 여기, 정적 호출은 인스턴스 메소드를 호출 할 때마다 인스턴스를 구성하는 것보다 4 ~ 5 배 빠릅니다. 그러나 우리는 여전히 통화 당 수십 나노초에 대해서만 이야기하고 있으므로 방법을 수백만 번 호출하는 단단한 루프가 없으면 혜택을 누릴 수 없으며 외부에서 단일 인스턴스를 구성하여 동일한 혜택을 얻을 수 있습니다. 그 루프와 재사용.

새로 정적 된 방법을 사용하려면 모든 통화 사이트를 변경해야하므로 점차적으로 리팩토링에 시간을 보내는 것이 좋습니다.

다른 팁

나는 내가 일하는 곳에서 비슷한 문제를 다루었 다. ME의 프로그래머는 모든 BLL 기능이 버려진 1 개의 컨트롤러 클래스를 만들었습니다.

우리는 현재 시스템을 재 설계하고 있으며 제어해야 할 것에 따라 많은 컨트롤러 클래스를 만들었습니다.

UserController, GeographyController, ShoppingController ...

각 컨트롤러 클래스 내에는 싱글 톤 패턴을 사용하여 캐시 또는 DAL을 호출하는 정적 메소드가 있습니다.

이것은 우리에게 두 가지 주요 장점을주었습니다. 약간 더 빠릅니다 (약 2-3 배 더 빠르지만 여기서 나노초를 말하고있었습니다; P). 다른 하나는 코드가 훨씬 깨끗하다는 것입니다

ShoppingController.ListPaymentMethods()

대신에

new ShoppingController().ListPaymentMethods()

수업이 상태를 유지하지 않으면 정적 방법이나 클래스를 사용하는 것이 합리적이라고 생각합니다.

그것은 그 객체가 포함하는 다른 것에 달려 있습니다. "객체"가 단지 많은 기능이라면 아마도 세상의 끝이 아닐 것입니다. 그러나 객체에 다른 물체가 포함 된 경우, 인스턴스팅은 모든 생성자 (및 삭제 될 때 파괴자)를 호출하고 메모리 조각화 등을 얻을 수 있습니다.

즉, 성능이 가장 큰 문제인 것처럼 들리지 않습니다.

다시 쓰기의 목표를 결정해야합니다. 멋진 테스트 가능하고 확장 가능하고 유지 관리 가능한 OO 코드를 원한다면 객체와 인스턴스 방법을 사용하려고 시도 할 수 있습니다. 결국 이것은 클래스 지향 프로그래밍이 아니라 여기서 우리가 이야기하고있는 객체 지향 프로그래밍입니다.

인터페이스를 구현하는 클래스를 정의하고 인스턴스 메소드를 실행할 때는 가짜 및/또는 모의 개체에 매우 간단합니다. 이것은 철저한 장치 테스트를 빠르고 효과적입니다.

또한 좋은 OO 원칙을 따르려면 (Solid at 참조 http://en.wikipedia.org/wiki/solid_%28object-oriented_design%29 ) 및/또는 디자인 패턴 사용 많은 정적 메소드를 사용하지 않고 많은 인스턴스 기반, 인터페이스 기반 개발을 수행 할 것입니다.

이 제안은 다음과 같습니다.

객체를 만드는 것이 바보 같은 것 같습니다. 그래서 당신은 객체에 부작용이없는 방법을 호출 할 수 있습니다 (설명에서 나는 이것을 가정합니다).

나는 이것을 Dot Net Shops에서 많이보고 나에게 이것은 핵심 OO 개념 인 캡슐화를 위반합니다. 메소드가 정적인지 여부에 따라 방법이 부작용이 있는지 여부를 알 수 없어야합니다. 파단 캡슐화뿐만 아니라 이는 부작용을 수정할 때 정적에서 인스턴스로 변경해야한다는 것을 의미합니다. 나는 당신이 이것에 대한 열린/닫는 원리를 읽고 위에서 인용 한 제안 된 접근법이 어떻게 그것을 염두에두고 어떻게 작동하는지 보는 것이 좋습니다.

오래된 밤나무, '조기 최적화는 모든 악의 근본입니다'라는 것을 기억하십시오. 이 경우 이것은 성능 문제가 있다는 것을 알기 전까지는 부적절한 기술 (즉, 클래스 지향 프로그래밍)을 사용하여 후프를 뛰어 넘지 않는다는 것을 의미합니다. 그럼에도 불구하고 문제를 디버깅하고 가장 적절한 것을 찾으십시오.

정적 방법은 훨씬 빠르며 메모리가 훨씬 적습니다. 조금 더 빠르다는 오해가 있습니다. 루프에 넣지 않는 한 조금 더 빠릅니다. BTW, 일부 루프는 작게 보이지만 실제로 루프를 포함하는 메소드 호출이 다른 루프이기 때문이 아닙니다. 렌더링 기능을 수행하는 코드의 차이를 알 수 있습니다. 많은 경우에도 기억이 훨씬 적습니다. 많은 경우에도 사실입니다. 인스턴스를 사용하면 자매 방법과 쉽게 정보를 공유 할 수 있습니다. 정적 방법은 정보가 필요할 때 정보를 요청합니다.

그러나 자동차를 운전하는 것과 마찬가지로 속도는 책임을집니다. 정적 메소드는 일반적으로 인스턴스보다 더 많은 매개 변수를 갖습니다. 인스턴스가 공유 변수를 캐싱하는 것을 관리하기 때문에 인스턴스 방법이 더 예쁘게 보입니다.

ShapeUtils.DrawCircle(stroke, pen, origin, radius);

ShapeUtils.DrawSquare(stroke, pen, x, y, width, length);

vs

ShapeUtils utils = new ShapeUtils(stroke,pen);

util.DrawCircle(origin,radius);

util.DrawSquare(x,y,width,length);

이 경우, 인스턴스 변수가 대부분의 모든 방법으로 사용될 때마다 인스턴스 메소드는 그만한 가치가 있습니다. 인스턴스는 상태에 관한 것이 아니며 공유 상태는 자연스러운 공유 형태이지만 동일하지는 않지만 공유에 관한 것입니다. 일반적인 규칙은 다음과 같습니다. 방법이 다른 방법과 밀접하게 결합된다면-그들은 서로를 너무 사랑하여 한 사람이 호출 될 때 다른 사람도 부를 필요가 있고 아마도 같은 물 컵을 공유 할 것입니다. -인스턴스를 만들어야합니다. 정적 메소드를 인스턴스 방법으로 변환하는 것은 그리 어렵지 않습니다. 공유 매개 변수 만 가져 와서 인스턴스 변수로 만 넣어야합니다. 다른 방법은 더 어렵습니다.

또는 정적 방법을 연결하는 프록시 클래스를 만들 수 있습니다. 이론에서는 더 비효율적 인 것처럼 보이지만 연습은 다른 이야기를합니다. DrawSquare를 한 번 (또는 루프) 호출해야 할 때마다 정적 메소드로 바로 이동하기 때문입니다. 그러나 DrawCircle과 함께 계속 사용할 때마다 인스턴스 프록시를 사용할 것입니다. System.io Classe FileInfo (인스턴스) vs 파일 (static)이 예를 들어 있습니다.

정적 방법은 테스트 가능합니다. 실제로 인스턴스보다 훨씬 더 테스트 가능합니다. 메소드 getSum (x, y)은 단위 테스트뿐만 아니라로드 테스트, 통합 테스트 및 사용 테스트는 매우 테스트 가능합니다. 인스턴스 방법은 단위 테스트에 적합하지만 다른 모든 테스트 (BTW보다 유닛 테스트보다 중요 함)에 끔찍합니다. 요즘 많은 버그를 얻는 이유입니다. 모든 메소드를 테스트 할 수 없게 만드는 것은 DateTime.now와 같은 글로벌 상태와 같이 의미가없는 매개 변수입니다. 실제로, 정적 방법은 테스트 가능성에 능숙하여 평균 OO 프로그래머보다 새로운 Linux 배포판의 C 코드에서 버그가 적습니다 (그는 내가 아는 S ***로 가득합니다).

나는 당신이 당신이 요청한 방식 으로이 질문에 부분적으로 대답했다고 생각합니다. 눈에 띄게 당신이 가지고있는 코드의 성능 처벌?

처벌이 눈에 띄지 않으면 반드시 아무것도 할 필요는 없습니다. (코드베이스는 점진적인 리팩터로부터 존경할만한 OO 모델로 습격 할 것이라고 말할 수는 없지만).

내가 말하는 것은 성능 문제가 문제라는 것을 알 때만 문제 일뿐입니다.

객체를 만드는 것이 바보 같은 것 같습니다. 그래서 당신은 객체에 부작용이없는 방법을 호출 할 수 있습니다 (설명에서 나는 이것을 가정합니다). 더 나은 타협은 몇 가지 글로벌 대상을 갖고 그냥 사용하는 것 같습니다. 이렇게하면 일반적으로 전 세계적으로 전 세계적으로 적절한 클래스에 넣어서 약간 더 작은 범위를 가질 수 있습니다.

거기에서 괜찮은 OOP 디자인이있을 때 까지이 객체의 범위를 더 작고 작게 옮길 수 있습니다.

그런 다음 다시, 접근 아마도 사용될 것입니다.).).

개인적으로, 나는 구조와 기능에 중점을 둘 것이며, 그 구조에 초점을 맞추고, 이들을 조금씩 멤버들과 함께 수업으로 변환하려고 시도 할 것입니다.

질문의 성능 측면에 관해서는, 정적 메소드는 물체를 구성, 통과 및 해체하지 않기 때문에 약간 더 빠르지 않아야합니다.

PHP에서 유효하지 않으며
객체 방법이 더 빠릅니다.
http://www.vanylla.it/tests/static-method-vs-object.php

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top