OOP composition and orm - database

I am building a simple rate limiter to train my oop skills and I am having some doubts regarding composition and orm.
I have the following code:
interface RateLimiterService {
void hit(String userid, long timestamp) throws UserDoesNotExistEx, TooManyHitsEx; // Option A
SingleRateLimiter getUser(String userid) throws UserDoesNotExistEx; // Option B
Optional<SingleRateLimiter> getUser(String userid); // Option C
}
class LocalRateLimiterService implements RateLimiterService {
// Uses an hash table userid -> SingleRateLimiter
}
interface SingleRateLimiter {
void hit(long timestamp) throws TooManyHitsEx;
}
class TimestampListSRL implements SingleRateLimiter {
// Uses a list to store the timestamps and purges the expired ones at each call
}
class TokenBucketSRL implements SingleRateLimiter {
// Uses the token bucket aproach
}
My doubts are:
Which option should I use for the RateLimiterService interface?
Option A is usually called "method forwarding" or "delegation" or "Law of Demeter". It protects the composed object by only exposing the intended methods and/or by possibly adding some extra validation logic before forwarding the call. Therefore, it seems like a good solution when that is needed. However, when this is not the case (as in my example), this option creates a lot of redundant repetitions which add nothing usefull.
Option B breaks encapsulation in a way but it avoids method repetions (the DRY principle). By picking A or B you always end up breaking some well known principles/good practices. Is there another option?
Option C is the same as B but returns an optional instead of throwing an exception. Which approach is considered better?
If the classes that implement the RateLimiterService had a single composing SingleRateLimiter instead of a collection of SingleRateLimiters (doesn't make much sense in this case but trying to be generic to other situations when the composed object is not a colection), would the best Option change to other alternative from the one in 1.?
If I wanted to add a database to this system, what would be the best approach to "talk to" the database?
creating a class DBRateLimiterService that implements RateLimiterService and has a private connection object to the database (is basically a DAO)? In this case, this class does not know anything besides the userid of the inner SingleRateLimiters, since there are multiple implementations available/possible. So how can I do this approach without changing the current OOP architecture?
In addition, I would need to create a DAO for each SingleRateLimiter implementation too, right? In this case, the SingleRateLimiter is not a simple model object that has only getters and setters so it should also be a DAO, right? Its hit method must be implemented as a transaction in most cases (if not all). If this is the right approach, how can the two DAOs operate together and map to the same database table?
What other options could serve for this?

Related

Deprecation of TableRegistry::get()

I'd like to ask what are your thought on deprecation of the TableRegistry::get() static call in CakePHP 3.6?
In my opinion it was not a good idea.
First of all, using LocatorAwareTrait is wrong on many levels. Most important, using traits in such way can break the Single Responsibility and Separation of Concerns principles. In addition some developers don't want to use traits as all because they thing that it breaks the object oriented design pattern. They prefer delegation.
I prefer to use delegation as well with combination of flyweight/singleton approach. I know that the delegation is encapsulated by the LocatorAwareTrait but the only problem is that it exposes the (get/set)TableLocator methods that can be used incorrectly.
In other words if i have following facade:
class Fruits {
use \Cake\ORM\Locator\LocatorAwareTrait;
public function getApples() { ... }
public function getOranges() { ... }
...
}
$fruits = new Fruits();
I don't want to be able to call $fruits->getTableLocator()->get('table') outside of the scope of Fruits.
The other thing you need to consider when you make such changes is the adaptation of the framework. Doing TableRegistry::getTableLocator()->get('table') every time i need to access the model is not the best thing if i have multiple modules in my application that move beyond simple layered architecture.
Having flyweight/singleton class like TableRegistry with property get to access desired model just makes the development more straight forward and life easier.
Ideally, i would just like to call TR::get('table'), although that breaks the Cake's coding standards. (I've created that wrapper for myself anyways to make my app bullet proof from any similar changes)
What are your thoughts?

Domain Driven Design (DDD) and database generated reports

