단일 방법을 사용하는 클래스 – 최선의 접근 방법?
단일 기능을 수행하는 클래스가 있다고 가정 해보십시오. 기능을 수행 한 후에는 기능이 손상 될 수 있습니다. 이러한 접근 방법 중 하나를 선호 할 이유가 있습니까?
// Initialize arguments in constructor
MyClass myObject = new MyClass(arg1, arg2, arg3);
myObject.myMethod();
// Pass arguments to method
MyClass myObject = new MyClass();
myObject.myMethod(arg1, arg2, arg3);
// Pass arguments to static method
MyClass.myMethod(arg1, arg2, arg3);
다른 상황에 대한 지침을 얻으려고 의도적으로 세부 사항에 대해 모호했습니다. 그러나 Math.random ()과 같은 간단한 라이브러리 함수는 실제로 생각하지 않았습니다. 구체적이고 복잡한 작업을 수행하는 클래스를 더 많이 생각하고 있지만 하나의 (공용) 메소드 만 필요합니다.
정적 메소드로 채워진 유틸리티 클래스를 좋아했습니다. 그들은 다른 방법으로 중복 및 유지 관리 지옥을 초래할 수있는 도우미 방법을 크게 통합했습니다. 그것들은 사용하기 쉽고 인스턴스화도없고 폐기도 불필요합니다. 나는 이것이 서비스 지향 아키텍처를 만들기위한 첫 번째 의도하지 않은 시도라고 생각합니다. 그러나 시스템이 성장함에 따라 드래곤들이오고있다.
다형성
우리가 행복하게 울리는 UtilityClass.SomeMethod 메소드가 있다고 가정 해 봅시다. 갑자기 기능을 약간 변경해야합니다. 대부분의 기능은 동일하지만 그럼에도 불구하고 두 부분을 변경해야합니다. 정적 메서드가 아닌 경우 파생 클래스를 만들고 필요에 따라 메서드 내용을 변경할 수 있습니다. 정적 방법이므로 할 수 없습니다. 물론, 이전 메소드 이전 또는 이후에 기능을 추가해야하는 경우 새 클래스를 작성하고 그 내부에서 이전 클래스를 호출 할 수 있습니다.
인터페이스 문제
논리적 인 이유로 인터페이스를 통해 정적 메서드를 정의 할 수 없습니다. 정적 메서드를 재정의 할 수 없기 때문에 정적 클래스는 인터페이스에서 전달해야 할 때 쓸모가 없습니다. 이로 인해 전략 패턴의 일부로 정적 클래스를 사용할 수 없습니다. 인터페이스 대신 델리게이트를 전달 하여 일부 문제를 패치 할 수 있습니다 .
테스트
이것은 기본적으로 위에서 언급 한 인터페이스 문제와 밀접한 관련이 있습니다. 구현을 교환하는 능력이 매우 제한되어 있으므로 프로덕션 코드를 테스트 코드로 바꾸는 데 어려움이 있습니다. 다시 말하지만, 우리는 그것들을 마무리 할 수 있지만 실제 객체 대신 래퍼를 허용하기 위해 코드의 큰 부분을 변경해야합니다.
블랍 육성
정적 메소드는 일반적으로 유틸리티 메소드로 사용되며 유틸리티 메소드는 일반적으로 다른 목적을 가지므로, 비 일관성 기능으로 채워진 큰 클래스로 빠르게 끝나게됩니다. 이상적으로 각 클래스는 시스템 내에서 단일 목적을 가져야합니다 . 그들의 목적이 잘 정의되어 있다면 클래스의 5 배를 훨씬 더 갖고 싶습니다.
파라미터 크리프
우선, 그 귀엽고 순진한 정적 메서드에는 단일 매개 변수가 필요할 수 있습니다. 기능이 커지면 몇 가지 새로운 매개 변수가 추가됩니다. 선택적인 추가 매개 변수가 곧 추가되므로 메소드의 과부하를 작성하거나이를 지원하는 언어로 기본값을 추가합니다. 머지 않아 10 개의 매개 변수를받는 방법이 있습니다. 처음 세 개만 필요하며 매개 변수 4-7은 선택 사항입니다. 그러나 매개 변수 6을 지정하면 7-9도 채워야합니다.이 정적 메서드가 수행 한 작업을 수행하는 단일 목적으로 클래스를 만들었 으면 필요한 매개 변수를 가져 와서이 문제를 해결할 수 있습니다. 생성자 및 사용자가 속성을 통해 선택적 값을 설정하거나 여러 개의 상호 종속 값을 동시에 설정하는 방법을 허용합니다. 또한 방법이이 정도의 복잡성으로 성장한 경우
아무 이유없이 소비자에게 클래스 인스턴스를 작성하도록 요구
가장 일반적인 주장 중 하나는 왜 우리 클래스의 소비자가이 단일 메소드를 호출하기 위해 인스턴스를 작성하고 나중에 인스턴스를 사용하지 않아도되는 인스턴스를 작성해야 하는가입니다. 클래스의 인스턴스를 만드는 것은 대부분의 언어에서 매우 저렴한 작업이므로 속도는 문제가되지 않습니다. 소비자에게 추가 코드 줄을 추가하는 것은 앞으로 훨씬 더 유지 보수가 쉬운 솔루션의 기초를 마련하는 데 드는 비용이 적습니다. 마지막으로, 인스턴스 생성을 피하려면 클래스의 싱글 톤 래퍼를 작성하여 쉽게 재사용 할 수 있습니다. 이렇게하면 클래스가 무국적이어야한다는 요구 사항이됩니다. 상태가없는 경우에도 모든 것을 처리하는 정적 래퍼 메서드를 만들면서도 장기적으로 모든 이점을 얻을 수 있습니다. 드디어,
Sith만이 절대적으로 다루는 것은
물론 정적 메소드를 싫어하는 것에는 예외가 있습니다. 부 풀릴 위험이없는 진정한 유틸리티 클래스는 정적 메소드 (System.Convert)의 훌륭한 사례입니다. 프로젝트가 향후 유지 보수에 대한 요구 사항이없는 일회성이라면 전체 아키텍처는 중요하지 않습니다. 정적이든 비 정적이든 실제로 중요하지 않습니다. 그러나 개발 속도는 중요합니다.
표준, 표준, 표준!
인스턴스 메소드를 사용해도 정적 메소드를 사용할 수 없으며 그 반대도 마찬가지입니다. 차별화의 이유가 있고 표준화되어있는 한. 다른 구현 방법으로 비즈니스 계층을 살펴 보는 것보다 나쁘지 않습니다.
나는 정적 방식을 선호합니다. 클래스가 객체를 나타내지 않기 때문에 인스턴스를 만드는 것은 의미가 없습니다.
해당 메소드에만 존재하는 클래스는 정적으로 두어야합니다.
함수를 실행하기 위해 클래스의 인스턴스를 작성할 이유가없는 경우 정적 구현을 사용하십시오. 이 클래스의 소비자가 필요하지 않은 인스턴스를 만드는 이유는 무엇입니까?
객체 의 상태 를 저장할 필요가 없으면 처음에 객체를 인스턴스화 할 필요가 없습니다. 매개 변수를 전달하는 단일 정적 메서드를 사용합니다.
또한 수십 개의 관련없는 정적 메소드가있는 거대한 Utils 클래스에 대해서도 경고합니다. 이것은 서두르면 혼란스럽고 다루기 힘들 수 있습니다. 관련 메소드가 거의없는 많은 클래스를 갖는 것이 좋습니다.
I would say the Static Method format would be the better option. And I would make the class static as well, that way you wouldn't have to worry about accidentally creating an instance of the class.
I really don't know what the situation is here, but I would look at putting it as a method in one of the classes that arg1,arg2 or arg3 belong to -- If you can semantically say that one of those classes would own the method.
I'd suggest that its hard to answer based on the information provided.
My gut is that if you are just going to have one method, and that you are going to throw the class away immediately, then make it a static class that takes all the parameters.
Of course, its hard to tell exactly why you need to create a single class just for this one method. Is it the typical "Utilities class" situation as most are assuming? Or are you implementing some sort of rule class, of which there might be more in the future.
For instance, have that class be plugable. Then you'd want to create an Interface for your one method, and then you'd want to have all the parameters passed into the interface, rather than into the constructor, but you wouldn't want it to be static.
Can your class be made static?
If so, then I'd make it a 'Utilities' class that I would put all my one-function classes in.
If this method is stateless and you don't need to pass it around, then it makes the most sense to define it as static. If you DO need to pass the method around, you might consider using a delegate rather than one of your other proposed approaches.
For simple applications and internal
helpers, I would use a static method. For applications with components, I'm loving the Managed Extensibility Framework. Here's an excerpt from a document I'm writing to describe the patterns you'll find across my APIs.
- Services
- Defined by an
I[ServiceName]Service
interface. - Exported and imported by the interface type.
- The single implementation is provided by the host application and consumed internally and/or by extensions.
- The methods on the service interface are thread-safe.
- Defined by an
As a contrived example:
public interface ISettingsService
{
string ReadSetting(string name);
void WriteSetting(string name, string value);
}
[Export]
public class ObjectRequiringSettings
{
[Import]
private ISettingsService SettingsService
{
get;
set;
}
private void Foo()
{
if (SettingsService.ReadSetting("PerformFooAction") == bool.TrueString)
{
// whatever
}
}
}
I would just do everything in the constructor. like so:
new MyClass(arg1, arg2, arg3);// the constructor does everything.
or
MyClass my_object(arg1, arg2, arg3);
One more important issue to consider is whether the system would be running at a multithreaded environment, and whether it would be thread-safe to have a static method or variables...
You should pay attention to the system state.
You might be able to avoid the situation all together. Try to refactor so that you get arg1.myMethod1(arg2, arg3)
. Swap arg1 with either arg2 or arg3 if it makes more sense.
If you do not have control over the class of arg1, then decorate it :
class Arg1Decorator
private final T1 arg1;
public Arg1Decorator(T1 arg1) {
this.arg1 = arg1;
}
public T myMethod(T2 arg2, T3 arg3) {
...
}
}
arg1d = new Arg1Decorator(arg1)
arg1d.myMethod(arg2, arg3)
The reasoning is that, in OOP, data and methods processing that data belong together. Plus you get all the advantages that Mark mentionned.
i think, if properties of your class or the instance of class will not be used in constructors or in your methods, methods are not suggested to be designed like 'static' pattern. static method should be always thinked in 'help' way.
참고URL : https://stackoverflow.com/questions/205689/class-with-single-method-best-approach
'IT' 카테고리의 다른 글
jQuery에서 요소의 전체 너비 (패딩 및 테두리 포함) (0) | 2020.05.31 |
---|---|
Enter 키를 누른 후 onChange 이벤트를 호출하려면 (0) | 2020.05.31 |
테이블 행에 여백을 추가하는 방법 (0) | 2020.05.31 |
부트 스트랩이있는 고정 너비 버튼 (0) | 2020.05.31 |
Bash 스크립트에 전달 된 인수 수를 어떻게 찾습니까? (0) | 2020.05.29 |