Abstraction Can Make Your Code Worse

CodeAesthetic
20 Nov 202205:13

Summary

TLDRThe video script discusses the trade-offs between code abstraction and coupling in software design. It illustrates how abstraction can simplify code by reducing repetition but may inadvertently increase coupling, complicating future modifications. The speaker uses examples from game development and data saving to highlight when abstraction is beneficial, such as when multiple save options are needed or when deferring the decision of which method to save. The key takeaway is to apply abstraction judiciously, prioritizing the value it adds over the potential for increased coupling.

Takeaways

  • ๐ŸŽฎ In game development, creating a 'Game Object' class can help manage position and rendering for characters and obstacles, reducing code repetition.
  • ๐Ÿ”„ Abstraction is a powerful tool in software design, but it should be used judiciously to avoid unnecessary coupling.
  • ๐Ÿ”— Coupling is the interdependence between components of a system; increased abstraction can inadvertently increase coupling.
  • ๐Ÿ“š When migrating from XML to JSON, consider creating separate classes to avoid entangling the new format with the old, making future changes easier.
  • ๐Ÿšซ Avoid creating a 'file saver' superclass that forces subclasses to accept a file input, as it can limit future flexibility and break abstraction.
  • ๐Ÿ”„ Code repetition is sometimes preferable to over-abstraction, as it can be less painful when making changes to the system.
  • ๐Ÿ” Before abstracting, consider the benefits it brings, such as simplifying the program or enabling new features.
  • ๐Ÿ”„ Use interfaces sparingly; they can increase coupling and only provide value when multiple classes share a common method.
  • ๐Ÿ”„ Abstraction is most valuable when it allows for deferred or repeated actions, such as interval-based saving.
  • ๐Ÿ”„ Evaluate the trade-offs between abstraction and coupling on a case-by-case basis, considering the specific needs of the project.
  • ๐Ÿ“ˆ Prioritize maintaining a balance between abstraction and coupling to ensure the system remains maintainable and flexible.

Q & A

  • What is the main purpose of creating a 'Game Object' class in the given game development scenario?

    -The 'Game Object' class is created to handle the common functionality of tracking position and rendering images for the main character, enemy characters, and obstacles, avoiding code repetition across these classes.

  • What is the tradeoff associated with abstraction in software design?

    -The tradeoff associated with abstraction is coupling. For every abstraction added, there is an increase in coupling, which can make the system more interdependent and potentially harder to modify.

  • Why might it be a bad idea to create a 'FileSaver' class that both XML and JSON writers inherit from?

    -Creating a 'FileSaver' class would couple both XML and JSON writers to the same input (file name), which would make it difficult to adapt to new saving methods like a database or cloud connection without breaking the abstraction.

  • What are the two cases where abstraction might be considered valuable in the context of the script?

    -Abstraction might be valuable when there are multiple save options with different parameters, or when the program needs to defer or repeat saving at different points in time, such as with an 'IntervalSaver' class.

  • What is the 'IntervalSaver' class mentioned in the script?

    -The 'IntervalSaver' class is a hypothetical class that would handle the task of saving data at regular intervals, without needing to know which specific saver (like XML or JSON) it is calling.

  • Why is it sometimes better to have code repetition rather than over-abstraction?

    -Code repetition might be better than over-abstraction because it can lead to less pain when changing code, as it avoids the complexities and dependencies that come with high coupling.

  • How does the script suggest deciding when to apply abstraction?

    -Abstraction should be applied when the value it brings, such as easier maintenance or flexibility, outweighs the increased coupling it introduces.

  • What is the significance of the 'save' method in the context of the script?

    -The 'save' method is significant because it represents a potential point of abstraction. However, the script suggests that creating a common interface for it might not simplify the program meaningfully and could increase coupling.

  • What is the role of the 'save' logic configuration in the script's example?

    -The 'save' logic configuration is mentioned as a potential way to support both XML and JSON formats. However, it is criticized for complicating the removal of XML support, as it intertwines the logic of the two formats.

  • How does the script relate the concepts of abstraction and coupling to the practice of software design?

    -The script illustrates that while abstraction can help manage complexity and reduce code repetition, it also introduces coupling, which can make systems more difficult to modify. It encourages developers to consider the balance between these two aspects when designing software.

Outlines

00:00

๐ŸŽฎ Abstracting Game Code

The paragraph discusses the concept of abstraction in game development. It starts with a scenario where a game has main characters, enemies, and obstacles, each requiring code for position tracking and rendering. To avoid repetition, a 'Game Object' class is created to handle these tasks, allowing subclasses to specify the image. The speaker then introduces the trade-off between abstraction and coupling, suggesting that abstraction can lead to increased coupling. An example is given where changing the data format from XML to JSON involves creating a separate JSON writer class, which simplifies the process of removing XML support. However, the speaker argues against creating a 'file saver' class to avoid coupling and breaking the abstraction if the need for a non-file-based saver arises. The paragraph concludes by questioning the value of abstraction when it doesn't provide significant benefits and suggests that sometimes, a little code repetition is preferable to over-coupling.

