What is more effective for organizing extensive code - utilizing mixins or static methods?

I currently have a lengthy code in a class that I would like to organize into separate files.

I am considering two ideas: using Mixin and utilizing static methods.

For instance,

class myController {
    routeSubView(type: SubViewType, params: any) {
        switch(type) {
            case SubViewType.A: 
                this._showA(params);
                break;
            case SubViewType.B: 
                this._showB(params);
                break;
            case SubViewType.C: 
                this._showC(params);
                break;
            case SubViewType.D: 
                this._showD(params);
                break;
            // ... many more cases
        }
    }

    private _showA() {
        // initialize view and render
    }

    private _showB() {
        // initialize view and render
    }

    private _showC() {
        // initialize view and render
    }

    private _showD() {
        // initialize view and render
    }

    // ... many more methods
}

#idea1 ) Refactor sub-view generation into a static class

### sub_views.ts
class SubViews {
    static showA(params: any) {
        // initialize view and render
    }
    static showB(params: any) {
        // initialize view and render
    }
}

### my_controller.ts
import { SubViews } from './sub_views';
class myController {
    routeSubView(type: SubViewType, params: any) {
        switch(type) {
            case SubViewType.A: 
                SubViews::showA();
                break;
            case SubViewType.B: 
                SubViews::showB();
                break;
            case SubViewType.C: 
                SubViews::showC();
                break;
            case SubViewType.D: 
                SubViews::showD();
                break;
            // ... many more cases
        }
    }
}

#idea2) Implementing Mixin

### mixin.ts
export interface ISubviews {
    _showA(params: any): any;
    _showB(params: any): any;
    _showC(params: any): any;
    _showD(params: any): any;
}

export function _showA(param: any){
    // initialize view and render
}
export function _showB(param: any){
    // initialize view and render
}
export function _showC(param: any){
    // initialize view and render
}
export function _showD(param: any){
    // initialize view and render
}

### my_controller.ts

import * as { Mixin } from './mixin';

class myController implement Mixin.ISubviews {
    _showA(params: any): any;
    _showB(params: any): any;
    _showC(params: any): any;
    _showD(params: any);

    /// ...
}

Cocktail.mixin(myController, Mixin);

Which idea do you think is better? Or do you have another suggestion? Your advice is appreciated.

Answer №1

Javascript and Typescript are languages with a prototypal nature, which means they break down the traditional object-oriented model into embedding, delegation, and creation. This unique approach allows for the representation of powerful concepts that are not present in the classical model. Your initial example seems to be more of a workaround in the context of traditional OO programming, highlighting a preference for composition over inheritance.

In prototypal languages, composition remains superior to inheritance, but it can be expressed more directly - for instance, through the use of mixins (a form of embedding). It is generally advisable to opt for a mixin over simple member composition.

If you wish to delve deeper into these ideas, I recommend watching Eric Elliot's insightful talk on the three types of prototypal inheritance. For an even more profound exploration, consider exploring Luca Cardelli's work, A Theory of Objects.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for resolving the error message "TypeError: Converting circular structure to JSON"

I had a straightforward query where I needed to select all from the aliases table. Everything was working fine until I ran npm update. TypeError: Converting circular structure to JSON public async fetchAliases(req: Request, res: Response): Promise< ...

Ways to streamline redundant code by creating a higher order function that accepts different parameter types in TypeScript

