如何在面向服务的体系结构中处理Java多态性

Eng*_*_DJ 13 java architecture oop soa

在面向服务的体系结构中处理实体类型的多态性和继承时,最不邪恶的道路是什么?

SOA的原则(据我所知)是将实体类仅仅作为数据结构,缺乏任何业务逻辑.所有业务逻辑都包含在窄范围,松散耦合的服务中.这意味着服务实现尽可能地进一步扩展松散耦合,并且意味着实体避免必须知道系统可能对它们执行的每个行为.

由于Java决定在决定使用哪个重载方法时使用声明的类型,因此服务实现中的任何多态行为都会被一系列条件检查object.getClass()或使用替换instanceof.在OOPL中,这似乎相当落后.

条件的使用是否是SOA中公认的标准?是否应放弃实体的继承?

UPDATE

我绝对意味着超载而不是压倒一切.

我将SOA定义为系统行为按用例分组到接口中,然后通常每个接口在一个类中实现这些行为的逻辑.因此,实体类(比如说Product)只不过是一个带有吸气剂和二传手的POJO.它绝对不应该包含任何与服务相关的业务逻辑,因为那时你引入了一个耦合焦点,实体类需要知道可能在其上运行的所有业务流程,完全否定松散耦合SOA的目的.

因此,如果不应该在实体类中嵌入特定于业务流程的行为,则不能对这些实体类使用多态 - 没有要覆盖的行为.

更新2

上述行为被更简单地解释为过载路径被选择在编译时,和重写在路径运行时.

对于它所处理的域模型类的每个子类型都有一个服务实现的子类是不好的做法,那么人们如何解决编译时的重载问题呢?

Low*_*can 6

您可以通过基于实体类型在不同类中设计业务逻辑来避免此问题,基于单一责任原则,当您将业务逻辑放在服务层并使用工厂创建逻辑实现时,这将是最佳方式,例如

enum ProductType
{
    Physical,
    Service
}


interface IProduct
{
    double getRate();
    ProductType getProductType();    
}

class PhysicalProduct implements IProduct
{
    private double rate;

    public double getRate()
    {
        return rate;
    }

    public double getProductType()
    {
        return ProductType.Physical;
    }
}

class ServiceProduct implements IProduct 
{
    private double rate;
    private double overTimeRate;
    private double maxHoursPerDayInNormalRate;

    public double getRate()
    {
        return rate;
    }

    public double getOverTimeRate()
    {
        return overTimeRate;
    }

    public double getMaxHoursPerDayInNormalRate;()
    {
        return maxHoursPerDayInNormalRate;
    }

    public double getProductType()
    {
        return ProductType.Service;
    }
}

interface IProductCalculator
{
    double calculate(double units);
}

class PhysicalProductCalculator implements IProductCalculator
{
    private PhysicalProduct product;

    public PhysicalProductCalculator(IProduct product)
    {
        this.product = (PhysicalProduct) product;
    }

    double calculate(double units)
    {
        //calculation logic goes here
    }
}

class ServiceProductCalculator implements IProductCalculator
{
    private ServiceProduct product;

    public ServiceProductCalculator(IProduct product)
    {
        this.product = (ServiceProduct) product;
    }

    double calculate(double units)
    {
        //calculation logic goes here
    }
}

class ProductCalculatorFactory
{
    public static IProductCalculator createCalculator(IProduct product)
    {
        switch (product.getProductType)
        {
            case Physical:
                return new PhysicalProductCalculator ();
            case Service:
                return new ServiceProductCalculator ();
        }
    }
}

//this can be used to execute the business logic
ProductCalculatorFactory.createCalculator(product).calculate(value);
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 4

我花了一段时间才读到你真正想要的是什么。

我的解释是,您有一组 POJO 类,当传递给服务时,您希望该服务能够根据传递给它的特定 POJO 类执行不同的操作。

通常,我会尝试避免宽或深的类型层次结构,并在需要一两种情况的情况下处理 instanceof 等。

当出于某种原因必须有一个宽类型层次结构时,我可能会使用如下所示的处理程序模式。

class Animal {

}
class Cat extends Animal {

}

interface AnimalHandler {
    void handleAnimal(Animal animal);
}

class CatHandler implements AnimalHandler {

    @Override
    public void handleAnimal(Animal animal) {
        Cat cat = (Cat)animal;
        // do something with a cat
    }

}

class AnimalServiceImpl implements AnimalHandler {
    Map<Class,AnimalHandler> animalHandlers = new HashMap<Class, AnimalHandler>();

    AnimalServiceImpl() { 
        animalHandlers.put(Cat.class, new CatHandler());
    }
    public void handleAnimal(Animal animal) {
        animalHandlers.get(animal.getClass()).handleAnimal(animal);
    }
}
Run Code Online (Sandbox Code Playgroud)