05:01

๐Ÿ”„ Balancing Abstraction and Coupling

This paragraph continues the discussion on abstraction and coupling, emphasizing that while code repetition is often seen as bad, it can sometimes be less problematic than over-coupling. The speaker suggests that it's better to have distinct classes with no connection rather than creating an interface that increases coupling. Two scenarios are presented where abstraction might be beneficial: when there are multiple save options or when the decision of which saver to use needs to be separated from the actual saving process. The speaker concludes that abstraction should only be applied when its benefits outweigh the coupling it introduces, even if it means some code repetition.

Mindmap

Keywords

๐Ÿ’กGame Object

In the context of the video, a 'Game Object' is a class created to handle common functionalities such as tracking position and rendering images for different entities in a game, like the main character, enemies, and obstacles. This concept is used to illustrate the idea of abstraction, where similar code is generalized to avoid repetition across different classes.

๐Ÿ’กAbstraction

Abstraction refers to the process of creating a generalized implementation for common features in software development. In the video, it is demonstrated through the creation of a 'Game Object' class that reduces code duplication. However, the video also warns of the trade-off between abstraction and coupling, emphasizing the need to balance these aspects in software design.

๐Ÿ’กCoupling

Coupling is a measure of how tightly interconnected components of a system are. High coupling means components are highly dependent on each other, which can make a system difficult to modify. The video discusses coupling as a byproduct of abstraction, where creating a shared class or interface can inadvertently increase the dependencies between different parts of a program.

๐Ÿ’กXML

XML, or Extensible Markup Language, is a data format used for storing and transporting data. In the video, it is mentioned as an old format that the program initially uses for saving data. The discussion around XML and JSON highlights the challenges of updating systems when they are tightly coupled with specific technologies.

๐Ÿ’กJSON

JSON, or JavaScript Object Notation, is another data format that is more modern and often preferred over XML for its lightweight and human-readable nature. The video uses the transition from XML to JSON to illustrate the trade-offs involved in refactoring a system to adopt new technologies while maintaining backward compatibility.

๐Ÿ’กFile Saver

The 'File Saver' is a hypothetical common class proposed in the video to handle the file-saving functionality for different data formats. The concept is used to demonstrate the potential pitfalls of over-abstraction, where creating a shared class can lead to unnecessary coupling and limit future flexibility in the system design.

๐Ÿ’กInterface

An interface in programming is a contract that specifies a set of methods that a class must implement. The video discusses the idea of creating a common interface for the 'save' method, which would increase coupling between different save classes. It highlights the importance of considering the benefits and drawbacks of such abstractions.

๐Ÿ’กCode Repetition

Code repetition, or duplication, occurs when the same or similar code appears in multiple places in a program. The video suggests that while abstraction can eliminate code repetition, it's important to weigh the benefits against the potential increase in coupling. In some cases, a little code repetition might be preferable to over-abstraction and its associated coupling issues.

๐Ÿ’กDatabase

A database is a structured set of data that can be accessed, managed, and updated. The video mentions databases as an alternative to file-based saving, which would require a different approach and could break the abstraction if it was based on file input, illustrating the importance of considering future requirements when designing software.

๐Ÿ’กCloud Connection

A cloud connection refers to the ability of a system to interact with remote servers or services hosted on the internet. The video uses the concept of a cloud connection to illustrate how future changes in technology might necessitate a redesign of the system, breaking the abstraction if it was not designed with such changes in mind.

๐Ÿ’กInterval Saver

The 'Interval Saver' is a hypothetical class mentioned in the video that would automate the saving process at regular intervals. This concept is used to demonstrate a scenario where abstraction becomes beneficial, as it allows the 'Interval Saver' to be agnostic to the specific saving method being used, thus providing flexibility and separation of concerns.

Highlights

Creating a 'Game Object' class to handle position tracking and rendering for main characters, enemies, and obstacles.

The importance of avoiding code repetition by using abstraction.

The concept of coupling as an equal and opposite reaction to abstraction.

The tradeoff between abstraction and coupling in software design.

The example of migrating from XML to JSON data format and the implications for abstraction.

The potential complications of mixing XML and JSON save logic.

The decision to separate JSON writing into a distinct class for easier maintenance.

The pitfalls of creating a 'File Saver' class due to increased coupling.

The argument against unnecessary abstraction that doesn't provide significant benefits.

The suggestion to keep classes distinct when abstraction does not add value.