Recently, I've been exploring the idea of refactoring this code into a higher order function using TypeScript to enhance its cleanliness and reusability. However, I'm facing quite a challenge in getting it to work seamlessly. import { DocumentDef ...

Issue in TypeScript: Property '0' is not found in the type

I have the following interface set up: export interface Details { Name: [{ First: string; Last: string; }]; } Within my code, I am using an observable configuration variable: Configuration: KnockoutObservable<Details> = ko.observable& ...

Utilizing winston to generate multiple log files with set maximum sizes and daily rotation

Currently, I am utilizing winston for logging with a maximum size and daily rotation. I am interested in having this functionality with one file per API endpoint to define multiple log files. Is there a way to achieve this? Displayed below is my winston ...

Cannot find the specified attributes in the 'Observable<PizzaState>' type

I am attempting to create pizzas that I receive from the store, but I am encountering a red flag on this issue. this.pizzas$ I'm unsure why this is happening, but when I remove : Observable<PizzaState>, it resolves the problem. However, I want ...

Conceal component (Ionic React TypeScript)

I was wondering about a specific situation in my code. Here is the relevant snippet: const Dashboard: React.FC<RouteComponentProps> = ({ history }) => { var random = 1; return ( <React.Fragment> <IonTitle id="title&qu ...

Unable to locate the name 'Cheerio' in the @types/enzyme/index.d.t file

When I try to run my Node application, I encounter the following error: C:/Me/MyApp/node_modules/@types/enzyme/index.d.ts (351,15): Cannot find name 'Cheerio'. I found a suggestion in a forum that recommends using cheerio instead of Cheerio. H ...

The sticky navbar fails to stay in place when the content becomes too lengthy

This is my current state of code (minified, for explanation only) index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-w ...

Python's yield functionality facilitates the creation of lightweight generators, allowing

Request is being sent from the front end to trigger the backend method. In Python Flask, the backend method utilizes a generator and yield to iterate through a list of 100000 elements, sending each element one by one to the front end. The goal is for the b ...

How do I implement data range filtering in Typescript?

Seeking assistance with filtering data by date range and forwarding the results to the client. The objective is to extract tickets created within specific dates, but I keep encountering a console error which is proving challenging to resolve. var befor ...

Is there a method to categorize an array of objects by a specific key and generate a new array of objects based on the grouping in JavaScript?

Suppose I have an array structured like this. It contains objects with different values but the same date. [ { "date": "2020-12-31T18:30:00.000Z", "value": 450 }, { "date": "20 ...

Using TypeScript with React Redux, encountering issue of property not being available in the Reducer from the ActionType

Currently, I am learning how to implement a Reducer in Redux while using React with TypeScript. I have encountered an issue that I need help with. Below are the action types that I am working with: import { LoginResponseInterface } from "../../interfaces ...

Defining the type of a component being passed in props in React using TypeScript

Below is the code snippet where the JavaScript version is functioning as expected. However, I encountered an issue when working with TypeScript : import React from 'react' class Parent extends React.Component { render() { return ( ...

Learn how to resolve the issue of "Property 'item' does not exist on type 'never'." in Angular using TypeScript with the following code snippet

addToCart (event: any) { if ("cart" in localStorage) { this.cartProducts = JSON.parse(localStorage.getItem("cart")!) console.log(event); let exist = this.cartProducts.find(item => item.item.id == event.item.id); ...

Converting a constant array of objects in Typescript into a typed index lookup object

const vehicles = [ { id: 'id1', name: 'bike' }, { id: 'id2', name: 'scooter' }, { id: 'id3', name: 'motorcycle' }, ] as const; type VehicleId = typeof vehicles[number]['id']; cons ...

The getMonthlyBalances function is providing inaccurate results when calculating stock balances

One of my functions is called getMonthlyBalances, which takes in two arrays - stocks and trades. It calculates the monthly balance of a user's stock holdings based on their trade history. The stocks array includes objects with stock ID, prices, and da ...

Angular 2 rc5 component fails to load

After transitioning from Angular2 RC4 to RC5, I've been facing some issues. I can't tell if these problems are due to my errors or the transition itself. Here's how my app component looks: import {Component, OnInit} from "@angular/core"; im ...

Is there a way to turn off TypeScript Inference for imported JavaScript Modules? (Or set it to always infer type as any)

As I attempt to utilize a JS module within a TypeScript File, I encounter errors due to the absence of type declarations in the JS module. The root cause lies in a default argument within the imported JS function that TypeScript erroneously interprets as ...

Angular, manipulating components through class references instead of creating or destroying them

I am exploring ways to move an angular component, and I understand that it can be achieved through construction and destruction. For example, you can refer to this link: https://stackblitz.com/edit/angular-t3rxb3?file=src%2Fapp%2Fapp.component.html Howeve ...

NextJS function utilizes its own references within React and automatically fetches data without the need for an import

I recently purchased this template and I'm trying to figure out which page the code snippet "{getLayout(<Component {...pageProps} />)}" is directed to during the initial load. It seems like it might be a global variable hidden somewher ...