CakePHP - where to put service logic - cakephp

I am Java programmer who tries to investigate CakePHP - currently I have problem with application structure/design. I could not understand where to put core logic of application.
When I am developing in JavaEE, common approach looks like following:
Model classes are simple beans which represent data entities (products, people etc) - mostly like data structures with getters/setters;
Controller classes are simple enough classes which aggregate necessary data and inject them into dedicated View template which is then sent to user;
DAO (DataAccessObject) or Repository classes are ones which can load and store entities into database;
Service classes are usually singletons which contains certain business-logic methods - these are called by controllers, by other services or by scheduled actions, on the other hand they themselves call DAO / Repository methods to fetch or modify data.
For example if I have entities Person, Product and Order, when user selects some product and clicks "put it into my cart/basket" new Order for this Person should be created and this Product should be added to this Order (we may check that Person is not bad debtor and that Product is present at store etc.) - all this work is performed in methods of OrderService called by some controller.
Usually some kind of IOC (Inversion of Control) is used so that all services and controllers have links to necessary services etc.
Now I am slightly bewildered about how this all is done in CakePHP. Where should I put this business-logic etc. ?

In CakePHP the model layer is made up from collection of active record instances, called AppModel. They combine the storage-related logic (that you would usually put in DAOs and/or Repositories) with business logic (what usually went into your "models").
Any other domain related logic (from your Service) becomes part of controller.
If you want to know, how you are supposed to implement domain business logic in CakePHP, just look up articles which praise active record pattern.
Personal opinion
CakePHP and CodeIgniter are two of the worst frameworks in PHP. They are filled with bad practices.
Actually, if you were doing correct-ish MVC, then model layer would contain all of the business logic and everything that is related to it. Model layer is made of DAOs, Repositories, Domain Objects (what you call "models") and Services.
While your descriptions of Java-based code indicates, that you are kinda moving in that direction, CakePHP is not even remotely close to it.
Then again, it might be that my understanding of MVC is just wrong.

The controllers should only contain logic relevant for the whole thing being a web application. Your business logic belongs into the models. I think it is one of the basic mistakes that you find in many cakePHP applications, that to much logic is put into the controllers, which actually belongs into the models.

In CakePHP. the "M" is just a bunch of Data Models instead of Domain Models.
In my opinion. CakePHP is made for RAD development. It is not a good fit for enterprise applications.
My opinion though.

Related

AngularJS and separate model classes

I plan to use AngularJS verion 1.latest. I'm new to this framework. Previously I was programming in mainly in PHP. I've studied https://docs.angularjs.org/tutorial
As far as I understood - there is no model stricte. Controller has $scope and this is the data layer for view.
Then I have troubles how to logically put data models into Angular application. Assume that data model represents computer: 1 mainboard with some properties, 1..* ram modules, 1..* processors, 1..* hard drives. Each device has its own properties. The data is fetched via RESTful API with several requests.
The data will be shared among few controllers.
How should all this be organized to preserve testability? I'd use Service for operations with REST.
I was talking to very experienced developer. He confirmed what I've studied by myself.
For storing data about PC I use a service (lets call it data-service). Data can be fetched by the same service or another one. Then data from data-service can be accessed in each controller and assigned to controller variables available in view (which should use controllerAs).
The guy also suggested to have as small data models as possible. It should be pure objects (can be nested) preferable without additional methods (opposite to classes from any backend) as they role is only to carry data. This sounds like truth in 90% of cases.

Universal data model and microservices integration

Since the native-cloud applications or microservices architecture requires decentralized data model (each microservices has its own database), and universal data model is centralized data model
So, how we have microservices architecture with universal data model patterns?
Is there any reference or implementation of universal data model and microservices?
In general the two concepts are not compatible. Using a universal data model for all of your services would clash with a couple of key ideas behind using Microservices, e.g. Polyglot Persistence, separate development & deployment of each service. Also, let's not forget that the "Data Model Resource Book" was last updated in 2009.
However, if you must combine the two approaches, e.g. because management insists on it, you can encapsulate all access to the universal data model by a dedicated service and make your other services dependent on it.
Some good thoughts on the subject can be found here: http://plainoldobjects.com/2015/09/02/does-each-microservice-really-need-its-own-database-2/
Yes to #Fritz's point -- universal data modeling and microservices are really two different concepts and are very difficult if not impossible to be used together. I would like to add that the reasoning for polyglot persistence is also because of how the data should be modeled. Microservices allow the use of different data stores that can best model the data according to their domain.
To elaborate more, I don't think it would do justice to mention microservices and data modeling but not domain driven design. From my experience, domain driven design really helps in thinking about services, their responsibilities, and their right to exist. For instance, I found it often to be the case that there are usually a collection of services that carries out a particular domain functionality. An example could be an e-commerce application that have payments, shopping carts, etc. These could be separated into different "bounded contexts" based on domain driven design terminology.
With the different bounded contexts, each microservice no longer sees the same concept in the system the same, so in effect, there is no real universal data model. The easiest example that I can think of to show this, is when you also want reporting on the metrics in the system. If the example was an ecommerce application, the notion of a transaction in the orders microservice are going to be different than transactions in a reporting service. The reporting service for instance may want to know about transactions at a sub-level such as the profit or revenue generated for a particular order instead of the particular line items in an order. However, in the perspective of the orders service, the order details such as the line items and the address of the individual that made the purchase are probably important and should be known. This should then require two different data models.
With respect to domain modeling, I may be a bit extreme but I would go as far as saying that if there are multiple services sharing the same data source, they should really be the same service; there should be only one service for a single data source. My arguments for that would be that the domain hasn't been properly modeled and that the coupling makes it different to evolve any one service if there are multiple services that relies on a single data source. The case could be that one service requires the schema of the data source to change while the other one does not but still is required to accommodate the schema change. Hope this helps!

