여기에 코드를 느슨하게 결합시키기 위해 기억해야 할 몇 가지 간단한 사항이 있습니다.
1 부:
기술적으로 "문제의 분리"라고합니다. 각 클래스에는 특정 역할이 있으며 비즈니스 논리 또는 응용 프로그램 논리를 처리해야합니다. 두 가지 책임을 모두 갖춘 수업에서 벗어나도록 노력하십시오. 즉, 데이터를 관리하는 클래스는 애플리케이션 로직이고 데이터를 사용하는 클래스는 비즈니스 로직입니다.
개인적으로 나는 이것을 (내 자신의 작은 세계에서)로 언급합니다 create it or use it. 클래스는 객체를 생성하거나 절대 사용하지 않아야하는 객체를 사용해야합니다.
2 부:
우려 분리를 구현하는 방법.
시작점으로 두 가지 간단한 기술이 있습니다.
참고 : 디자인 패턴은 절대적이지 않습니다.
상황에 맞게 사용자 정의해야하지만 모든 응용 프로그램과 유사한 기본 테마를 갖습니다. 따라서 아래의 예를 보지 말고 이것을 엄격하게 따라야한다고 말하십시오. 이것들은 단지 예일뿐입니다.
의존성 주입 :
여기에서 클래스가 사용하는 객체를 전달합니다. 인터페이스를 기반으로 전달하는 객체는 클래스와 함께 무엇을해야하지만 실제 구현을 알 필요는 없습니다.
class Tokenizer
{
public:
Tokenizer(std::istream& s)
: stream(s)
{}
std::string nextToken() { std::string token; stream >> token;return token;}
private:
std::istream& stream;
};
여기서 스트림을 토큰 화기에 주입합니다. 토크 나이 저는 std :: istream의 인터페이스를 구현하는 한 스트림이 어떤 유형인지 알지 못합니다.
서비스 로케이터 패턴 :
서비스 로케이터 패턴은 종속성 주입에서 약간의 변형입니다. 사용할 수있는 객체를 제공하는 대신 사용하려는 객체를 찾는 방법을 알고있는 객체를 전달합니다.
class Application
{
public:
Application(Persister& p)
: persistor(p)
{}
void save()
{
std::auto_ptr<SaveDialog> saveDialog = persistor.getSaveDialog();
saveDialog.DoSaveAction();
}
void load()
{
std::auto_ptr<LoadDialog> loadDialog = persistor.getLoadDialog();
loadDialog.DoLoadAction();
}
private:
Persister& persistor;
};
여기서 우리는 애플리케이션 객체를 영속 객체로 전달합니다. 저장 /로드 조치를 수행 할 때 지속자를 사용하여 실제로 조치 수행 방법을 알고있는 오브젝트를 작성합니다. 참고 : 다시 지속자는 인터페이스이며 상황에 따라 다른 구현을 제공 할 수 있습니다.
potentially작업을 인스턴스화 할 때마다 고유 한 개체가 필요할 때 유용 합니다.
개인적으로 이것은 단위 테스트 작성에 특히 유용합니다.
패턴 노트 :
디자인 패턴은 그 자체로 큰 주제입니다. 이것은 느슨한 결합을 돕기 위해 사용할 수있는 독점적 인 패턴 목록이 아닙니다. 이것은 일반적인 출발점입니다.
경험을 통해 이미 이러한 패턴을 사용하고 있다는 것을 알게 될 것입니다. 우리는 그들의 이름을 표준화하고 모든 사람들이 그것들을 배우게함으로써 아이디어를 쉽고 빠르게 전달할 수 있다는 것을 알게되었습니다.