我有一个基类Address
类,它定义了基本地址属性并充当CRUD对象:
我有一个'ShipToAddress'类,它扩展了Address并包含了两个属性:
Address
包含每个属性的验证方法,ShipToAddress
仅包括对其属性(电话号码和电子邮件地址)的验证。
我的问题是,我还想在不重复代码的情况下为这两个类考虑美国和国际地址,以便我可以为州和邮政编码提供不同的验证方法。美国国家验证将确保该值是50个国家之一。国际验证只会确保它不超过数据库中允许的长度。
我如何设计它以允许任意数量的不同类型的地址(美国,加拿大等),但也有基础Address
类和ShipToAddress
类,而不重复代码?我基本上想要以下内容:
Address
基类ShipToAddress
USAAddress
USAShipToAddress
***Address
***ShipToAddress
答案 0 :(得分:5)
将AddressValidator定义为单独的接口。
public interface AddressValidator {
boolean validateAddress(ShipToAddress add);
}
创建不同的实现 - USAAddressValidator
,CanadaAddressValidator
等。
您可以Factory
根据国家/地区为您提供相应的AddressValidator
对象。
public class AddressValidatorFactory {
public static AddressValidator GetValidator(Address address) { ... }
}
您还应该考虑ShipToAddress
是extend
Address
还是contain
。您是否要通过ShipToAddress
对象预期Address
?如果没有,则ShipToAddress
不需要扩展地址。
答案 1 :(得分:2)
我可能会把它作为模板,将验证器作为模板参数传递:
class US_validator { /* ... */ };
class Int_validator { /* .. */ };
template <class Validator>
class Address {
// ...
};
template <class Validator>
class Shipping_address : public Address {
// ...
};
typedef Address<US_validator> US_Address;
typedef Address<Int_validator> Int_Address;
typedef Shipping_address<US_validator> US_Shipping_address;
typedef Shipping_address<Int_validator> Int_Shipping_address;
另一种可能性是使用多重继承,验证器作为基类。
class US_validator { /* ... */ };
class Int_validator { /* ... */ };
class Address { /* ... */ };
class Shipping_Address : public Address { /* ... */ };
class US_Shipping_Address : public US_validator, public Shipping_Address { /* ... */ };
class Int_Shipping_Address : public Int_validator, public Shipping_Address { /* ... */ };
后者几乎没有经常使用,也可能(大概)被大多数人认为是有利的,但仍然可以很好地运作。