The potential benefits of abstraction when dealing with multiple save options or deferred saving.

The 'Interval Saver' class as an example of a situation where abstraction is beneficial.

The principle of applying abstraction only when its value outweighs the coupling.

The acceptance of some code repetition as a lesser evil compared to over coupling.

The importance of balancing abstraction and coupling for effective software design.

Transcripts

00:00

You have a game where you have a main character, enemy characters and obstacles.

00:05

For each of these objects we need to have code that keeps track

00:09

of its position in the world and code for rendering the image for each object.

00:15

We could write the same code in all three classes,

00:18

but you recognize that this is all similar.

00:21

So instead you make a third class called Game Object that handles this for you.

00:26

You now have a general implementation that tracks and renders out the object.

00:31

The code is mostly identical, but you allow the subclass to specify

00:36

which image is shown.

00:39

You just created an abstraction.

00:46

Architects have gotten really good at this game

00:50

of identifying repetition and extracting it out.

00:53

We get into the mode of code repetition bad, more abstraction good.

00:58

But there's a hidden tradeoff that doesn't get considered: Coupling.

01:02

Most engineers conceptually understand what coupling is,

01:06

and they definitely feel its web when trying to modify an over coupled system.

01:10

But when designing software, you don't feel

01:13

the impacts of coupling.

01:17

I consider coupling to be an equal and opposite reaction of abstraction.

01:21

For every bit of abstraction you add, you've added more coupling.

01:26

Let's explore an example.

01:28

We have a program that saves out data to XML, but that's the old format.

01:33

So we want to move to JSON.

01:38

We could do this by adding a configuration to the save logic

01:41

to support both modes.

01:48

But this will make the removal

01:49

of XML complicated and dangerous

01:52

because they're all intermingled.

01:57

So instead we'll make the JSON writer a separate class.

02:00

Then we can just chop off the XML support by deleting the whole file,

02:04

not needing to unweave the program logic.

02:08

All right, so now we've written our fancy new JSON writing class.

02:12

We might notice that both take in a file name during construction.

02:16

Our little repetition detectors go off and realize that maybe.

02:21

Maybe we could extract this out.

02:24

So our instinct is to create a common class called file saver

02:28

that just takes the file name, and our subclasses can grab it

02:31

from this protected variable.

02:38

But this is a bad idea.

02:40

We've now coupled both of these classes to the same input.

02:44

They must take a file input.

02:46

So if there ever became a need to create something that didn't use a file

02:51

like a database or cloud connection, this would break the abstraction.

02:55

And on the flip side, this abstraction brings us no value.

02:59

What does this abstraction save us?

03:01

Well, I guess we don't need to assign the variable twice.

03:05

But this isn't any complicated logic.

03:07

It's simply assigning a variable.

03:09

So for me, this squarely fits into the not worth it camp.

03:14

Okay, now what about the save functionality?

03:18

We could consider creating an interface that represents the โ€œsaveโ€ method,

03:21

but we do know that this would increase coupling because now

03:24

both of these classes are constrained to the same save method.

03:29

So what benefits does this abstraction bring us?

03:32

Well, let's look at the usage.

03:35

We have an if statement that decides which class

03:37

to create and calls save on one of them.

03:40

So if we add a common interface,

03:42

we only get to remove this one duplicate save line.

03:46

That doesn't simplify the program in any meaningful way.

03:50

So I'd also put this into the it's not worth it camp.

03:53

At this point it's better to keep these as two distinct classes

03:57

with no connection at all.

04:01

There are two cases where it would make me decide it was worth it.

04:05

One would be if we added more save options.

04:08

If we had three or more we might want to extract the construction

04:11

of these save objects into a separate piece of code, especially

04:17

if the different savers had different parameters, like a database configuration.

04:23

The other case would be if we needed our program to defer

04:27

or repeat saving at a different point in the program.

04:30

For example, if we wanted to save every 5 minutes

04:33

automatically, weโ€™d create a class called โ€œIntervalSaverโ€,

04:37

and it would make sense for this Interval Saver class

04:40

to be unaware which saver it's calling.

04:43

In both cases, it becomes worth it when we want to separate the decision

04:46

of which saver we want from the time we actually want to save.

04:52

Overall, it's good to only apply abstraction

04:55

when the value it brings overweighs the coupling.

04:58

This does mean that you might have a little bit of code repetition.

05:01

But I think that a little code repetition

05:03

brings less pain when changing code than over coupling.

05:07

What do you think?

Rate This
โ˜…
โ˜…
โ˜…
โ˜…
โ˜…

5.0 / 5 (0 votes)

Related Tags
SoftwareDesignAbstractionCouplingCodeOptimizationProgrammingPrinciplesGameDevelopmentObjectOrientedJSONXMLDataFormatsInterfaceDesign