دفتر سليمان

Article

Define the Purpose Before You Build the Tool

Tools become complicated surprisingly quickly when their purpose is unclear. Defining what a tool exists to accomplish, and what it should deliberately not become, is one of the simplest ways to build better systems.

There is a familiar moment in almost every software project. Someone identifies a problem. A tool is proposed. Development begins. Then something interesting happens. A second problem appears nearby, and the tool could probably solve that too. Then a third. A new field is added. Another screen follows. Permissions become more sophisticated. Reporting is introduced. Someone suggests notifications. Another person asks whether the tool could also manage the workflow that happens before the original process. Before long, a small solution has become a small platform. Sometimes this evolution is useful. Sometimes it is exactly how good products grow. But sometimes the tool simply forgot why it exists. And that is one of the easiest ways to build complexity without building equivalent value.

Start With Purpose, Not Features

When we begin designing something, the natural question is often: What should this system contain? It sounds reasonable. But I increasingly think there is a better question to ask first: What is this system responsible for? The difference matters. Features describe what a system can do. Purpose describes why those capabilities belong there. Without that distinction, almost any useful feature can justify itself. A project-management platform could store documents. A document platform could manage approvals. An approval system could track tasks. A task manager could contain discussion threads. A discussion system could become a knowledge base. Every one of those additions can be defended individually. The problem appears when nobody can explain where one system ends and another begins.

A Tool Needs a Job

I find it useful to think of a software system almost as if it were a member of a team. If I asked:

I would expect a reasonably clear answer. Not every individual performs only one tiny activity, of course. But there should be a coherent area of responsibility. Software deserves the same clarity. A tool should have a job. For example:

That statement immediately helps us reason about future requests. Should it support article drafts? Probably. Should it manage publishing states? Certainly. Should it store media used by those articles? Likely. Should it become the authoritative system for managing every project in the organization? Probably not. The purpose begins creating a boundary. And boundaries are incredibly valuable.

Boundaries Are Not Limitations

The word boundary can sound restrictive. In product development, however, boundaries often create freedom. When a system knows what it owns, developers can improve that responsibility deeply without constantly wondering whether they are accidentally creating another product inside it. Users also understand where to go. Data ownership becomes clearer. Integrations become easier to reason about. Maintenance becomes more predictable. Even future replacement becomes easier because responsibilities are less entangled. A boundary does not mean:

Quite the opposite. Good systems can be highly connected. The important distinction is between owning a responsibility and interacting with a responsibility owned elsewhere. Those are not the same thing.

The Temptation to Build Everything Nearby

Complexity often grows through proximity. Imagine that a publishing platform stores an article associated with a project. The platform needs enough information to display that relationship. The tempting next step is to add project names. Then project descriptions. Then status. Then classification. Then ownership. Soon the content platform contains its own miniature project-management system. It may work perfectly at first. The problem arrives later when a dedicated project platform also exists. Now two systems can answer the question:

And perhaps they give different answers. This is how small conveniences become architectural debt. The mistake was not connecting content to projects. The mistake was allowing the content system to quietly become an authority over something it was never meant to own. A cleaner model would be:

The distinction may appear subtle. Over time, it becomes enormous.

Purpose Helps Us Say “Not Here”

One of the most valuable outcomes of defining purpose is the ability to reject a feature without rejecting the underlying need. Suppose someone asks:

There are at least two possible responses. The first is:

That may be wrong. Perhaps financial tracking is extremely important. The second is:

That is a much stronger architectural response. You are not denying the requirement. You are deciding where the requirement belongs. This distinction allows systems to collaborate without consuming one another.

Purpose Should Be Written Down

A system's purpose should not exist only in the head of its original developer. It should be written. And ideally, it should be short. Something like:

Then add something equally important:

That second sentence is powerful. Most requirements documents describe what a system will do. Mature system design should also record what it will not own. Otherwise every future feature request starts with an empty map.

Purpose Is Not Permanent

Defining a purpose does not mean freezing a product forever. Systems evolve. Businesses evolve. Users discover needs nobody anticipated. Sometimes a system genuinely should expand its responsibility. But that expansion should be a decision. Not an accident produced by fifty individually reasonable feature requests. When a proposed capability significantly changes what a platform is responsible for, we should recognize that we are making an architectural decision. The question changes from:

to:

