Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] - Builder versus configuration object #3

Closed
jaygarcia opened this issue Jul 21, 2015 · 8 comments
Closed

[Question] - Builder versus configuration object #3

jaygarcia opened this issue Jul 21, 2015 · 8 comments

Comments

@jaygarcia
Copy link

Question as to why you used the builder pattern instead of a configuration object pattern for configuring instances.

The following has ten total method calls just for one button.

var CustomButton = new MKButton.Builder()
  .withBackgroundColor(MKColor.Teal)
  .withShadowRadius(2)
  .withShadowOffset({width:0, height:2})
  .withShadowOpacity(.7)
  .withShadowColor('black')
  .withOnPress(() => {
    console.log('hi, raised button!');
  })
  .withTextStyle({
    color: 'white',
    fontWeight: 'bold',
  })
  .withText('RAISED BUTTON')
  .build();

The MooTools configuration pattern uses just one

var CustomButton = new MKButton({
    backgroundColor : MKColor.Teal,
    shadow : {
        radius  : 2,
        opacity : .7,
        color   : 'black',
        offset  : {
            width  : 0,
            height : 2
        }
    },
    textStyle {
        color      : 'white',
        fontWeight : 'bold'
    },
    onPress : () => {
        console.log('onPress')
    }

});
@jaygarcia jaygarcia changed the title [Question] [Question] - Builder versus configuration object Jul 21, 2015
@xinthink
Copy link
Owner

Hi @jaygarcia, thanks for the valuable question.

The same question has been frustrating me 😖, until I realize that I'm not going to obsolete the object pattern by introducing builder. I just can't, configuration object is built into the heart of ES7 (Object Spread) and thus React (Props Transferring). For example, you're always free to do this:

var coloredButtonProps = {
  style: {
    marginLeft: 20,
    marginRight: 20,
  },
  backgroundColor: MKColor.Purple,
  rippleLayerColor: MKColor.Lime,
  onPress: () => console.log('button clicked'),
};

var buttonTextProps = {
  pointerEvents: 'none',
  style: {
    color: 'white',
    fontWeight: 'bold',
  },
};

<MKButton {...coloredButtonProps}>
  <Text {...buttonTextProps}>
    Halo!
  </Text>
</MKButton>

the props objects can be reused & extended:

var accentButtonProps = {
  ...coloredButtonProps,
  backgroundColor: MKColor.DeepOrange,
};

<MKButton {...accentButtonProps}>
  <Text {...buttonTextProps}>
    Accent colored raised button
  </Text>
</MKButton>

So, my reasoning is that the builder is just another way to make and reuse view definitions, hoping those who feel familiar to builder pattern or method chaining will like it.

An additional reason to introduce builder pattern is that it can make the best out of IDE's code completion feature (e.g. WebStorm).
ide-code-completion

It is not an either-or situation, you can even mix them up, to leverage the pre-defined theme:

var accentButtonProps = {
  ...MKButton.coloredButton().toProps(),
  backgroundColor: MKColor.DeepOrange,
};

<MKButton {...accentButtonProps}>
  <Text {...buttonTextProps}>
    Accent colored raised button
  </Text>
</MKButton>

Hope my choice is reasonable, 🍻. I'll leave this issue open in case of someone interested wanna join the discussion.

@slonoed
Copy link

slonoed commented Jul 22, 2015

Hi! Thanks for great thing.
How to create fab in JSX code?

@xinthink
Copy link
Owner

the most easy way is to leverage the predefined props:

var coloredFabProps = {
  ...MKButton.coloredFab().toProps(),
  style: {
    width: 42, height: 42,
  },
  cornerRadius: 21,
};

<MKButton {...coloredFabProps}>
  <Image pointerEvents="none" source={require('image!plus-white')} />
</MKButton>

if you prefer the tag style

<MKButton
  shadowRadius={2}
  shadowOffset={{width: 0, height: 2}}
  shadowOpacity={.7}
  style={{
    backgroundColor: MKColor.Indigo,
    width: 42,
    height: 42,
  }}
  cornerRadius={21}
  >
  <Image pointerEvents="none" source={require('image!plus-white')} />
</MKButton>

@Sherlock92
Copy link

Can we have more documentation on the standard configuration object style ? I think patterns like the builder pattern are more useful in statically typed languages.

@xinthink
Copy link
Owner

hi @Sherlock92, maybe you're right about builder, but it's not mandatory, like I said, you're free to use React-style props.
About documents, how do u think about the annotated source?

@Sherlock92
Copy link

@xinthink great, I somehow missed these docs. Thanks so much!

@kristian-puccio
Copy link
Contributor

It would be great to able to combine the approaches. So use the builder pattern to configure widgets that you will use then be able to customise them at runtime using props. I know you can do this with some props but not all.

Specifically Text doesn't work, I'm not sure about other props yet.

@trevorwhealy
Copy link

@slonoed previously asked how to create the fab using tag style. If you use MKButton as was shown in the example, you actually still need to pass a prop of fab={true} otherwise onPress the nice spreading effect onPress will outline as a square.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants