TypeScript - Abstract class to the rescue

Recently I found some repeatable code that was repeated due to different methods of retrieving data In my components.

Many times it is required of me to develop solutions on short notice and present working software to companies and almost no time to plan the software with as little information about the end product.

Here is an example of 2 classes with similar functionality but a different type of data and method to obtain the data.

interface BaseProduct {

    name: string;

    id: number;

    price: number;

}


interface ProductsList {

    top: BaseProduct[];

    bottom: BaseProduct[];

}





class SliderX {
    data: ProductsList

    next(): void { };

    getStandartProduct(): ProductsList {
        return { top: [], bottom: [] }
    }
    init() {
        this.data = this.getStandartProduct();
        // .... rest of the logic
    }
}

class SliderY {

    data: ProductsList

    next(): void { }

    init() {

        const baseProduct = this.getBaseProduct();

        const bottom = this.getRecommendedProducts(baseProduct.id);

        this.data = {

            top: [baseProduct],

            bottom
        }
        // .... rest of the logic
    }

    getBaseProduct(): BaseProduct {

        return {
            name: 'someName',

            id: 1,

            price: 33
        }
    }

    getRecommendedProducts(baseProductId: number): BaseProduct[] {

        // get Recommended products from server using the baseProduct
        return [{
            name: 'someName',

            id: 1,

            price: 33
        }];
    }

}




As you can see from the code above, SliderX gets a ProductsList Type and he knows how to work with this type of data. Its a simple request to the server and no need to build the data from the ground.

SliderY doesn't have the same easy life as SliderX. It has few more methods that allow him to get the required data and build the ProductsList by getting the base product first and then recommended products for the base product.

When we have those to types of data we can build ProductsList;

A refactor had to be done those 2 classes have the same functionality and the end product is completely the same, the only difference is setting up the required data for everything to work.

I expect of myself to maintain a single class and adding unique functionality to separate classes.

Achieving this with Abstract class.

interface BaseProduct {

    name: string;

    id: number;

    price: number;

}


interface ProductsList {

    top: BaseProduct[];

    bottom: BaseProduct[];

}


class Slider {
    data: ProductsList

    next(): void { }

    prev(): void { }

    select(): void { }

}

abstract class AbstractSlider extends Slider {

    //will handle this.data 
    abstract initData(): void;

    init() {

        this.initData();
        //... rest of the flow 
    }

}

class SliderX extends AbstractSlider{

    initData() {

        this.data = this.getStandartProduct();

    }

    getStandartProduct(): ProductsList {

        return { top: [], bottom: [] }

    }
}

class SliderY extends  AbstractSlider{

    initData() {

        const baseProduct = this.getBaseProduct();

        const bottom = this.getRecommendedProducts(baseProduct.id);

        this.data = {
            top: [baseProduct],
            bottom
        }
    }

    getBaseProduct(): BaseProduct {

        return {

            name: 'someName',

            id: 1,

            price: 33
        }
    }

    getRecommendedProducts(baseProductId: number): BaseProduct[] {
        // get Recommended products from server using the baseProduct
        return [{

            name: 'someName',

            id: 1,

            price: 33

        }];
    }

}

Now I can maintain my slider and the unique code in my different sliders.

I tried to simplify my case using this example, of course, there could be many approaches to tackle this kind of cases and whatever works for you and your team is great.

要查看或添加评论,请登录

Ray Luxembourg的更多文章

社区洞察

其他会员也浏览了