That is a much healthier conversation.

Feature Requests Become Easier to Evaluate

Once purpose is explicit, individual feature requests become easier to judge. I like asking four questions. Does this capability directly support the system's purpose? If yes, it probably belongs. Does the system need this information to perform its purpose? If yes, it may need to reference or cache the information without owning it. Is another system naturally responsible for this capability? If yes, integration may be better than duplication. Would adding this change what the product fundamentally is? If yes, treat it as an architectural decision rather than an ordinary feature. These questions do not automatically give perfect answers. But they prevent many accidental ones.

The Same Principle Applies Beyond Software

This idea becomes even more useful when we leave software. Projects need purpose. Processes need purpose. Meetings need purpose. Documents need purpose. Even recurring habits benefit from it. Consider a weekly review. If its purpose is:

then collecting information without making decisions is clearly incomplete. Consider a dashboard. If its purpose is:

then adding metrics that never affect a decision may make the dashboard worse rather than better. Purpose becomes a filter. It tells us what deserves inclusion. More importantly, it tells us what does not.

Complexity Is Easy to Add

We sometimes imagine that sophisticated systems are difficult to build because complexity requires expertise. Technically, that may be true. Architecturally, the opposite is often true. Complexity is remarkably easy to create. Every reasonable request adds a little. Every exception adds another branch. Every duplicated responsibility adds synchronization. Every unclear boundary creates another dependency. The difficult discipline is often subtraction. Keeping responsibilities understandable. Keeping data ownership clear. Keeping the system small enough that its behavior can still be explained. A good system does not need to be simple in the sense of being primitive. It needs to be coherent. Complexity may exist inside it, but that complexity should serve a recognizable purpose.

Build the Smallest Complete Responsibility

There is a useful distinction between building the smallest possible product and building the smallest complete responsibility. A tiny system that solves only half of its own problem may be frustrating. But a system that solves its responsibility completely does not need to absorb adjacent responsibilities. Imagine an authentication service. It should probably handle authentication thoroughly. Security. Sessions. Identity verification. Authorization contracts. Recovery. Whatever belongs to its defined responsibility. That does not mean it should also become the user-facing content system simply because both deal with users. Depth inside a responsibility is different from uncontrolled breadth across responsibilities. Strong platforms often become powerful because they go deep where they belong and remain disciplined everywhere else.

Purpose Protects Future Systems

There is another reason this matters. Sometimes the system that should own a capability does not exist yet. That is dangerous. The absence of the future system creates pressure to build its functions into whatever exists today. This can be practical for a while. But we should distinguish between:

and:

A mature architecture can intentionally leave a door for something that does not exist yet. Store the minimum reference. Create an interface. Document the temporary assumption. Avoid deeply embedding the foreign responsibility. Then, when the proper system eventually arrives, there is somewhere for it to live. Architecture is partly about supporting today's reality. It is also about avoiding unnecessary traps for tomorrow.

Before Writing the First Line

Before building a new tool, feature, platform, or workflow, I increasingly want one small artifact first. A purpose statement. Nothing elaborate. Just answers to a few questions: What problem exists? Who experiences it? What responsibility will this tool own? What result should it create? What information does it need from elsewhere? What responsibilities explicitly belong somewhere else? If those questions cannot yet be answered, writing code may be premature. Not because planning should continue forever. But because a few sentences written before development can prevent thousands of lines of code from heading in the wrong direction.

The Tool Should Serve the Purpose

Tools are seductive. Once we start building them, they develop momentum of their own. A database appears. Then APIs. Screens. Components. Automations. Infrastructure. Soon, maintaining the tool itself becomes work. That is not necessarily a problem. But it means we should periodically return to the original question: What is this for? Not: What else could we add? Not: What would make the architecture more impressive? Not even: What would make the tool more powerful? Simply: What is this for? If the answer remains clear, development has a compass. If the answer becomes difficult to articulate, the system may be accumulating capabilities faster than meaning. The best tools are not necessarily the ones that do the most. They are the ones that understand exactly what they are responsible for, perform that responsibility well, and cooperate cleanly with everything around them. Before building the tool, define its purpose. And when the tool begins to grow, define it again.

Filed under

  • Building What Matters
  • Systems Thinking
  • Decision Making
  • Software Design
  • Product Development
  • Architecture
  • Building What Matters