연결에 실패하면 연결 개체가 실제로 작동하지 않는 경우 다른 모든 메서드가 항상 아무 작업도 수행하지 않거나 예외를 throw하면 해당 개체를 존재하게하는 것이 바람직하지 않습니다. 이러한 이유로 나는 생성자에서 연결을 수행하고이 메서드가 실패 할 경우 예외 (std::exception
에서 파생 됨)를 throw하여 실패합니다.
그러나 클래스의 클라이언트가 생성자가 차단되거나 실패 할 수 있다는 사실을 알고 있어야 할 수도 있습니다. 이런 이유로 나는 생성자를 private으로 만들고 클라이언트가 명시적인 MakeConnection
호출을해야하도록 정적 팩토리 메소드 (생성자 관용법)를 사용하도록 선택할 수 있습니다.
연결이 끊어 졌는지 또는 오프라인 모드를 처리 할 수 있는지 여부를 결정하는 것은 고객의 책임입니다. 전자의 경우 값으로 연결을 소유 할 수 있으며 모든 연결 실패가 클라이언트에 전파되도록 할 수 있습니다. 후자에서는 포인터를 통해 오브젝트를 소유 할 수 있으며, '스마트'가 바람직합니다. 후자의 경우 생성자에서 소유 된 연결의 생성을 시도하거나 필요할 때까지 지연시킬 수 있습니다.
예. (경고 : 코드는 모두 완전히 테스트되지 않았습니다.)
class Connection
{
Connection(); // Actually make the connection, may throw
// ...
public:
static Connection MakeConnection() { return Connection(); }
// ...
};
다음은 작동 연결이 필요한 클래스입니다.
class MustHaveConnection
{
public:
// You can't create a MustHaveConnection if `MakeConnection` fails
MustHaveConnection()
: _connection(Connection::MakeConnection())
{
}
private:
Connection _connection;
};
다음은 하나도없이 작동하는 클래스입니다.
class OptionalConnection
{
public:
// You can create a OptionalConnectionif `MakeConnection` fails
// 'offline' mode can be determined by whether _connection is NULL
OptionalConnection()
{
try
{
_connection.reset(new Connection(Connection::MakeConnection()));
}
catch (const std::exception&)
{
// Failure *is* an option, it would be better to capture a more
// specific exception if possible.
}
}
OptionalConnection(const OptionalConnection&);
OptionalConnection& operator=(const OptionalConnection&);
private:
std::auto_ptr<Connection> _connection;
}
마지막으로 필요에 따라 하나를 만들고 호출자에게 예외를 전파합니다.
class OnDemandConnection
{
public:
OnDemandConnection()
{
}
OnDemandConnection(const OnDemandConnection&);
OnDemandConnection& operator=(const OnDemandConnection&);
// Propgates exceptions to caller
void UseConnection()
{
if (_connection.get() == NULL)
_connection.reset(new Connection(Connection::MakeConnection()));
// do something with _connection
}
private:
std::auto_ptr<Connection> _connection;
}
블록 생성자가 의미있는 RATI 기반 잠금을 사용하는 경우는 물론 예외가 있습니다. 물론 문서화와 적절한 명명이 중요합니다. –
+1 별도의 연결 메소드에서 차단 작업을 수행하면 해당 작업을 취소하는 'cancel'메소드가 열려있는 상태로 두십시오. –