Skip to content

Do you consider trait-to-extend as a anti-pattern #310

@sudipghimire533

Description

@sudipghimire533

Trait-to-extend ( I don't know what else could I name it )

I am presenting my opinion for another anti-pattern. While I have treated this as anti-pattern some of my friend says it might be pattern instead. So depending upon the discussion we might add it to (anti-)pattern section

Creating a new trait to extend external struct functionality

The pattern

Suppose this is the content of struct Time in any external crate:

enum Color {
    Red, Green, Blue, Yellow, Black, White, Gray, Custom(u8, u8, u8)
}

struct Style {
    background: Color,
    foreground: Color,
}

impl Style {
    pub fn new(fg: Color, bg: Color, ...other_properties) -> {
        Style {
           foreground: fg, background: bg,
        }
    }
}

And we are using this crate. Suppose now we start to use this Style struct. Now in this application we need to only create Dark style i.e {fg: White. bg: Black} and Light style i.e { fg: Black, bg: White }. What I previoudly did and some of my colleges still do is something like:

use other_crate::{
    Style,
    Color::{Black, White},
};

pub trait LightAndDarK {
  fn get_light(..other_properties) -> Style;
  fn get_dark(..other_properties) -> Style;   
}

impl LightAndDark for Style {
   fn get_light(..other_properties) -> Style {
        Style::new(Black, White)
    }

    fn get_dark(..other_properties) -> Style {
        Style::new(White, Black)
    }
}

fn main() {
    let light_style = Style::get_light(..);
    let dark_style = Style::get_dark(..);
}

I Consider this as anti-pattern. What I prefer a better idea for such case is to:

use other_crate::{
    Style,
    Color::{Black, White},
};

pub struct DarkStyle;
impl DarkStyle {
    pub fn new(..other_prop) -> Style { Style::new(White, Black) }
}

pub struct LightStyle;
impl DarkStyle {
    pub fn new(..other_prop) -> Style { Style::new(Black, White) }
}

fn new() {
    let light_style = LightStyle::new();
    let dark_style = DarkStyle::new();
}

Here the main idea is: there is not a method we want in external struct, since we can't extend external item create a new local trait with desired method and implement it to external item.

What do you think of this? And also if maintainers are willing to add this (anti-)pattern, I would be glad to take responsibility to write this

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions