如何处理模块化应用程序中的泛型类/接口?

时间:2015-04-24 10:51:58

标签: java modularity decoupling

我是Java新手,我正在编写一个这样的模块化应用程序:

*************          *******         ***********
*           *          *     *         *   Data  *
* Front-end * -------- * API * ------- * Handler *
*           *          *     *         *         *
*************          *******         ***********

基本上,我希望能够使用N个类定义API,然后让“数据处理程序”模块处理将对象存储在某个地方(例如数据库),而不需要前端知道任何事情如何实施。

所以,假设我的API中定义了两个类:Contract和Company。 我希望前端能够做到这样的事情:

myContract = new Contract();
myCompany = new Company();
myContract.setCompany(myCompany);
myContract.save();
myCompany.save();

这样,将来我可以改变存储数据的方式(数据处理程序模块),而无需更改前端的任何代码。

为此,我在API模块中为Contract和Company编写了两个接口。 然后,在数据处理程序模块中,我写了实现两个接口的类:DbContract和DbCompany。

现在,我遇到了问题,因为我在Contract接口中定义了getter / setter方法:

public interface Contract {
    public Company getCompany();
    public void setCompany(Company company);
}

并在DbContract中实现它们:

public class DbContract implements Contract {
    private DbCompany company;

    @Override
    public Company getCompany() {
        return this.company;
    }

    @Override
    public void setCompany(Company company) {
        this.company = company;
    }
}

但是,我在整个地方都遇到类型不匹配错误... 我完全忽视了这一点吗?我该怎么做呢?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

更改

    private DbCompany company;

    private Company company;

每件事都应该是甜蜜的。

否则,您需要前端知道您正在处理的公司类型并变得通用。 这还没有编译但是像:

public interface Contract<T extends Company>{
    public T getCompany();
    public void setCompany(T company);
}

public class DbContract implements Contract<DbCompany> {
    private DbCompany company;

    @Override
    public DbCompany getCompany() {
        return this.company;
    }

    @Override
    public void setCompany(DbCompany company) {
        this.company = company;
    } 
}

答案 1 :(得分:1)

myContract = new Contract();

由于您无法创建界面实例,因此无法使用。

你似乎有正确的想法,但似乎对术语&#34;实施&#34;似乎存在误解。

如果前端需要创建这些接口的实例,则需要知道实现或提供自己的实现。另一方面,如果前端根本不知道实现,它应该调用后端来创建一个新实例。

除此之外,制作ContractCompany数据容器并移动实际逻辑以保存到服务可能是更好的设计,例如:你的代码看起来像这样:

class Contract { ... } //as before, but classes not interfaces
class Company { ... } //as before, but classes not interfaces

创建新合同:

Contract myContract = new Contract();
Company myCompany = new Company();
myContract.setCompany(myCompany);

contractService.save( myContract ); //assuming this would save the company as well

您可以查看服务或注入服务。对于后者,请看一下Spring依赖注入。

更新:

在您的评论中,您声明CompanyContract将是JPA实体,如果我理解正确,您不希望前端有任何关于使用JPA的想法。< / p>

在这种情况下,您有两种选择:

  1. 使您的对象成为普通POJO,并在后端为JPA映射添加XML。然后,您将从前端传递的每个实例视为一个分离的实体。

  2. 如果您想使用注释进行映射,并且不希望前端知道您需要提供中间层(称为数据传输对象= DTO )API使用的。然后,内部后端将在实体和DTO之间进行转换。

相关问题