I'm still investigating DDD, but I'm curious to know about one potential pitfall.
According to DDD an aggregate-root shouldn't know about persistence, but doesn't that mean the entire aggregate-root ends up being instantiated in memory?
How could the aggregate-root, for instance, ask the database to group and sum a lot of data if it's not supposed to know about persistence?
According to DDD an aggregate-root shouldn't know about persistence, but doesn't that mean the entire aggregate-root ends up being instantiated in memory?
Oh no, it's worse than that; the entire aggregate (the root and all of the subordinate entities) get loaded instantiated in memory. Essentially by definition, you need all of the state loaded in order to validate any change.
How could the aggregate-root, for instance, ask the database to group and sum a lot of data if it's not supposed to know about persistence?
You don't need the aggregate-root to do that.
The primary role of the domain model is to ensure the integrity of the book of record by ensuring that all writes respect your business invariant. A read, like a database report, isn't going to change the book of record, so you don't need to load the domain model.
If the domain model itself needs the report, it typically defines a service provider interface that specifies the report that it needs, and your persistence component is responsible for figuring out how to implement that interface.
According to DDD an aggregate-root shouldn't know about persistence, but doesn't that mean the entire aggregate-root ends up being instantiated in memory?
Aggregate roots are consistency boundaries, so yes you would typically load the whole aggregate into memory in order to enforce invariants. If this sounds like a problem it is probably a hint that your aggregate is too big and possibly in need of refactoring.
How could the aggregate-root, for instance, ask the database to group and sum a lot of data if it's not supposed to know about persistence?
The aggregate wouldn't ask the database to group and sum data - typically you would load the aggregate in an application service / command handler. For example:
public class SomeUseCaseHandler : IHandle<SomeCommand>
{
private readonly ISomeRepository _someRepository;
public SomeUseCaseHandler(ISomeRepository someRepository)
{
_someRepository = someRepository;
}
public void When(SomeCommand command)
{
var someAggregaate = _someRepository.Load(command.AggregateId);
someAggregate.DoSomething();
_someRepository.Save(someAggregate);
}
}
So your aggregate remains ignore of how it is persisted. However, your implementation of ISomeRepository is not ignorant, so can do whatever is necessary to fully load the aggregate. So you could have your persistence implementation group/sum when loading the aggregate, but more often you would probably query a read model:
public class SomeUseCaseHandler : IHandle<SomeCommand>
{
private readonly ISomeRepository _someRepository;
private readonly ISomeReadModel _someReadModel;
public SomeUseCaseHandler(ISomeRepository someRepository, ISomeReadModel readModel)
{
_someRepository = someRepository;
_someReadModel = someReadModel;
}
public void When(SomeCommand command)
{
var someAggregaate = _someRepository.Load(command.AggregateId);
someAggregate.DoSomethingThatRequiresTheReadModel(_someReadModel);
_someRepository.Save(someAggregate);
}
}
You haven't actually said what your use case is though. :)
[Update]
Just noticed the title refers to database generated reports - this will not go through your domain model at all, it would be a completely separate read model. CQRS applies here

Cakephp 3: Calling Table functions from Entity is a bad or good idea?

When I have some entity and I wanna save, validade or delete. Why do I have to call the Table method? For example:
$articlesTable = TableRegistry::get('Articles');
$article = $articlesTable->get(12);
$article->title = 'CakePHP is THE best PHP framework!';
$articlesTable->save($article);
Why isn't like this:
$article->save();
or $article->delete();
It's very simple to implement:
On my Article Entity I can do it like:
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Article extends Entity
{
public function save()
{
$table = TableRegistry::get($this->source());
$table->save($this);
}
}
It's working, but I would like to know if its a bad practice or a good idea.
Thanks in advance :)
TL;DR: Technically you can do it for the high price of tight coupling (which is considered bad practice).
Explanation: I wouldn't consider this best practice because the entity is supposed to be a dumb data object. It should not contain any business logic. Also usually it's not just a simple save call but there is some follow up logic to implement: Handle the success and failure of the save and act accordingly by updating the UI or sending a response. Also you effectively couple the entity with a specific table. You turn a dumb data object into an object that implements business logic.
Technically you can do it this way and I think there are frameworks or ORMs that do it this way but I'm not a fan of coupling things. I prefer to try to write code as lose coupled as possible. See also SoC.
Also I don't think you'll save any lines of code with your approach, you just move it to a different place. I don't see any benefit that would justify the introduction of coupling the entity to the business logic.
If you go your path I would implement that method as a trait or use a base entity class to inherit from to avoid repeating the code.

How to make a model in Go

