mercredi 8 juin 2022

Mediator design pattern right choice?

i am asking me if this is a good design. I have my own variables which will be persisted on a server with legacy protocol. Is this the way to go in modern c++? Can i improve code with template, CRTP or std::variant?

I tried std::variant but with std::refrence_wrapper<connected_int32/connected_string> in std::vector i was not able to use std::find_if.

#include <algorithm>
#include <cstring>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
#include <vector>

class mediator_interface
{
public:
    virtual ~mediator_interface() noexcept = default;

    void value_to_server(const uint32_t id, const std::vector<uint8_t> &value) noexcept { value_to_server_impl(id, value); }
    void value_to_parameter(const uint32_t id, const std::vector<uint8_t> &value) noexcept { value_to_parameter_impl(id, value); }

private:
    virtual void value_to_server_impl(const uint32_t id, const std::vector<uint8_t> &value) = 0;
    virtual void value_to_parameter_impl(const uint32_t id, const std::vector<uint8_t> &value) = 0;
};

class parameter
{
public:
    std::string_view topic() const noexcept { return topic_; }
    void set_topic(const std::string_view topic) noexcept { topic_ = topic; }

    uint32_t id() const noexcept { return id_; }
    void set_id(const uint32_t id) noexcept { id_ = id; }

    void set_mediator(mediator_interface *mediator_ptr) noexcept { mediator_ptr_ = mediator_ptr; }

    virtual void set_value_impl(const std::vector<uint8_t> &value) = 0;
    virtual void print_impl() = 0;

protected:
    std::string_view topic_{""};
    uint32_t id_{UINT32_MAX};
    mediator_interface *mediator_ptr_{nullptr};
};

class connected_int32 final : public parameter
{
public:
    connected_int32(const std::string_view topic) noexcept { topic_ = topic; }

    int32_t value() const noexcept { return data_; }
    void set_value_impl(const int32_t value) noexcept {
        data_ = value;
        if (mediator_ptr_) {
            std::vector<uint8_t> tmp(sizeof(data_));
            memcpy(tmp.data(), &data_, sizeof(data_));
            mediator_ptr_->value_to_server(id_, tmp);
        }
    }
    void set_value_impl(const std::vector<uint8_t> &value) noexcept { std::memcpy(&data_, value.data(), sizeof(data_)); }
    void print_impl() { std::cout << "id: " << id_ << " --> value: " << data_ << std::endl; }
    
private:
    int32_t data_ = 2;
};

class connected_string final : public parameter
{
public:
    connected_string(const std::string_view topic) noexcept { topic_ = topic; }

    std::string value() const noexcept { return data_; }
    void set_value_impl(const std::string_view value) noexcept {
        data_ = value;
        if (mediator_ptr_) {
            mediator_ptr_->value_to_server(id_, { data_.begin(), data_.end() });
        }
    }
    void set_value_impl(const std::vector<uint8_t> &value) noexcept { data_ = std::string(value.begin(), value.end()); }
    void print_impl() { std::cout << "id: " << id_ << " --> value: " << data_ << std::endl; }
    
private:
    std::string data_ = "two";
};

class mediator final : public mediator_interface
{
public:
    mediator() = default;
    ~mediator() = default;

    void register_parameter(parameter *param) {
        parameters_.push_back(param);
        param->set_mediator(this);
    }

    bool receive_id(const std::string_view topic, uint32_t id) {
        auto param = std::find_if(
            std::begin(parameters_),
            std::end(parameters_),
            [&](const parameter *const p)
            {
                return p->topic() == topic;
            });

        if (param != std::end(parameters_))
        {
            (*param)->set_id(id);
            return true;
        }

        return false;
    }

    void value_to_parameter_impl(const uint32_t id, const std::vector<uint8_t> &value) noexcept override {
        auto param = std::find_if(
            std::begin(parameters_),
            std::end(parameters_),
            [&](const parameter *const p)
            {
                return p->id() == id;
            });

        if (param != std::end(parameters_))
        {
            (*param)->set_value_impl(value);
        }
    }

    void print_all() {
        for (auto &e : parameters_) { e->print_impl(); }
    }

private:
    std::vector<parameter*> parameters_;

    void value_to_server_impl(const uint32_t id, const std::vector<uint8_t> &value) noexcept override {
        std::cout << "Sending data from id(" << id << ") to server..." << std::endl;
    }
};

int main()
{
    connected_int32 my_int{"TstInt"};
    connected_string my_string{"TstString"};

    mediator medi;

    medi.register_parameter(&my_int);
    medi.register_parameter(&my_string);
    medi.print_all();

    medi.receive_id("TstInt", 123);
    medi.receive_id("TstString", 321);
    medi.print_all();

    //User updates variables, persisting to server...
    my_int.set_value_impl(1);
    my_string.set_value_impl("one");
    medi.print_all();

    //Getting update from server...
    medi.value_to_parameter_impl(123, { 0, 0, 0, 0});
    medi.value_to_parameter_impl(321, { 'z', 'e', 'r', 'o'});
    medi.print_all();
}

