在子方法中使用父子 class 的什么设计模式?
What design pattern to use parent and child class with child method?
我在想建立亲子关系的时候遇到过很多次这个问题class。
我有一个基地 AuthenticateRequest
class。就我而言,我有 2 个子请求,但它们对 GetContent()
有自己的逻辑。
它并没有真正落入 Composite Pattern nor Liskov Substitution 因为基本方法是唯一的并被调用。
我应该使用哪种设计模式?
public class AuthenticateRequest
{
public string Url { get; set; }
public string ContentType { get; set; }
public string Method { get; set; }
public virtual HttpContent GetContent()
{
return new StringContent("");
}
}
public class SoapAuthenticateRequest : AuthenticateRequest
{
public string SoapMethodName { get; set; }
public string SoapAction { get; set; }
public string KeyForUserNameParameter { get; set; }
public string ValueForUserNameParameter { get; set; }
public string KeyForPasswordParameter { get; set; }
public string ValueForPasswordParameter { get; set; }
public override HttpContent GetContent()
{
var methodName = this.SoapMethodName;
var keyUsername = this.KeyForUserNameParameter;
var keyPwd = this.KeyForPasswordParameter;
var valueUsername = this.ValueForUserNameParameter;
var valuePwd = this.ValueForPasswordParameter;
var soapAction = this.SoapAction ?? @"http://tempuri.org/";
var soap = $@"<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""><soap:Body><{methodName} xmlns=""{soapAction}""><{keyUsername}>{valueUsername}</{keyUsername}><{keyPwd}>{valuePwd}</{keyPwd}></{methodName}></soap:Body></soap:Envelope>";
return new StringContent(soap, Encoding.UTF8, ContentTypes.XmlSoap);
}
}
public class JsonAuthenticateRequest : AuthenticateRequest
{
public string SoapMethodName { get; set; }
public string SoapAction { get; set; }
public Dictionary<string, string> ParameterKeyValues { get; set; }
public override HttpContent GetContent()
{
var json = JsonConvert.SerializeObject(ParameterKeyValues);
return new StringContent(json, Encoding.UTF8, ContentTypes.Json);
}
}
public async Task<AuthenticateResponse> Authenicate(AuthenticateRequest request)
{
var requestMsg = new HttpRequestMessage
{
RequestUri = new Uri(request.Url),
Method = new HttpMethod(request.Method.ToString()),
Content = request.GetContent(),
};
var responseMsg = await _httpClient.SendAsync(requestMsg).ConfigureAwait(false);
var responseContent = await responseMsg.Content.ReadAsStringAsync().ConfigureAwait(false);
return new AuthenticateResponse
{
Message = responseContent,
IsSuccess = Regex.Match(responseContent, (string)request.RegexForValidUser).Success
};
}
你见过工厂模式吗?
但是对于你的问题,要求 class 有他的正确实现。您可以简单地使用像 this
这样的抽象关键字
public abstract class AuthenticateRequest
{
public abstract HttpContent GetContent();
}
public class SoapAuthenticateRequest : AuthenticateRequest
{
public override HttpContent GetContent()
{
// your logic
return new StringContent(soap, Encoding.UTF8, ContentTypes.XmlSoap);
}
}
public class JsonAuthenticateRequest : AuthenticateRequest
{
public override HttpContent GetContent()
{
var json = JsonConvert.SerializeObject(ParameterKeyValues);
return new StringContent(json, Encoding.UTF8, ContentTypes.Json);
}
}
我在想建立亲子关系的时候遇到过很多次这个问题class。
我有一个基地 AuthenticateRequest
class。就我而言,我有 2 个子请求,但它们对 GetContent()
有自己的逻辑。
它并没有真正落入 Composite Pattern nor Liskov Substitution 因为基本方法是唯一的并被调用。
我应该使用哪种设计模式?
public class AuthenticateRequest
{
public string Url { get; set; }
public string ContentType { get; set; }
public string Method { get; set; }
public virtual HttpContent GetContent()
{
return new StringContent("");
}
}
public class SoapAuthenticateRequest : AuthenticateRequest
{
public string SoapMethodName { get; set; }
public string SoapAction { get; set; }
public string KeyForUserNameParameter { get; set; }
public string ValueForUserNameParameter { get; set; }
public string KeyForPasswordParameter { get; set; }
public string ValueForPasswordParameter { get; set; }
public override HttpContent GetContent()
{
var methodName = this.SoapMethodName;
var keyUsername = this.KeyForUserNameParameter;
var keyPwd = this.KeyForPasswordParameter;
var valueUsername = this.ValueForUserNameParameter;
var valuePwd = this.ValueForPasswordParameter;
var soapAction = this.SoapAction ?? @"http://tempuri.org/";
var soap = $@"<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""><soap:Body><{methodName} xmlns=""{soapAction}""><{keyUsername}>{valueUsername}</{keyUsername}><{keyPwd}>{valuePwd}</{keyPwd}></{methodName}></soap:Body></soap:Envelope>";
return new StringContent(soap, Encoding.UTF8, ContentTypes.XmlSoap);
}
}
public class JsonAuthenticateRequest : AuthenticateRequest
{
public string SoapMethodName { get; set; }
public string SoapAction { get; set; }
public Dictionary<string, string> ParameterKeyValues { get; set; }
public override HttpContent GetContent()
{
var json = JsonConvert.SerializeObject(ParameterKeyValues);
return new StringContent(json, Encoding.UTF8, ContentTypes.Json);
}
}
public async Task<AuthenticateResponse> Authenicate(AuthenticateRequest request)
{
var requestMsg = new HttpRequestMessage
{
RequestUri = new Uri(request.Url),
Method = new HttpMethod(request.Method.ToString()),
Content = request.GetContent(),
};
var responseMsg = await _httpClient.SendAsync(requestMsg).ConfigureAwait(false);
var responseContent = await responseMsg.Content.ReadAsStringAsync().ConfigureAwait(false);
return new AuthenticateResponse
{
Message = responseContent,
IsSuccess = Regex.Match(responseContent, (string)request.RegexForValidUser).Success
};
}
你见过工厂模式吗?
但是对于你的问题,要求 class 有他的正确实现。您可以简单地使用像 this
这样的抽象关键字public abstract class AuthenticateRequest
{
public abstract HttpContent GetContent();
}
public class SoapAuthenticateRequest : AuthenticateRequest
{
public override HttpContent GetContent()
{
// your logic
return new StringContent(soap, Encoding.UTF8, ContentTypes.XmlSoap);
}
}
public class JsonAuthenticateRequest : AuthenticateRequest
{
public override HttpContent GetContent()
{
var json = JsonConvert.SerializeObject(ParameterKeyValues);
return new StringContent(json, Encoding.UTF8, ContentTypes.Json);
}
}