I want to make models for my framework, written in go, and I'm not sure how to compose them in a way that shares the common database interaction methods: save, update, delete.
I would normally do this by creating a Model abstract parent class to all concrete models, but Go doesn't have inheritance. You're supposed to use embedding and composition instead, but I don't see how I can embed a model class and have it save the data of the class holding it.
I see the other option, of creating a model class that embeds a concrete model type within it, but I don't really see an interface that would apply to all the models unless it was empty. That brings with it the insecurity that anything can be considered a model.
What do?
In my projects I do something like this:
type Storable interface {
// called after unmarshalling from the database
Init() error
// called when an object is being deleted
// this is useful if the object needs to delete other objects,
// change state on a remote server, etc.
Destroy() error
// called after Init, helps separate initialization from
// sanity checks (useful to detect errors before using a potentially
// invalid object)
Validate() error
// type of this object, stored in the database in `Save` and `Update`
// so it can be read out in `Get`
Type() string
}
If you're working with an SQL database, you could do something like this:
type Schema map[string]reflect.Type
type SQLStorable interface {
Storable
Schema() Schema
}
Then in the database, I have functions like this:
func Get(id string) (Storable, error)
func Save(Storable) error
func Update(id string, Storable) error
func Delete(id string) error
// register a type with the database (corresponds to the Type() in Storable)
func Register(typ string, reflect.Type)
I keep a cache of objects in the database: map[string]Storable. This allows me to implement caching logic to reduce lookup times (don't need to reconstruct objects each time it's read from the database).
In my project, I have lots of packages that need to talk with objects from other packages. Since managing dependency chains would be a nightmare, I've set up a messaging system that uses the database:
type Message map[string]interface{}
func Send(id string, Message)
And I've added a Receive function to Storable that takes a Message and returns an error. This has reduced many headaches so far and has lead to a more pluggable design.
I'm not sure if this is the "Go way", but it avoids the idea of inheritance and solves the problem. In the database logic, I use tons of reflection to grab the data from the database and populate an object with it. It leads to some unfortunate type assertions, but I guess that can't really be helped when trying to keep things abstract.

encapsulation and abstraction OOPs concept

Does Encapsulation is information Hiding or it leads to information hiding??
As we say that Encapsulation binds data and functions in a single entity thus it provides us control over data flow and we can access the data of an entity only through some well defined functions. So when we say that Encapsulation leads to abstraction or information hiding then it means that it gives us an idea which data to hide and which data to show to users... coz the data that users cant access can be hidden from them thus encapsulation gives us a technique to find out what data to be hidden and what should be visible... Is this concept correct??
And what is the difference between information hiding and abstraction??
Possible duplicate of the this
public class Guest {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
See the above code, we have encapsulated the String name, we provide the access to it through public methods.
Say we have created object of Guest called guest. Then the following will be illegal.
System.out.println("Guests name : "guest.name);
Access through public methods is what can only be done.
guest.getName();
Benefits of Encapsulation:
The fields of a class can be made
read-only or write-only.
A class can have total control over
what is stored in its fields.
The users of a class do not know how
the class stores its data. A class
can change the data type of a field,
and users of the class do not need
to change any of their code.
Encapsulation means hiding the implementation
Abstraction means providing blueprint about the implementation
Data Hiding means controlling access to DataMember or attributes
Information is a more general term, hence, i believe, to say Encapsulation is Information hiding, will not be appropriate.
I would say Encapsulation is Data Hiding.
Encapsulation means ...
Combining an Object's State & behavior (that operates on that State), in one single unit.
This closely mimics a real world Object.
Hiding & Securing Object's State from accidental external alterations by providing a well-defined, controlled access (through behaviors).
In Java, the definition can be detailed out as ...
In Java, Classes and Enums are single units for implementing encapsulation. State is defined using variables (primitives, references to objects), and behavior using methods.
Data Hiding is achieved using private access specifier on variables (so that no one can access them from outside).
Controlled Access is achieved by providing Getters / Setters and/or business logic methods. Both Setters and other State affecting methods should have boundary condition checks for keeping the State logically correct.
Encapsulation talks about hiding data into something and give it a name ( private data members in a class - Car) and binding behavior methods with it which will mutate or provide access to those data variables.
Abstraction provides perspective of the client in abstract terms. As a concept or idea. Car is concrete entity where as Drivable, Trackable(which has position and can be tracked down) can be abstraction for Car for different clients.
You can check some real life examples of Abstraction and Encapsulation here.
Encapsulation is a technique used for hiding properties & behavior of an object.
Abstraction refers to representing essential features.
Encapsulation - Work complete and door permanently closed. Get work benefits through method name.
Abstraction - Work started and door temperately closed. Open and change work using overriding Key.
Both these OOP principles involve information hiding but are different.
Encapsulation involves restricting the direct access to the variables of the class by making them private and giving public getters and setters to access them.
Purpose: This is done so that the members of the class cannot be accidentally manipulated (and thus corrupted) from outside.
Abstraction involves exposing only the relevant details to the caller while hiding other details (details of implementation). The client does not need to bother about implementation which may change later. Example: The caller will call the add method of List, the implementation of which may be ArrayList today but may change to LinkedList tomorrow.
Purpose: This provides flexibility that tomorrow the implementation can be changed. Also, it simplifies the design.

Resources