mardi 7 juin 2022

Cross module communication in modular monolith

I have been learning about modular monolith project structure in this article: https://codewithmukesh.com/blog/modular-architecture-in-aspnet-core

Most of it makes sense to me but something I don't quite get is:

Cross Module communication can happen only via Interfaces/events/in-memory bus. Cross Module DB Writes should be kept minimal or avoided completely.

How exactly does that cross-module communication look?

Let's say I have 3 modules:

  • Product
  • User
  • Security

My security module registers an endpoint for DisableUser. It's this endpoint's job to update a User and every Product associated with the user with a disabled status.

How does the Security module call User & Product update status method in a unit of work?

My understanding is that this pattern is intended to make it easier to extract a module to a microservice at a later date so I guess having it as a task of some sort makes it easier to change to a message broker but I am just not sure how this is supposed to look.

My example is obviously contrived, my main point is how do modules communicate together when read/writes are involved?

Why Go's append NEED create and return a new slice? [duplicate]

In Go, when we use append, we use it like this:

a := make([]int, 0)
a = append(a, 1)

In this sample, append will create a new slice (we know that go will always do this when trigger slice's grow algorithm), which has different memory location from the old one, but WHY?

Consider we wants a iterator pattern, code like this:

type SliceIterator struct {
    index int
    slice []int
}

func (i *SliceIterator) HasNext() bool {
    return i.index < len(i.slice)
}

func (i *SliceIterator) Next() int {
    i.index += 1
    return i.slice[i.index-1]
}

If we pass a slice into an iterator and we append some elements to the slice outside, the slice inside the iterator may not be what we want and the iterator may be useless.

So is there any way to reslove this problem?

And the most important, why Go designs its append like this? I think it can just reallocate the pointer to the actual array but no need to create a new slice, just change the pointer, len and capacity inside the original slice.

lundi 6 juin 2022

passing One class as input to another class that takes multiple reference interfaces for his constructor C++

I have Manager class that inherit multiple interfaces and implements them.

class iperson
{
    public:
    virtual void doSomething1() = 0;
}

class imachine
{
    public:
    virtual void doSomething2() = 0;
}

class ibook
{
    public:
    virtual void doSomething3() = 0;
}
class Manager: iperson, imachine, ibook
{
    public:
    void doSomething1() override 
    {/** implemetation **/}
    
    void doSomething2() override
    {/** implemetation **/}
    
    void doSomething3() override
    {/** implemetation **/}

    /*** 
    another code and implemetation 
    ****/
} 

And there is Employee class that takes Manager implementation as input for his constructor

class Employee
{
    Employee(iperson& person, imachine& machine, ibook& book)
    { /*** some code ***/ }
}

And when i need to pass Manger to Employee from Manager class, I end up with code like this

/** That looks bad passing three this XD **/
Employee employee(*this, *this, *this);

Why using interfaces instead of passing Manager reference?(what i'm trying to achieve) 1- to be able to mock these methods while testing the employee class 2- to restrict access of employee classes to just these methods, not all Manager methods

So the question is: is there better solution and is there a way to istead passing the three (*this) just passing one or something?

What is the recommended way to organize files storage?

I have a NodeJS server running as a file storage for clients and other services.

I am using two approach to organize when a file is uploaded:

1, Prefix the folder that file belongs to, such as: image files will go to uploads/image folder, mp3 files will go to uploads/mp3 folder here is NodeJS implimentation

let image = "public/uploads/image";
let mp3 = "public/uploads/mp3";
let video = "public/uploads/video";

fs.existsSync(image) || fs.mkdirSync(image, { recursive: true });
fs.existsSync(video) || fs.mkdirSync(video, { recursive: true });
fs.existsSync(mp3) || fs.mkdirSync(mp3, { recursive: true });

2, Dynamic organize base on params on the request I have some parameters in the endpoint to config path that file will go to

const savedPath = `public/uploads/${type}/${path}`
fs.existsSync(savedPath) || fs.mkdirSync(savedPath, { recursive: true })

So what is the best way to organize files in a file storage service?

How to Efficiently Utilize Objects in Conjunction with HTML Elements

I am getting pretty deep into an employee talent management system website and I am finding out really quick why OOP is so talked about. Being able to efficiently utilize it would change that game for me and make my codebase much more maintainable. I am currently working on a dropdown menu section, and while I have implemented OOP, I can tell from a mile away it is not "good code." It gets the job done but is very messy. I will have an example of the Object and Implementation down below. I have tried watching a few videos on implementing OOP in an existing project, but I keep coming up dry. I understand the basic concepts, but I am not sure how to implement these ideas in a real world application.

Here are some sticking points I am having:

  1. I am not confident I instantiated my objects correctly/efficiently. I have a list of toggleable menus, each representing a candidate in the portal. Well, I created an object for each menu using a for loop. This worked, but it felt unintuitive. When I wanted to attach click events to these menus, I had to loop through them a second time to attached to objects methods as click events.

  2. I felt I had a lot of 'if' statements in my Object. This is because I see myself using the object again in the future, but I do not think each menu will have all the same features. For example, this specific menu had a fade in animation when clicked. But, I doubt every toggleable menu will have this feature. I don't know, I just felt it made the code way more difficult to navigate.

  3. I did not like having to loop through my menu elements and attach methods as click events. This made me have to run an additional for loop and felt 'off'. I was tempted to handle all the event attachments inside the object itself, but I wasn't sure if this is bad practice. It seemed like a good idea and would save a lot of code, but I'm not sure.

Long story short, I can see myself using OOP for forms, buttons, toggleable menus, navbars, (ect.) all over the place. The problem is I am not sure how to actually carry out the process of handling HTML elements and converting them to Objects in a clear and concise manner.

I looked into some design patterns on refactoring.guru, but I felt these concepts were past the scope of what I am trying to do. They all felt like more advanced concepts to take on after getting a solid grip on objects. It was helpful and I really liked the builder pattern. I am currently working on a branch which implements the builder pattern into my current scenario.

Any thoughts, advice, or direction?

Here is an example of the Object and it's Implementation:

TOGGLE MENU OBJECT

class ToggleMenu {
    constructor(wrapper, menu, openIcon, closeIcon, title, hiddenMenu) {
        this.wrapper = wrapper
        this.menu = menu
        this.openIcon = openIcon
        this.closeIcon = closeIcon
        this.title = title
        this.hiddenMenu = hiddenMenu
        this.toggled = false
    }
    props() {
        console.log(this.menu)
        console.log(this.openIcon)
        console.log(this.closeIcon)
        console.log(this.title)
        console.log(this.hiddenMenu)
        console.log(this.toggled)
    }
    openHiddenMenu(config) {
        if (config == undefined){
            config = {}
        }
        if (config.menuBackGroundColor !== undefined){
            this.menu.style.backgroundColor = config.menuBackGroundColor
        }
        if (config.titleColor !== undefined){
            this.title.style.color = config.titleColor
        }
        if (config.hiddenMenuDisplay !== undefined){
            this.hiddenMenu.style.display = config.hiddenMenuDisplay
        }
        if (config.hiddenMenuAnimation !== undefined){
            this.hiddenMenu.style.animationName = config.hiddenMenuAnimation
        }
        if(config.menuAnimation !== undefined){
            this.menu.style.animationName = config.menuAnimation
        }
        this.openIcon.style.display = 'none'
        this.closeIcon.style.display = 'block'
        this.toggled = true
    }
    closeHiddenMenu(config){
        if (config == undefined){
            config = {}
        }
        if (config.menuAnimation !== undefined && this.toggled == true){
            this.menu.style.animationName = config.menuAnimation
        }
        this.menu.style.backgroundColor = ''
        this.openIcon.style.display = ''
        this.closeIcon.style.display = ''
        this.title.style.color = ''
        this.hiddenMenu.style.display = ''
        this.toggled = false
    }
}

IMPLEMENTATION

const initCandidateMenus = () => {
    let candidateToggleMenus = document.getElementsByClassName('candidate-toggle-menu')
    let candidateToggleWrappers = document.getElementsByClassName('candidate-toggle-menu-wrapper')
    let hiddenMenus = document.getElementsByClassName('hidden-candidate-menu')
    let toggleMenus = []
    //collecting toggle menu objects
    for (x = 0; x < candidateToggleMenus.length; x++){
        let toggleMenu = new ToggleMenu(
            candidateToggleWrappers[x],
            candidateToggleMenus[x],
            candidateToggleMenus[x].getElementsByClassName('candidate-open-icon')[0],
            candidateToggleMenus[x].getElementsByClassName('candidate-close-icon')[0],
            candidateToggleMenus[x].getElementsByClassName('candidate-name')[0],
            hiddenMenus[x],
        )
        toggleMenus.push(toggleMenu)
    }
    //looping through toggle menu objects
    for (x = 0; x < toggleMenus.length; x++){
        let currentMenu = toggleMenus[x]
        currentMenu.openIcon.addEventListener('click', () => {
            //closing all other toggle menus
            for (y = 0; y < toggleMenus.length; y++){
                toggleMenus[y].closeHiddenMenu()
            }
            //opening current menu
            currentMenu.openHiddenMenu({
                menuBackGroundColor: 'var(--main-clr)',
                titleColor: 'var(--white)',
                menuAnimation: 'fade-title-color',
                hiddenMenuDisplay: 'flex',
                hiddenMenuAnimation: 'open-hidden-menu'
            })
        })
        currentMenu.closeIcon.addEventListener('click', () => {
                //closing current menu
                currentMenu.closeHiddenMenu()
        })
    }
}

I am trying to do a patern but don t know how.I want some help if u cab help me

I am trying to do a pattern for so long and i can t make it Pls i need helpp.[This is the image][1]

    public static void main(String[] args) {
  

      int size = 5;
     
      for (int i = 0; i < size; i++) {
        
        for (int j = 5; j < size;j++ ) {
          System.out.print("");
        }
        System.out.println();
      }
    }
  }``` 


  [1]: https://i.stack.imgur.com/SBmvw.png