I have the following folder structure for my application
app
core
features
feature1
domain
entities
entity1
entity2
entity3
entity4
entity5
entity6
data
models
model1
model2
model3
model4
model5
model6
presentation
feature2
domain
entities
entity1
entity2
entity3
entity4
entity5
entity6
data
models
model1
model2
model3
model4
model5
model6
presentation
Model 1 to 6 for both features are exactly the same and more are coming as the application scales. This is becoming hard to maintain. Does clean architecture allow for sharing models and entities across the multiple features? Would that be done through the core folder?
Yes you can and you maybe should not do it.
Yes, because the clean architecture doesn't make a statement about this. As long as the dependency rule is honored you are compliant in terms of the clean architecture.
But you maybe should not do it, because there are other principles and considerations you should take into account.
First, you should ask your self if it would be a violation of the single responsiblility principle. Sometimes things look the same but are not really douplicated code. It's more an accident that they look the same. The question is "Who is the change trigger?". Usually the features change for different reasons and thus the features use cases and entities change for different reasons. If so you should not share the models between them.
Second, from a DDD (domain driven design) perspective the features can be in different bounded contexts. In this case you can have two entities with the same name, but they have different meanings in the differnt context. Therefore, the models have different properties and different methods.
If you decide to share the modles you should take a close look at them in intervalls and scan the properties and methods. Are there properties and methods that are exclusively dedicated to one feature? If so you are maybe mixing concerns.
Finally if you are facing problems like "Uhh, we changed someting here and broke something there", you should rethink if the sharing of some code is a good way to go. Sharing of code always couples code, because all clients depend on the shared code. It's a trade off between duplication (maintenance costs) and dependencies. Principles like the SRP help you to make an educated guess.
Does clean architecture allow for sharing models and entities across the multiple features?
I think DRY principles should be applied whether you use clean architecture or not.
As for the answer:
I think you could abstract your shared models and entities into separate modules or packages. If it's all dart code, I suggest choosing packages. You can place it inside the root project (Monorepo) or separate it to another repository, this way you could achieve modularity by abstracting the all layer of shared dependency (abstract class, interface, clients, or maybe repositories) out of the main application
There is a good video about this topic on Google I/O'19, it is about Android but you can get great insight and applied to general mobile development. I suggest you give it a try
I'm assuming you're following the ResoCoder course. I did too. I used that design in our team for a few weeks before realizing there soon become problems with it (which ResoCoder himself realizes if you check the Github issues and responses for his repo):
Sharing between features doesn't work well.
It's hard to have functionality split between multiple features.
Not well organized with a lot of code.
Some more which I forget off the top of my head (He wrote some article on the failing of it somewhere).
Hence, for my team's app (getting quite complex now), we've adapted this which seems to work:
(ignore the 2 \core directories, that's by mistake. There's meant to be only 1)
Then, inside all of these top-level directories (excluding /core - that's specifically for things like API clients, routers, etc.), there's folders for each feature. Ex: authentication, settings, posting, etc.
Then, here's the important bit, in each of these feature-split directories (ex: /domain, /presentation, etc.) we have a sub-directory called /shared that resembles what each folder needs to look like, except it just contains functionality that's categorized as (example) domain or data. This stuff is then split between all features.
For example, if I have an app that allows users to post content, I'm going to create the post entity (using ResoCoder terminology) inside the /posts feature. Except, UH OH, I need to have it displayed inside the /feed feature as well! This is then a perfect case for /shared inside the general /domain directory.
Let me know if this helps, or if you have any further questions!
Related
We are working on a bigger project with Ruby on Rails. As you might know, Rails works with MVC pattern and typically enforces the following class types for Domain objects:
Controllers (+ Helpers)
Models
Views (e.g. erb)
Serializers
Mailers
We experienced - like many other teams - that this is not feasible for bigger, long-running projects.
So in our current project, we added some layers, so we typically have
Controllers (+ Helpers)
Policies (access control per controller)
Presenters (a.k.a ViewModel)
Forms (containing all attributes available in an HTML form)
Views
Models
Queries (static ActiveRecord queries)
Serializers
Mailers
Services (Domain Service which extracts business code from controller)
It is much more testable, maintainable and understandable.
However, our boss disagrees with "These are too many classes".
As he is typically a proficient architect (doing consulting), I don't want to simply reject this response. However, his time as active Java developer are gone and he often explains such sentences with his improved "gut feeling".
Of course, there are metrics that count classes - but is there a general approach to classify something like 'Classes per Domain object' or 'Class per Business case', which can be taken for an argument?
I have never heard of a rule or best practice which limits a number of classes per project, domain or whatever. One should create as many classes as he REALLY needs. The key word here is "REALLY" because quite often developers over complicate things and create unnecessary classes, layers or even tiers. Without the details about your project I suggest you do the following:
Ask your boss to elaborate on the "Too many classes" phrase. Ask for his concerns. If he is a good architect and a team member he understands his responsibility of coaching people.
Make sure you clearly explained to him why you needed those classes. Provide examples.
If your boss is stubborn, his best days as a developer are gone and he just wants to show his significance, remind him about his responsibility for a successful project. For example, tell him he is an architect and a person who makes the final decision and you will follow it because he is the one who is responsible for the project success but on the other hand it's your responsibility to be proactive and express any concerns you have to help your boss make the right decision. This should make your boss think again as he doesn't want to fail the project because of his "gut feeling".
Hope it helps!
I'm using the Entity Framework 4.1 and ASP.Net MVC 3 for my application. MVC provides the presentation layer, an intermediate library provides the business logic and the Entity Framework sort of acts as the data layer I guess?
I could separate the Entity Framework code into a set of repository classes, or an appropriate variation thereof, whatever constitutes a worthwhile data layer, but I'm having trouble resolving a design problem I have.
If the multi-layered approach exists to help me keep concerns separated, then it stands to reason that my choice of data persistence should also not be a concern of the presentation layer. The problem is that by using the Entity Framework, I'm basically tightly coupling my application to the notion that entity changes are tracked and persisted automatically.
As such, let's say in a hypothetical world I found a reason not to use the Entity Framework and wanted to swap it out. A well-designed solution should allow me to do this at the appropriate layer and not have dependent layers affected, but because all code is being written with the knowledge that the data layer tracks object changes, I would only be able to swap out the Entity Framework for something that works in a similar fashion, for example nHibernate.
How do I get to use the Entity Framework but not need to write my code in a way that assumes that entity changes are being tracked by the data layer?
UPDATE for those still wondering about this issue in their own scenarios:
Ayende Rahien wrote a great article shooting down this whole argument:
http://ayende.com/blog/4567/the-false-myth-of-encapsulating-data-access-in-the-dal
If you want to continue this way you should give up programming job and go to study philosophy. Entity framework is abstraction of persistence and there is a rule of Leaky abstraction which says that any non-trivial abstraction is to some degree leaky.
Agile methodologies come with really interesting phenomenon: Do not prepare for hypothetical situations. The most of the time it is just Gold plating. Each change has its cost. Changing persistence layer later in the project is costly but it is also very rare. From customer perspective there is no reason to pay part of these costs in the most of projects where this change is not needed. If we discus customer perspective more deeply we can say that he should not pay for that at all because choosing bad API which has to be replaced later on is failure of developers / architects. Refactor your code regularly but only to the point which is needed for adding new features which customer wants otherwise you can hardly be competitive on the market. This of course has some exceptions:
Customer wants (or architecture demands it for any reason and customer agrees with it) such abstraction. In such case you must count with it and define architecture open for such changes.
It is hobby or open source project where you can do what you want because it is not constrained by some resources
Now to your problem. If you want such high level abstraction you should not expose entities to your controller. Expose DTOs from the business layer (or even from repositories) and add fields like IsNew, IsModified, IsDeleted to those DTOs. Now your UI is completely separated from the persistence but your architecture is much more complex and there is probably no reason for such complexity - it is over architected. Another way can be simply turning off tracking (add AsNoTracking() to each query) and proxy creation on your entities (context.Configuration.ProxyCreationEnabled) - lazy loading will not work as well. That's like throwing away most of features persistence frameworks offer to you.
There are also other points of view. I recommend you reading Ayende's recent posts about repository and his comments to Sharp architecture.
Short answer? You don't. You could turn off EF's tracking and then not worry about it, but that's about it.
If you're going to write your presentation layer with the expectation that changes are being tracked and persisted automatically, then whatever you replace EF with has to do that. You can't swap it out for something that doesn't track and persist changes automatically and just expect things to keep working. That'd be like taking a system that relies on a TCP/IP connection for duplex communication, swapping it to a HTTP connection (which by the nature of HTTP isn't really duplex) and expect things to work the same way. It doesn't.
If you want to be able to swap out your persistence layer for something else and not have to change anything else, then you need to wrap EF (or whatever) in your own custom code to provide the functionality you want. Then you have to provide implementations for anything not provided by whatever you swap to.
This is doable, but it's going to be an awful lot of work for a problem that very rarely actually happens. It's also going to add extra complexity to the project. Ladislav is bang on: it's not worth abstracting this far.
You should implement the repository pattern and plain POCOS if you are concerned about potentially swapping out EF.
There is a great project on Codeplex that goes over Domain Driven design including documentation. Take a look at that.
http://microsoftnlayerapp.codeplex.com/
Please after reading Microsoft n-layer project, read ayenede's weblog.
Mr.ayende posted series posts about advantage and disadvantage Microsoft n-layer project.
This thread introduced two different approaches to a fundamental need of every web-app - email-based interactions with a site's users - the uses the term MailManager. I'm currently suffering the pain of a poorly designed, first gen attempt at generating (and sending, and logging, and searching) things like invoices, notifications, followups and tracking. Stuff that wasn't in the original spec. I understand the need to refine things to use a more generalized controller.
So i'd like to study how this functionality has been implemented in other projects. Is this role generic or well defined enough that perhaps one of the codeplex or git projects (or an MVC-based tutorials) has a fleshed out example?
I've noticed in pretty much every company I've worked that they have a common library that is generally shared across a number of projects. More often than not this has been a single companyx-commons project that ends up as a dumping ground for common programs including:
Command Line Parsers
File Utilities
Framework Helpers
etc...
Some of these are well thought out and some duplicate functionality found in Apache commons-lang, commons-io etc..
What are the things you have in your common library and more importantly how do you structure the common libraries to make them easy to improve and incorporate across other projects?
In my experience, the single biggest factor in the success of a common library is user buy-in; users in this case being other developers; and culture of your workplace/team(s) will be a big factor.
Separate libraries (projects/assemblies if you're in .Net) for different application tiers is essential (e.g: there's obviously no point putting UI and data access code together).
Keep things as simple as possible; what you don't put in a common library is often at least as important as what you do. Users of the library won't want to have to think, so usage needs to be super easy.
The golden rule we stuck to was keeping individual functions focused on a single task - do one thing and do it well (or very very well); don't try and provide something that tries to take every possibility into account, the more reusable you think you're making it - the less likely it is to be used. Code Complete (the book) has some excellent content on common libraries.
A good approach to setting/improving a library up is to do regular code reviews and retrospectives; find good candidates that you've already come up with and consider re-factoring them into a library for future projects; a good candidate will be something that more than one developer has had to do on more that one project (for example).
Set-up some sort of simple and clear governance of the libraries - someone who can 'own' a specific library and ensure it's overal quality (such as a senior dev or team lead).
I have so far written most of the common libraries we use at our office.
We have certain button classes that are just slightly more useful to us than the standard buttons
A database management class that does some internal caching and can connect to ODBC, OLEDB, SQL, and Access databases without even the flip of a parameter
Some grid and list controls that are multi threaded so we can add large amounts of data to them without the program slowing and without having to write all the multithreading code every time there is a performance issue with a list box/combo box.
These classes make it easier for all of us to work on each other's code and know how exactly they work since we all use the exact same interfaces throughout our products.
As far as organization goes, all of the DLL's are stored along with their source code on a shared development drive in the office that we all have access to. (We're a pretty small shop)
We split our libraries by function.
Commmon.Ui.dll has base classes for ui elements.
Common.Data.Dll is sort of a wrapper around Enterprise library Data access classes.
Common.Business is a dumping ground for other common classes that don't fit into one of those.
We create other specialized dlls as needs arise.
Update: This question was inspired by my larger quest for mapping ontologically the whole software systems architecture enchilada. I've written a blog post about it, and hopefully it will help clarify what I'm after.
Many, many, many frameworks and stacks that's event-driven have too much variation for my little head to get around. Is there somewhere some resources that defines the outline of a reasonable Application Event Model, what events there are, and what triggers are most common?
I've got my own framework with a plugin and event-driven architecture, but I want to open-source it, and as such would like to make it closer to some common ground as not to alienate people.
So to clarify; this is for an application, meaning setting up the environment, the dependencies, the data sources (like databases), and being a MVC framework setting up the model, the view, launching controllers / actions, and in the GUI various stages of the interface (header, content, columns, etc.).
Ideas? Thoughts? Pointers? (And I've made it language and platform neutral at this point)
I read your blog entry, which btw I found an extremely interesting read, but... this question does not seem to reflect the broadness of the issue you are presenting there.
What you are after is very abstract and theoretical. What I mean to say is that if you tie any of those ideas to actual technology you will find yourself 'stuck' with it. This is why many of us are reluctant to use any framework. Especially the 'relabeled' products suddenly claiming to conform to the trend. We choose mainly on the basis of what appears to be needed to reach a predetermined result.
Frameworks (or tools in general) that target the application architecture domain distinguish themselves primarily by the amount of responsibility they are designed to take on. Spring for example only deals with the concept of decoupling and is therefore easily adopted and useable in many situations. The quality of any framework is expressed in terms of how well the designers of such frameworks were able to keep their products within the boundaries of that responsibility. Some front-to-end products will do exactly the opposite, code generators being among the 'worst' of them.
To answer your question at the top of this page, I do not think there is a framework that does what you want at this time and I do not think there is a single model of how applications (should) work. Keep in mind though that the application architecture domain deals with technology more than it does with concepts. In other words: If it works and meets the requirements, then you're pretty much done.
That said, you might find something of value in agent-based systems.
Heh. Most developers pick the major framework they like the tools for and stick with it. That's usually the winning strategy. I sympathize with your desire not to marry a single vendor.
Keep in mind however, that in developing your own framework, you're going to end up tied to a single vendor anyway. :-)
Is there somewhere some resources that defines the outline of a reasonable
Application Event Model, what events there are, and what triggers are most common?
I don't think so.
From what I see, there are two kinds of models out there: those with a real framework with which you can make a working data entry dialog, and abstract meta-meta-models that are optimized for modeling themselves.
Try surveying a few current frameworks that have good documentation online and cross-reference the major terminology in a spreadsheet. It's an interesting exercise.
I'd have a look at Spring for Java, and the XT Framework Spring module (http://springmodules.dev.java.net/docs/reference/0.9/html/xt.html), which apparently supports event-driven architecture, as starting points. Spring has an MVC framework (inc. convention-based routing to controllers), db configuration (for Hibernate, particularly), plus full dependency injection support. There's also a mechanism in Spring for modularising your web apps, called Spring Slices. And it can be integrated with Jersey for building RESTful apps.
(Unfortunately, I tried to provide links to everything, but this place only lets new users post a single link. So you'll have to do some googling :) )