Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to abstract the Database class and stop it's public usage : Laravel 5.2.31

I have following classes

Interface

interface IRole {
    public function All();
}

In below class, I will also write some logic before sending the data to Database layer and some code after data is retrieved from Database class

class RoleBL implements IRole {

    public function All() {
        return (new RoleDb())->All();
    }
}

Database class

class RoleDb {
    public function All() {
        $Roles = \App\Models\Role\RoleModel
                ::all();
        return $Roles;
    }
}

Below is my Controller Action Method

class MembershipController extends \App\Http\Controllers\BaseController
{
    private $role;

    public function __construct(IRole $_role) {
        $this->role = $_role;
        parent::__construct();
    }

    public function create() {
        $RoleTypes = $this->role->All();
        return view('Membership.Create', array('Roles' => $RoleTypes));
    }
}

Can somebody help me how can I stop direct access to RoleDb class? It's access modifier is public right now.

like image 994
Pankaj Avatar asked Mar 12 '23 01:03

Pankaj


1 Answers

You should not even try to do that. At PHP it will look more like hacks. Just keep one code style and if you work in team then write some guidelines.

Keep all your objects in separate layers based on their purpose. Database related objects in data access layer. Domain objects in domain layer.

Models at domain layer represent all business objects that business talk about (role, customer, comment, payment, etc.) and all related actions on them (user->register, user->assignRole, blog->postArticle, etc.). These models hold business requirements, rules.

Models at data access layer represents all objects that persists state of those business objects and finds them in specific ways (blog->getUnreadPosts, user->findAdministrators, etc.).

If by RoleBL you mean role business logic then it should be part of domain (your business requirements). These objects are persisted/retrieved by DAL.

Your business objects should not know anything about data access layer. (new RoleDb())->All(); means reading from database. To fix this you can create separate read model at DAL for querying your business objects. That means there will be separate model (e.g. RoleDataModel) at DAL for designing query side based on business/application needs.

namespace Domain
{
    class Role
    {
        private $id;
        private $title;

        /* etc. */

        public function getId()
        {
            return $this->id;
        }
    }

    class Person
    {
        private $roles = [];

        /* etc. */

        public function assignRole(Role $role)
        {
            // person already promoted?
            // can person be promoted ?

            // if you promote person then it might not be required to add instance af this $role
            // to $this->roles array, just add identifier from this role

            // If you would like to respond on what did just happen
            // at this point you can return events that describe just that
        }

        public function getRoles()
        {
            return $this->roles;
        }
    }
}

namespace DAL
{
    class Person
    {
        function storePerson(Person $person)
        {
            // here you can use eloqueent for database actions
        }

        function getAllAdministrators()
        {

        }
    }
}

There will be separate Person class for eloquent. Use that just for data manipulation. Map data from eloquent objets to Data Transfet Objects or your Business Layer Objects. DTOs can be more specific to your other layers like UI where you might not need to show everything that BLOs contains. DTOs for your UI will model everything your UI needs.

Get familiar with some of the DDD and overall programming concepts. I should be able to look up something that will fit your needs.

like image 183
featherbits Avatar answered Mar 19 '23 20:03

featherbits