Class design with bi-directional relationships

This is a purely design question.

I want to port a nice educational “game” Bug Brain to Java. In this game you design neural networks which consist of three elements: neurons, nodes and synapses.
Neuron is used to perform some kind of processing on its input signals to produce the desired output; it can be connected with other neurons/nodes (connections are uni-directional and weighted). We can think about nodes can as of junctions – they can also be connected with other neurons/nodes (and these connections are also uni-directional and weighted), but the weight of we cannot change weights of input connections. Synapse is a connection between these two elements.
To sum up: neurons and nodes have both inputs and outputs (to other neurons/nodes) and they do some inputs->outputs processing.

Q: Now, how would you design this class structure?
This is a sketch I “produced” so far:
screenshot of the design

Because the operation “connect two joins (i.e. neuron/node)” has three responsibilities (add synapse, add output to join A, add input to join B) I’ve decided to put it as a static methid in a controller class.
Of course I could avoid such two-directional relationships between elements: I don’t have to keep track of outputs, only inputs but there are some other limitations eg. there can be only 8 I/Os per join so then I’d have to iterate over all synapses every time I add a connection to see if there is still some place to add it. In this case (this game) you won’t have too many connections so it would not hit performance, but I’d like to know how to deal with such situations in general.

As it’s the foundation of this whole logic of this project I’d like to have it properly made. All suggestions are warmly welcome 😉

Bi-directional associations in a class design are possible, but they always come at a hefty price, which you should know and must be willing to pay.

Generally, I like to avoid bi-directional associations with the only exception being performance. As you have mentioned, without knowing the other directions, you may have to loop through all the other objects to find the right one (or count them in your case). This may be costly, but it can also be worked around in other ways than creating a bi-directional relationship (f.ex. association classes with caches).

As you may well get hundreds of synapses, it certainly isn’t good to loop over them to be able to check if something is connectable, so I think your bi-directional association may be a valid option here. It depends on what exactly you mean with this game

won’t have too many connections.

If you can afford the looping, then I suggest you do so. If you do keep the bi-directional relationship, you will have to be extremely careful to keep your model consistent. Each time you touch one of these associations, you must ensure that you atomically update the whole model to become consistent again.

It’s hard enough to ensure that each and every modification is correctly mirrored for all involved objects / associations, but once you add concurrency to that it gets even more ugly, because you do not ever want another thread to see the model in an intermediate state, where just one direction has been added/removed yet.

Even if you use tools like Hibernate, which support the bi-directional relationships out of the box, you get other trade-offs. For example, if you combine Hibernate with eager fetching you may well end up reading your whole neural network from the database, whenever you just call for one join. That’s all part of the price to be payed.

Also note that omitting the bi-directional relationship and adding some helper class which keeps track of the number of inputs/outputs instead is not a good idea. For one, you split up the responsibility for consistent model updates to something outside of your main model, and second, the involved logic to keep things consistent needs to be added either way. You may accept the poor looping performance, or you may reasonably improve it by some cached lookup that is easier to update and need not necessarily be complete.

As a summary: Bi-directional relationships are possible, but should only be considered, when you cannot work around their absence in a feasible way.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Class design with bi-directional relationships

This is a purely design question.

I want to port a nice educational “game” Bug Brain to Java. In this game you design neural networks which consist of three elements: neurons, nodes and synapses.
Neuron is used to perform some kind of processing on its input signals to produce the desired output; it can be connected with other neurons/nodes (connections are uni-directional and weighted). We can think about nodes can as of junctions – they can also be connected with other neurons/nodes (and these connections are also uni-directional and weighted), but the weight of we cannot change weights of input connections. Synapse is a connection between these two elements.
To sum up: neurons and nodes have both inputs and outputs (to other neurons/nodes) and they do some inputs->outputs processing.

Q: Now, how would you design this class structure?
This is a sketch I “produced” so far:
screenshot of the design

Because the operation “connect two joins (i.e. neuron/node)” has three responsibilities (add synapse, add output to join A, add input to join B) I’ve decided to put it as a static methid in a controller class.
Of course I could avoid such two-directional relationships between elements: I don’t have to keep track of outputs, only inputs but there are some other limitations eg. there can be only 8 I/Os per join so then I’d have to iterate over all synapses every time I add a connection to see if there is still some place to add it. In this case (this game) you won’t have too many connections so it would not hit performance, but I’d like to know how to deal with such situations in general.

As it’s the foundation of this whole logic of this project I’d like to have it properly made. All suggestions are warmly welcome 😉

Bi-directional associations in a class design are possible, but they always come at a hefty price, which you should know and must be willing to pay.

Generally, I like to avoid bi-directional associations with the only exception being performance. As you have mentioned, without knowing the other directions, you may have to loop through all the other objects to find the right one (or count them in your case). This may be costly, but it can also be worked around in other ways than creating a bi-directional relationship (f.ex. association classes with caches).

As you may well get hundreds of synapses, it certainly isn’t good to loop over them to be able to check if something is connectable, so I think your bi-directional association may be a valid option here. It depends on what exactly you mean with this game

won’t have too many connections.

If you can afford the looping, then I suggest you do so. If you do keep the bi-directional relationship, you will have to be extremely careful to keep your model consistent. Each time you touch one of these associations, you must ensure that you atomically update the whole model to become consistent again.

It’s hard enough to ensure that each and every modification is correctly mirrored for all involved objects / associations, but once you add concurrency to that it gets even more ugly, because you do not ever want another thread to see the model in an intermediate state, where just one direction has been added/removed yet.

Even if you use tools like Hibernate, which support the bi-directional relationships out of the box, you get other trade-offs. For example, if you combine Hibernate with eager fetching you may well end up reading your whole neural network from the database, whenever you just call for one join. That’s all part of the price to be payed.

Also note that omitting the bi-directional relationship and adding some helper class which keeps track of the number of inputs/outputs instead is not a good idea. For one, you split up the responsibility for consistent model updates to something outside of your main model, and second, the involved logic to keep things consistent needs to be added either way. You may accept the poor looping performance, or you may reasonably improve it by some cached lookup that is easier to update and need not necessarily be complete.

As a summary: Bi-directional relationships are possible, but should only be considered, when you cannot work around their absence in a feasible way.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật