Java 带有泛型的工厂模式
我试图用泛型实现工厂模式。我不确定我的实施是否正确Java 带有泛型的工厂模式,java,groovy,factory-pattern,Java,Groovy,Factory Pattern,我试图用泛型实现工厂模式。我不确定我的实施是否正确 interface DocumentValidator<T> { Boolean validate(Document document, T object) } class ShipmentDocumentValidator implements DocumentValidator<Shipment>{ @Override Boolean validate(Document docu
interface DocumentValidator<T> {
Boolean validate(Document document, T object)
}
class ShipmentDocumentValidator implements DocumentValidator<Shipment>{
@Override
Boolean validate(Document document, Shipment object) {
return true
}
}
class DocumentValidatorFactory {
static DocumentValidator forClass(Class clazz) {
if (clazz.simpleName.contains('Shipment')) {
return new ShipmentDocumentValidator ();
}
}
}
我不认为我应该依赖于类名,但我如何实现其他方面的功能如果您的参数是,那么比较是可行的,但是在这种情况下,您可以简单地比较类:
if (clazz == Shipment) {
return new ShipmentDocumentValidator ();
}
但您也可以使用类作为键、验证器作为值的映射:
class Shipment {}
class Invoice {}
class Document {}
interface DocumentValidator<T> {
Boolean validate(Document document, T object)
}
class ShipmentDocumentValidator implements DocumentValidator<Shipment>{
Boolean validate(Document document, Shipment object) {
true
}
}
class InvoiceDocumentValidator implements DocumentValidator<Invoice>{
Boolean validate(Document document, Invoice object) {
true
}
}
class DocumentValidatorFactory {
static DocumentValidator forClass(Class clazz) {
[
(Shipment) : ShipmentDocumentValidator,
(Invoice) : InvoiceDocumentValidator
][clazz].newInstance()
}
}
assert DocumentValidatorFactory.forClass(Shipment) instanceof ShipmentDocumentValidator
assert DocumentValidatorFactory.forClass(Invoice) instanceof InvoiceDocumentValidator
类装运{}
类别发票{}
类文档{}
接口文档验证程序{
布尔验证(文档,T对象)
}
类ShipmentDocumentValidator实现DocumentValidator{
布尔验证(文档、装运对象){
真的
}
}
类InvoiceDocumentValidator实现DocumentValidator{
布尔验证(文档、发票对象){
真的
}
}
类文档验证工厂{
类的静态文档验证程序(类clazz){
[
(装运):装运文件验证人,
(发票):InvoiceDocumentValidator
][clazz].newInstance()
}
}
断言DocumentValidatorFactory.forClass(装运)实例ShipmentDocumentValidator
断言DocumentValidatorFactory.forClass(发票)实例为InvoiceDocumentValidator
groovy的多分派方法解析可以简化工厂。例如:
class DocumentValidatorFactory {
DocumentValidator forClass(Shipment shipment) {
new ShipmentDocumentValidator()
}
DocumentValidator forClass(Invoice invoice) {
new InvoiceDocumentValidator()
}
}
public interface Validation
{
public Validator getValidator();
}
public class Shipment implements Validation
{
... whatever ...
public Validator getValidator()
{
return new ShipmentValidator();
}
}
public class Restock implements Validation
{
... whatever ...
public Validator getValidator()
{
return new RestockValidator();
}
}
public class ValidationFactory
{
public getValidator(Validation x)
{
return x.getValidator();
}
}
Groovy足够聪明,可以在运行时通过查看参数类来调用正确的方法。同上,WillP和Ataylor。让我补充一点,另一个选项是将验证器的创建放入正在验证的类中。例如:
class DocumentValidatorFactory {
DocumentValidator forClass(Shipment shipment) {
new ShipmentDocumentValidator()
}
DocumentValidator forClass(Invoice invoice) {
new InvoiceDocumentValidator()
}
}
public interface Validation
{
public Validator getValidator();
}
public class Shipment implements Validation
{
... whatever ...
public Validator getValidator()
{
return new ShipmentValidator();
}
}
public class Restock implements Validation
{
... whatever ...
public Validator getValidator()
{
return new RestockValidator();
}
}
public class ValidationFactory
{
public getValidator(Validation x)
{
return x.getValidator();
}
}
是的,检查字符串不是个好主意。没有编译时验证,因此如果您不小心键入了“Shiqment”而不是“shipping”,您将得到不正确的结果,并且没有任何警告。我曾经使用过一个系统,最初的程序员定期传递硬编码字符串,我发现numeorus的例子中代码给出的不正确,因为它们是“frieght”而不是“运费”,“shipping”而不是“shipping”(注意大写字母——如果你忽略了差异,他们也会这样做),等等。这是一个有效的解决方案,但是一旦您完成了这项工作,
ValidationFactory
添加了什么价值?您永远不会遇到这样的情况:您可以调用ValidationFactory.getValidator(x)
,而不能只调用x.getValidator()
。我认为工厂的重点是能够将文档验证的所有知识从文档本身中分离出来,它将调用方所需的验证知识从实现中分离出来。是的,被验证的东西必须知道他们的验证器是什么,而不是工厂知道他们的验证器是什么。我有点喜欢这个,非常OO,我认为。虽然我同意@ataylor,ValidationFactory
现在有点没用了。在某种程度上让我想起了@Constraint(validatedBy=Clazz)
中的自定义验证器。无论如何,我并不是说这是正确的答案,只是同一个一般问题的一种可能解决方案。我在前面试着说,有人可能仍然使用验证工厂,因为这使得调用方不需要知道如何获得验证程序,从而使它成为实现细节,而不是API的一部分。