Programming a one-to-many relationship

后端 未结 8 807
醉话见心
醉话见心 2020-12-25 08:16

So I am surprised that doing a search on google and stackoverflow doesn\'t return more results.

In OO programming (I\'m using java), how do you correctly implement a

8条回答
  •  滥情空心
    2020-12-25 08:28

    Maybe you didn't expect a complex (and zero-code) answer, but there is no solution to build your bombproof API the way you intend it. And it's not because the paradigm (OO) or the platform (Java), but only because you made a wrong analysis. In a transactional world (every system that models real life problems and their evolution over time is transactional) This code will ever break at some point:

    // create
    Job j1 = ...
    Job j2 = ...
    ...
    // modify
    j1.doThis();
    ...
    
    // access
    j2.setSomeProperty(j1.someProperty);
    

    because at the time j1.someProperty is accessed, j1 and j2 could not even exist :)

    TL;DR

    The long answer to this is immutability, and it also introduces the concepts of life cycle and transactions. All other answers tell you how to do it, instead I want to outline why. A one-to-many relationship has two sides

    1. has many
    2. belongs to

    Your system is consistent as long as if Customer A has Job B, the Job B belongs to Customer A. You can implement this in a number of ways, but this must happen in a transaction, ie a complex action made of simple ones, and the system must be unavailble until the transaction has finished execution. Does this seem too abstract and unrelated to your question? No, it isn't :) A transactional system ensures that clients can access system's objects only if all these objects are in a valid state, hence only if the whole system is consistent. From other answers you see the amount of processing needed to solve some problems, so that guarantee comes at a cost: performance. This is the simple explanation why Java (and other general purpose OO languages) can't solve your problem out of the box.

    Of course, an OO language can be used to both model a transactional world and accessing it, but special care must be taken, some constraints must be imposed and a special programming style be required to client developers. Usually a transactional system offers two commands: search (aka query) and lock. The result of the query is immutable: it's a photo (ie a copy) of the system at the very specific moment it was taken, and modifying the photo has obviously no effect on the real world. How can one modify the system? Usually

    1. lock the system (or parts of it) if/when needed
    2. locate an object: returns a copy (a photo) of the real object which can be read and written locally
    3. modify the local copy
    4. commit the modified object, ie let the system update its state based on provided input
    5. discard any reference to (now useless) local objects: the system has changed changed, so the local copy isn't up to date.

    (BTW, can you see how the concept of life cycle is applied to local and remote objects?)

    You can go with Sets, final modifiers and so on, but until you introduce transactions and immutability, your design will have a flaw. Usually Java applications are backed by a database, which provides transactional functionalities, and often the DB is coupled with an ORM (such as Hibernate) to write object oriented code.

提交回复
热议问题