An Object Model

If you were to draw out all the objects in your system and their relationship to each other at runtime, that would be a graphical representation of your object model.

Object-oriented programming is about modeling the behavior of entities. It is a programming paradigm that, when used correctly, helps us build resilient systems that are straightforward to understand and extend. But we gain these benefits only by correctly using the object-oriented paradigm, which involves having a domain model that reflects what’s being modeled.

Designs often start out with a good domain model but then degrade over time as new features are added. Features get hacked in and new behaviors are bolted onto existing objects rather than expanding the object model to include these new classes. This distorts the object model and makes it more difficult to understand. Behaviors, and even entirely new classes, can be hiding in long methods. Pulling them out makes the code clearer and cleaner.

Object-oriented programming languages allow us to define classes and instantiate objects, but I find some developers resistant to doing that, having the false impression that creating objects is expensive and makes a system less efficient. But creating object instances are cheap, and modern runtimes are optimized for this. We should be defining classes and making objects all the time.

Any group of behaviors that converge around a set of values or state should be defined as a class. Since a class can represent anything, we can think of it in many ways, but most fundamentally as a concept that aggregates behaviors, often around a common set of instance data. For example, a savings account aggregates behaviors like deposits and withdrawals around an account balance.

Classes and objects, their runtime representations, can contain data that represents its state. They can also contain methods that represent its behaviors.

Though classes may only contain data and methods, object-oriented languages provide a rich environment for modeling anything. Classes can represent anything from tangible objects to ephemeral ideas. They can be a part of a larger whole, or they can represent the relationship between different entities.

Classes can be anything.

And there’s the rub.

We have to name our classes well. If we don’t create good, intention revealing names, our object model becomes distorted. If we stuff behavior into another object that belongs in its own object, the object model gets distorted. If we fail to call out classes in our domain or spread responsibilities across multiple, unrelated classes, our object model gets distorted.

When an object model gets distorted it becomes hard to read and understand. Worse still, a distorted object model will often lack flexibility precisely where flexibility is most needed.

Going against a design to special case features can often lead to maintainability issues, so we want to keep our object model robust and clear. We want it to reflect reality: the thing we’re modeling. The way we do this is by calling out classes when we find them. We must actively look for classes and continue to expand our object model as our knowledge of our system expands. This is how we keep a system maintainable.

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

David Scott Bernstein的更多文章

  • Green Tests and Red Tests

    Green Tests and Red Tests

    In practice, I found that there are times that I want a bit more test coverage than I get from just doing test-first…

  • Radiators and Silos

    Radiators and Silos

    In the old days of corporate America, the way you got ahead was through hard work and perseverance. You strove to…

    1 条评论
  • Makers and Menders

    Makers and Menders

    I’ve been getting back into some research interests of mine that require data acquisition from a variety of sensors so…

  • Core Developer Practices

    Core Developer Practices

    Every field of engineering has a core set of practices that they follow and software engineering is no different. But…

    1 条评论
  • Still XP After All These Years

    Still XP After All These Years

    Are you humming in your head Paul Simon’s “Still Crazy After All These Years”? I am. And it does seem crazy.

  • The Importance of Continuous Integration

    The Importance of Continuous Integration

    Perhaps the most important yet easiest to implement of all the software development practices in Agile is continuous…

  • The Importance of Technical Practices (Again)

    The Importance of Technical Practices (Again)

    Software development has undergone many revolutions over the last few decades. The way we build software today is…

  • Summary of Seven Strategies Series

    Summary of Seven Strategies Series

    I finished my “Seven Strategies” series of 72 blog posts with seven strategies for implementing each of the nine…

    1 条评论
  • Refactor to Learn What Not to Do

    Refactor to Learn What Not to Do

    One of the things that I was not expecting when I started refactoring other people’s code was that I started to see…

    4 条评论
  • Refactor to Clean Up Before Moving On

    Refactor to Clean Up Before Moving On

    Of course, the best time to refactor code is while it’s fresh in your mind, right after having worked with it. Once I…

社区洞察

其他会员也浏览了