Java 领域模型:具有特定子类别的类别
Java domain model: categories with specific subcategories
我有一个 class 产品。每个产品可以有任意数量的类别:
public class Product
{
private List<Category> categories
...
}
每个类别都有自己独特的一组子类别。例如:
- 类别 'Red' 有子类别 'Maroon'、'Orange'、'Bordeaux'
- 类别 'Blue' 有子类别 'Light'、'Dark'、'Azure'
对于每组子类别,我创建了一个具有可能静态值的枚举:
public enum RedSubCategory
{
MAROON, ORANGE, BORDEAUX;
}
public enum BlueSubCategory
{
LIGHT, DARK, AZURE;
}
我现在正在努力创建类别 class。因为每个类别都有很好的定义,所以我想把它做成一个枚举。然而,每个枚举值都应该有一个不同子类型的子类别列表,这是行不通的:
public enum Category
{
RED, BLUE;
private List<SubCategory> subCategories;
// This won't work! SubCategory is not a real class and the
// SubCategory enums can't extend from a common supertype!
public setSubCategories(List<SubCategory> subCategories)
{
this.subCategories : subCategories;
}
}
如果我将类别设为 a class 而不是枚举,我 运行 也会遇到同样的问题。我可以使用泛型来解决这个问题,但是我丢失了所有可能类别的静态定义。此外,如何才能使类别 RED 成为唯一可以使用 RedSubCategories 的类别?通过将 class 与泛型一起使用,没有什么可以阻止我创建具有类别 "blue" 和红色子类别的类别对象!
我可以在这里使用任何模式或 inheritance/generics 技巧吗?
可能正在使用 java 接口:
package basic;
import static basic.SubCatMain.RedSubCategory.*;
import static basic.SubCatMain.BlueSubCategory.*;
public class SubCatMain {
public interface Category {
}
public enum MainCategory implements Category {
RED(MAROON, ORANGE, BORDEAUX),
BLUE(LIGHT, DARK, AZURE);
final private Category[] subcategories;
private MainCategory(Category... subcategories) {
this.subcategories = subcategories;
}
public Category[] getSubcategories() {
return subcategories;
}
}
public enum RedSubCategory implements Category {
MAROON, ORANGE, BORDEAUX;
}
public enum BlueSubCategory implements Category {
LIGHT, DARK, AZURE;
}
public static void main(String[] args) {
// do something with your categories
}
}
编辑
@user1884155:大约 "I want to ensure a product cannot have a red category but a list of blue subcategories"。
我认为您不能仅在编译时使用强制转换来做到这一点。编译器无法知道哪个主要类别将提供给 Product ctor。
需要编写一些业务规则,例如:
public static class Product {
final private MainCategory category;
private Category[] categories;
public Product(MainCategory category) {
this.category = category;
}
protected void checkCategoriesAreValid(Category... categories) {
// throw an exception if at least one of the categories
// is not valid in respect of some business rules
// by default any sub-category of a main one is ok
List refs = Arrays.asList(category.getSubcategories());
for(Category c:categories) {
if (!refs.contains(c)) {
throw new IllegalArgumentException("...");
}
}
}
public Category[] getCategories() {
return categories;
}
public void setCategories(Category... categories) {
checkCategoriesAreValid(categories);
this.categories = categories;
}
}
我有一个 class 产品。每个产品可以有任意数量的类别:
public class Product
{
private List<Category> categories
...
}
每个类别都有自己独特的一组子类别。例如:
- 类别 'Red' 有子类别 'Maroon'、'Orange'、'Bordeaux'
- 类别 'Blue' 有子类别 'Light'、'Dark'、'Azure'
对于每组子类别,我创建了一个具有可能静态值的枚举:
public enum RedSubCategory
{
MAROON, ORANGE, BORDEAUX;
}
public enum BlueSubCategory
{
LIGHT, DARK, AZURE;
}
我现在正在努力创建类别 class。因为每个类别都有很好的定义,所以我想把它做成一个枚举。然而,每个枚举值都应该有一个不同子类型的子类别列表,这是行不通的:
public enum Category
{
RED, BLUE;
private List<SubCategory> subCategories;
// This won't work! SubCategory is not a real class and the
// SubCategory enums can't extend from a common supertype!
public setSubCategories(List<SubCategory> subCategories)
{
this.subCategories : subCategories;
}
}
如果我将类别设为 a class 而不是枚举,我 运行 也会遇到同样的问题。我可以使用泛型来解决这个问题,但是我丢失了所有可能类别的静态定义。此外,如何才能使类别 RED 成为唯一可以使用 RedSubCategories 的类别?通过将 class 与泛型一起使用,没有什么可以阻止我创建具有类别 "blue" 和红色子类别的类别对象!
我可以在这里使用任何模式或 inheritance/generics 技巧吗?
可能正在使用 java 接口:
package basic;
import static basic.SubCatMain.RedSubCategory.*;
import static basic.SubCatMain.BlueSubCategory.*;
public class SubCatMain {
public interface Category {
}
public enum MainCategory implements Category {
RED(MAROON, ORANGE, BORDEAUX),
BLUE(LIGHT, DARK, AZURE);
final private Category[] subcategories;
private MainCategory(Category... subcategories) {
this.subcategories = subcategories;
}
public Category[] getSubcategories() {
return subcategories;
}
}
public enum RedSubCategory implements Category {
MAROON, ORANGE, BORDEAUX;
}
public enum BlueSubCategory implements Category {
LIGHT, DARK, AZURE;
}
public static void main(String[] args) {
// do something with your categories
}
}
编辑
@user1884155:大约 "I want to ensure a product cannot have a red category but a list of blue subcategories"。
我认为您不能仅在编译时使用强制转换来做到这一点。编译器无法知道哪个主要类别将提供给 Product ctor。 需要编写一些业务规则,例如:
public static class Product {
final private MainCategory category;
private Category[] categories;
public Product(MainCategory category) {
this.category = category;
}
protected void checkCategoriesAreValid(Category... categories) {
// throw an exception if at least one of the categories
// is not valid in respect of some business rules
// by default any sub-category of a main one is ok
List refs = Arrays.asList(category.getSubcategories());
for(Category c:categories) {
if (!refs.contains(c)) {
throw new IllegalArgumentException("...");
}
}
}
public Category[] getCategories() {
return categories;
}
public void setCategories(Category... categories) {
checkCategoriesAreValid(categories);
this.categories = categories;
}
}