4 ms·
Show HN: The Obvious Architecture
- programminggeek 14y agoI'm one of the creators of Obvious. If you have any questions, fire away!
- huherto 14y ago> The fundamental data structure of data transport between layers is a hash. This is for both incoming and outgoing data from the each layer. There are many benefits to this approach. The biggest benefit is that each layer stays decoupled from the other layers and that hashes act as messages passed between the layers. If I understand correctly, the only thing this is doing is converting a compile time dependency into a run time dependency. But the dependency is there nevertheless in the names of the fields, types, etc.
- programminggeek 14y agoWell for now Obvious is implemented in ruby, so everything happens at runtime. There is no explicit dependency between layers. Dependency injection is used to pass the data jacks into the actions. That allows for incredibly fast tests and pluggable data persistence.
- bryanthompson 14y agoAfter I saw @unclebobmartin speak at Ruby Midwest last year, I got so flipping excited. I walked away with goals of having tests that ran instantly, layers that were as independent as possible, and wanted to build this master framework he described so cryptically. I think programminggeek nailed it here. If you watch Bob's talk, then watch the Obvious screencast, you'll see that this is a serious attempt at this dream architecture. http://www.confreaks.com/videos/759-rubymidwest2011-keynote-architecture-the-lost-years http://www.confreaks.com/videos/759-rubymidwest2011-keynote-...
- joyinsky 14y agoDoes any functional example of this architecture exists?
- programminggeek 14y agoYep, there is an example twitter clone called Status. https://github.com/RetroMocha/obvious_status https://github.com/RetroMocha/obvious_status It can run as a rails app, sinatra web app, sinatra api app, command line app, or desktop app using jruby. Backend database is pluggable and can use json files, mongo, mysql, or even its own api as a data source without switching the application code itself.
- ttiurani 14y agoReally cool! However I'm struggling a bit to see how to use the architecture in larger projects. I have a (grandiose) idea for a group of web sites with the following structure: * Backend server A provides a REST API and stores data to a NoSQL database. * Website B communicates with A or can work standalone with MySQL. * Android client C communicates with A, and also caches data to its own SQLite database for off-line access. A is written in Scala, B in Python and C is native Android. How would you use Obvious in this scenario? Is it one big Obvious architecture or three separate Obvious instances? The REST API here is both a delivery and a plug, no?
- programminggeek 14y agoWow, that's a crazy structure. I like it. Conceptually, Obvious is language-independent, but for now it's only implemented in Ruby. It would be pretty easy to implement elsewhere in Java, Scala, Python, or whatever. That being said, in each instance you could use the Obvious approach to structure each app. If you were using the same language in each place, you could theoretically reuse the "app" structure in multiple places, so that your same business rules and validations would exist in each instance. For the structure you describe, if you were willing to do Website B in something that worked with the JVM, you could write your "app" in Java or Scala and package it as a JAR file. So, you could use Jython to run your python code on the JVM. Then, you could reuse your app library in each project. Assuming your app is a JAR file, your structure would look like this: REST API - Scala for delivery -> App JAR -> NoSQL plug Website - Java, Scala, Jruby, or Jython for delivery? -> App JAR -> API plug or MySQL plug Android - Java for delivery -> App JAR -> SQLite db plug & API plug If you were able to run the whole thing on the JVM you could place them all in one project, or separate projects, it's really up to you. And yes, the REST API would act as a delivery mechanism for system A and a plug for systems B and C.
- ttiurani 14y agoThe motivation for the two server backend is that I currently have one working standalone B and will build a second B soon to serve a closely related purpose, and really don't want to duplicate the work or the data. That's why a backend server that stores common data and also most of the heavy business logic looks like the best solution at the moment. Obvious seems like a very good fit for all the B's (closely related Python websites). But I don't know about Scala backend though: do you have thoughts on packaging of different deliveries for static languages in Obvious? Because if there is only one folder structure, you typically (with Maven) get only one JAR. To get many JARs the folder structure quickly turns into: app/actions/common/src/main/scala app/actions/featureset1/src/main/scala app/actions/featureset2/src/main/scala delivery/plug1/src/main/scala delivery/plug2/src/main/scala etc. which isn't very pretty nor obvious (sic!). The other option I can think of is to have one big JAR that always has every plug and delivery baked in with a folder structure like: src/main/scala/[Obvious folders] and plugs and deliveries would then need to be activated runtime with configuration files. But that also seems sub-optimal: I don't want to have any code in production I'm not going to use. Am I missing something?
- przemekpokrywka 14y agoHow does Obvious relate to Hexagonal Architecture (AKA Ports-and-Adapters, http://alistair.cockburn.us/Hexagonal+architecture http://alistair.cockburn.us/Hexagonal+architecture)? I'd like to suggest that it's not bad, but others have found the right answer already. Or does Hexagonal leave some important problems unsolved?
- programminggeek 14y agoObvious is a clean architecture more directly in the style of Uncle Bob's Screaming Architecture. It's actually a kind of hybrid between Screaming Architecture and Ports-and-Adapters. In fact, I looked at Hexagonal architecture a lot and purposely avoided the terms ports and adapters in place of jacks and plugs even though they are conceptually the same idea. The key difference in Obvious is that it tries to be more purposeful in the naming and the structure of the parts of your application. The "app" describes your business logic and entities, the "external" defines external interfaces to data sources, and the "delivery" defines the delivery mechanism like a web app, command line, rich client, or whatever. To drill down deeper into things being given obvious names and structure, the "app" is structured with single purpose use case objects called actions. Core data structures(business objects) are defined by entity objects. In that structure you can look at the app folder and see what the system data is and what the system does. The idea is that the system's intent and functionality would scream at you just by looking at it from a high level. Uncle Bob's keynote at Ruby Midwest 2011 articulates it a bit better than maybe I do - http://www.confreaks.com/videos/759-rubymidwest2011-keynote-architecture-the-lost-years http://www.confreaks.com/videos/759-rubymidwest2011-keynote-...