How to keep controller and model on different machine in AngularJS

I have recently gone thru several articles on AngularJS. As AngularJS maintains controllers and models separately from view. As soon as model gets updated it updates View automatically and vice versa as it is two way binding. But as much I have gone thru all the articles I have found that all views, models and controllers are managed on client side.
Do we have any way to put controllers and models on different machines than client side ?
Yes, but not automatically. AngularJS is a client-side MV* framework. There are also server-side frameworks and even some combos like Meteor that run on both sides. But always there is some messaging back and forth, and at the end of the day, what is it you wish to do on the server? Servers and clients are almost always very different, and where a client might be drawing forms and tables, a server might be reading/writing database queries or managing multimedia assets. That means there's rarely a benefit to a 1:1 duplication of functionality in both environments.
I would suggest you evaluate the excellent ExpressJS framework for NodeJS. This is a great building block for server-side MV* apps, especially when combined with a good templating library like Swig. You can easily create a CRUD API here (in just a few minutes) that manages creating/updating data objects in a model and storing them in a database like MySQL, Mongo, or something like Redis. Then, back in AngularJS, you can use $resource, Restangular, or similar to map between the two.
This technique has a few more steps in it than Meteor would, but it gives you an incredible amount of flexibility and doesn't take very much code to produce.

WCF multiple data contracts or multiple service contracts representing multiple data model classes?

In my WPF application data model I have multiple classes representing data for interaction with backend DB through WCF self hosted service.
Should I have multiple Data Contracts or multiple Service Contacts or Endpoints in my WCF Sevice for representing these multiple WPF data model classes? What is correct (or maybe the only) way to architect WCF in this case?
There is a design recommendation called Interface Segragation Principle which basically states what the iDesign WCF Coding Standards also say: don't make your interfaces (= your service contracts) too big and too unwieldy.
Consider this: you have a huge service contract with hundreds of methods, and some third party would like to implement a subset of functionality, maybe only two or three of those service methods. If you have a single huge service contract, they would have to implement their 3-4 service methods of interest, and all the others, they would have to stub a dummy - e.g. something like throw new NotImplementedException(); or something. This is not a good idea, in general.
So the basic principle should be: try to group your service contracts in such a way that if ever someone else needs to implement a subset, they most likely will find a single service contract that has all the methods they need, and nothing else. Try to group your service contracts by topics, e.g. if you have 6 methods to search addresses, put those in a separate service contract. If you have 7 other methods to insert new addresses, update and delete existing ones - that should probably be a separate service contract (since you could well imagine someone wanting to only search for addresses - not modify anything).
So I guess there's no real hard rule what is good or not - try to group your service into "logically connected" groups of methods. That's not an easy thing to do, for sure! But it's worth the effort to think about how others might be using your services.
Also, if you have a few smaller service contracts, it's also a lot easier if you ever need to change anything. If you need to introduce a breaking change into a service contract, only those (hopefully few) users of that particular service contract with a few methods will be affected. If you always have to change your huge 200 method service contract, you'll always affect everyone - that might not be a good thing!
In WCF terms a data contract is a class used in a service contract operation. It's called a data contract because it is usually annotated with the DataContractAttribute in order to be recognized and serialized successfully (although starting from .NET 3.5 SP1 DataContractSerializer works with POCO objects and this attribute is no longer required). So you could have a single service contract with multiple operations dealing with multiple data contracts all exposed in a single endpoint.

Does business logic belong in the service layer?

I've got a set of classes, namely, a data transfer object, a service implementation object, and a data access object. I currently have business logic in the service implementation object; it uses the dao to get data to populate the dto that is shipped back to the client/gui code.
The issue is that I can't create a lightweight junit test of the service implementation object(it's a servlet); I think the business logic should be elsewhere, but the only thing I can think of is putting business logic in the dao or in yet another layer that goes between the dao and the service implementation.
Are there other options, or am I thinking about this the wrong way?
It's a GWT/App Engine project.
I don't understand why you can't unit-test the servlet, e.g. as per this SO question (there are others on similar themes) -- can you please explain?
Edit: if there's no special reason, I suggest you should the business logic in the service layer (where it seems to belong) and unit-test it there -- the approaches suggested in the SO question I just quoted, for example, seem reasonably lightweight (though I didn't test them specifically).
You can put your business logic in it's own jar file and test this component independently from the integration with the web (servlet)
The servlet is just a protocol, it is not your business logic, more an integration point.
It must be easy to imagine to expose your same business logic through a thick client.
Also in that case, you should not hide the business logic under buttons or links.
One more note: you might want to look into the MVC framework; struts. Your model will hold the business logic.
Hope this helps.
The servlet is the controller , it is a very big mistake, to put the business logic there.

Resources