面向服务体系结构中如何处理Java多态性
在面向服务的体系结构中处理实体类型的多态性和继承时,什么是最安全的路径 SOA的一个原则(据我所知)是将实体类作为纯粹的数据构造,缺少任何业务逻辑。所有业务逻辑都包含在范围狭窄、松散耦合的服务中。这意味着服务实现尽可能小,从而进一步促进松耦合,并意味着实体不必知道系统可能对其执行的每一种行为 ,服务实现中的任何多态行为都将替换为一系列条件检查面向服务体系结构中如何处理Java多态性,java,oop,architecture,soa,Java,Oop,Architecture,Soa,在面向服务的体系结构中处理实体类型的多态性和继承时,什么是最安全的路径 SOA的一个原则(据我所知)是将实体类作为纯粹的数据构造,缺少任何业务逻辑。所有业务逻辑都包含在范围狭窄、松散耦合的服务中。这意味着服务实现尽可能小,从而进一步促进松耦合,并意味着实体不必知道系统可能对其执行的每一种行为 ,服务实现中的任何多态行为都将替换为一系列条件检查object.getClass()或使用instanceof。在OOPL中,这似乎相当落后 使用条件句是SOA中公认的规范吗?是否应该放弃实体中的继承 更新
object.getClass()
或使用instanceof
。在OOPL中,这似乎相当落后
使用条件句是SOA中公认的规范吗?是否应该放弃实体中的继承
更新
我肯定是指重载而不是重写
我将SOA定义为指系统的行为按用例分组到接口中,然后通常在每个接口的一个类中实现这些行为的逻辑。这样一个实体类(比如说产品)就变成了一个带有getter和setter的POJO。它绝对不应该包含任何与服务相关的业务逻辑,因为这样就引入了一个耦合焦点,实体类需要了解可能在其上运行的所有业务流程,这完全否定了松耦合SOA的目的
因此,由于不应在实体类中嵌入特定于业务流程的行为,因此不能对这些实体类使用多态性—没有可重写的行为
更新2
以上行为更简单地解释为在编译时选择重载路径,在运行时选择重写路径
为服务实现的每个域模型类的子类型指定一个子类是一种不好的做法,那么人们如何避免编译时的重载问题呢
由于Java非常令人困惑地决定在
决定使用哪个重载方法
是谁给你这个主意的?如果Java是这样的话,它将是一种毫无价值的语言
请阅读以下内容:
下面是一个简单的测试程序:
public class Tester{
static class Foo {
void foo() {
System.out.println("foo");
}
}
static class Bar extends Foo {
@Override
void foo() {
System.out.println("bar");
}
}
public static void main(final String[] args) {
final Foo foo = new Bar();
foo.foo();
}
}
您可以通过基于实体类型、基于单一责任原则在不同类别中设计业务逻辑来避免此问题。例如,将业务逻辑放置在服务层并使用工厂创建逻辑实现时,这将是最好的方法
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);
我认为这里有一种混乱的担忧。SOA是解决组件之间交互的体系结构方法。SOA解决方案中的每个组件将处理更大域中的上下文。每个上下文都是其自身的一个域。换句话说,SOA允许域上下文或应用程序之间失去耦合
当在这种环境中工作时,Java中的面向对象将应用于每个域。因此,使用类似于域驱动设计的方法建模的层次结构和丰富的域对象将位于SOA解决方案中服务的底层。在暴露于其他上下文的服务和详细的域模型之间有一个层,该层将创建丰富的对象供域使用
使用SOA解决每个上下文/应用程序体系结构并不能提供很好的应用程序。正如使用OO解决它们之间的交互一样
为了更具体地回答悬赏问题:
这不是围绕这个问题的工程问题。这是一个将正确的模式应用到每个设计层次的问题
对于大型企业生态系统,SOA是我解决系统之间交互的方式,例如人力资源系统和工资单。但是在处理人力资源(或者可能是人力资源中的每个上下文)和工资单时,我会使用DDD中的模式
我希望这能让事情变得明朗一点。我花了一段时间读完这篇文章,才明白你真正想要的是什么
我的解释是,您有一组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);
}
}
类动物{
}
猫科动物{
}
界面动物处理程序{
动物;
}
类CatHandler实现AnimalHandler{
@凌驾
公共动物(动物){
猫=(猫)动物;
//对猫做点什么
}
}
类AnimalServiceImpl实现AnimalHandler{
Map animalHandlers=new HashMap();
AnimalServiceImpl(){
put(Cat.class,new CatHandler());
}
公共动物(动物){
animalHandlers.get(animal.getClass()).handleAnimal(animal);
}
}
考虑过这一点后,我想到了一种更简单的设计方法
abstract class Animal {
}
class Cat extends Animal {
public String meow() {
return "Meow";
}
}
class Dog extends Animal {
public String bark() {
return "Bark";
}
}
class AnimalService {
public String getSound(Animal animal) {
try {
Method method = this.getClass().getMethod("getSound", animal.getClass());
return (String) method.invoke(this, animal);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String getSound(Cat cat) {
return cat.meow();
}
public String getSound(Dog dog) {
return dog.bark();
}
}
public static void main(String[] args) {
AnimalService animalService = new AnimalService();
List<Animal> animals = new ArrayList<Animal>();
animals.add(new Cat());
animals.add(new Dog());
for (Animal animal : animals) {
String sound = animalService.getSound(animal);
System.out.println(sound);
}
}
抽象类动物{
}
猫科动物{
公共字符串meow(){
返回“喵喵”;
}
}
狗类动物{
公共字符串(){
返回“树皮”;
}
}
类动物服务{
公共字符串getSound(动物){
试一试{
方法Method=this.getClass().getMethod(“getSound”,animal.getClass());
return(String)方法。invoke(this,animal);
}捕获(例外e){
抛出新的运行时异常(e);
}
}
公共字符串getSound(Cat)