Known outside properties

+ hide inner mechanics

+ giving it a name

=> Abstraction

+ defining return value

...or shouldn't they???

NOW, YOU REPEAT THIS

NAMING THINGS

small methods are simple

small methods are simple

Gather together the things that change for the same reasons. Separate those things that change for different reasons.

Single Responsibility Principle

The Open/Closed Principle

open for extension / closed for modification

You should be able to extend the behavior of a system without having to modify that system.

duplication is far cheaper

than the wrong abstraction

duplication is far cheaper

than the wrong abstraction

Why people don't refactor

"Make the change easy. This might be hard. And then make the easy change."

Don't let sunk costs guide you

When dealing with wrong abstractions while refactoring, the fastest way forward is back:

  1. Re-introduce duplication by inlining the abstracted code back into every caller.
  2. Within each caller, use the parameters being passed to determine the subset of the inlined code that this specific caller executes.
  3. Delete the bits that aren't needed for this particular caller.

Separation of Concerns

A Software system must be decomposed into parts that overlap in functionality as little as possible

Modular programming is a software design technique that emphasizes separating the functionality of a programme into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality

Modules FTW!

Wait!

Which concerns?

What "one aspect"???

Back at abstractions

Abstraction allows us to treat something complicated as one simple thing.

Leaky abstractions

A leaky abstraction is an abstraction that fails at encapsulating.

Adding leaky abstractions might add complexity

If you have to know about internals of your abstraction on the outside, you added complexity instead of reducing it.

Let's practice

// Dirty
import Title from './Title';
export const Thingie = ({ description }) => (
  <div class="thingie">
    <div class="description-wrapper">
      <Description value={description} />
    </div>
  </div>
);
export const ThingieWithTitle = ({ title, description }) => (
  <div>
    <Title value={title} />
    <div class="description-wrapper">
      <Description value={description} />
    </div>
  </div>
);
// Clean
import Title from './Title';
export const Thingie = ({ description, children }) => (
  <div class="thingie">
    {children}
    <div class="description-wrapper">
      <Description value={description} />
    </div>
  </div>
);
export const ThingieWithTitle = ({ title, ...others }) => (
  <Thingie {...others}>
    <Title value={title} />
  </Thingie>
);

Task: DRY up

// Dirty
const Icon = ({ className, onClick }) => {
  const additionalClasses = className || 'icon-large';
  return (
    <span
      className={`icon-hover ${additionalClasses}`}
      onClick={onClick}>
    </span>
  );
};
// Clean
const Icon = ({ className = 'icon-large', onClick }) => (
  <span className={`icon-hover ${className}`} onClick={onClick} />
);
// Cleaner
const Icon = ({ className, onClick }) => (
  <span className={`icon-hover ${className}`} onClick={onClick} />
);
Icon.defaultProps = {
  className: 'icon-large',
};

Task: Clean Up

Let's talk about Tabby and the PollMetaDataSheet

Abstraction

By bastianalbers

Abstraction

Thoughts on abstraction

  • 218