How do you keep a chunk of information self-contained? How do you package an accumulation of thoughts and facts into one whole? Perhaps more importantly, now that the world is connected over the Internet, how do we make those information packages available for consumption? The answer, of course, is the document — a generalized abstraction that represents a pertinacious embodiment of information we've collected.
Is the document concept something we can continue with moving forward, given the degree of connectedness we all endure? That is, are documents a suitable abstraction with which to enclose and exchange our information? Most people understand the concept. Documents are a generalized notion — you have a document and a suitable application that'll read and possibly alter it. The drawback is that they are in fact a black box. Until a document exists somewhere locally, it doesn't hold any meaning — it is a closed source of information.
Locally Addressable
If you're looking for something, it helps if it's been labeled. Maybe not so much if you're searching an area that has a limited number of items and if each item is uniquely identifiable by it's form alone. But if you're seeking out an item that is surrounded by similar-looking things, a label will identify it. Without the ability to label things, we're required to do some deep inspecting on each individual item. This isn't without it's downsides — the time consumption alone would render us unavailable for anything else.
And so the theory holds inside digital documents — labels can identify what they contain, who they belong to, where they came from, and why they exist. A document stored in a software system is simply a file. The key trait documents inherit from their older file ancestors is that of being addressable. In this context, an address is synonymous with a label you might attach to a physical object — a storage bin for instance. A document has a name, a name that might reflect something about the information contained within. That is, on your computer, if you've got a dozen or so files in a single folder, you need a means to differentiate between them. Without attaching an outward-facing label for the owner, they'd never be able to find what they're looking for without opening each document, looking through the contents, and making sure that it is in fact the information they've sought in the first place.
So our documents have an address — an address we've designated, possibly injecting some meta-data about the document's contents in the process. This really isn't unique to documents, any file on any file system has an address. So what? Bare in mind, however, that a document is simply a concept — as is a file, but more concrete. The idea behind the document abstraction is more geared toward human production and consumption. Sure, applications read documents too, but I think it makes more sense not to confuse the terminology where humans are the creator and the reader. Having said that, when we think addressable, we're thinking of things that we can point to. This includes things inside the document itself.
For example, a document might have one or more headings, it might have a glossary, it might be a spreadsheet with individually addressable cells. So the idea that a document is addressable extends down into what the document contains — it's components are also addressable. No matter who is consuming these documents, human or machine, labels help guide them. Meta-data about the information that instructs on meaning.
The addresses centered around the document concept are only local to where the document is currently stored. This is great for portability, for making sure that no matter where the information ends up, there is always going to be a label that describes a particular data item. And this is why documents are only considered to be locally addressable. The address of something pertaining to a document is meaningless without the document itself — it provides the context. This is meaningful, still, but if we focus too much on ensuring that all our information is stuffed into discrete packages before they move around, we lose our grip on what it means to be globally-connected.
Globally Connected
Having things that are locally addressable is useful only to an extent. Given that documents are an encapsulated object, containing the information we're addressing. So the context is local in scope, the addressable items limited. One of the great attributes of the web is that we're able to define canonical addresses that point to information, regardless of where it is physically located. The address abstraction we're presented with, when working on the web, enables a broader context with which we can point to information and make use of it.
Can we keep in tact the same benefits that the document concept affords? Things such as information encapsulation are indeed valuable. The portable document format let's our information be consumed by anyone, simply because everything associated with that information, including the presentation rules, are blobbed together. And, of course, let's not forget the obvious advantage traditional documents have over other resources found on the web — they work in an offline environment. But like other handy document features, this is becoming less of a concern as well — people have access to a network connection more often than not.
Being connected, having a link to the community of others with which we share information, is the norm. What does this mean for the fundamental document property of self-containment? It seems to me that this priority of being able to ship information back and forth as though we're exchanging physical goods isn't so prudent. Maybe the document concept needs to be broadened slightly, to include some of the more flexible features of the web.
Creating web versions of documents — where the form of the document is assumed on some server and it's editors and readers are presented with something browser-friendly — isn't a new idea. In fact, it was envisioned to solve the exact issues I'm talking about now — to take a concept traditionally thought of as a local item, and make it globally addressable. Instead of working on creating and modifying information locally, and then shipping off to target recipients, the canonical document is used. Now we don't send documents, we point to their address.
Is this model perfect? Perhaps we're starting to move away from the document abstraction altogether. The whole concept of a document is centered around self-contained information that we may choose to send, or we may not. Another area in which the document concept is falling behind in our daily operations on the web is the very fact that documents are so self-contained. Maybe we need to reevaluate what is considered a tightly-knit unit of information? Maybe the document needs to be decomposed into a new concept. Something with smaller parts, all of which are addressable.
Showing posts with label concept. Show all posts
Showing posts with label concept. Show all posts
Friday, February 3, 2012
Tuesday, August 31, 2010
Methods As Concepts
In object-oriented software development, there are classes, and there are methods. Methods are like functions in a functional programming language with an important difference - they don't exist in isolation. Methods belong to an object. Object-oriented programming methodology encapsulates structure and behavior into a single descriptive unit, the class. Classes describe what structure and what behavior an object may have. They are the object blueprints.
Encapsulating the structure and behavior of an object is how software design scales in size and complexity. A developer that uses an object, doesn't know how the behavior of that object is implemented. Nor do they care. They know everything beneath the surface works as expected. Encapsulation isn't limited to objects. A developer using a function only cares that it works as expected, not how the job is carried out.
Objects, in addition to hiding method implementation, hide structure. These are the attributes that give an object it's identity. Functions have no such structure to hide. An object represents a concept, something that exists in the real world, or some intangible thing. Attributes that describe objects in a software system don't exist in functions. They suffer from a lack of identity, and that is the key difference between functions and methods.
With everything object oriented programming languages promises, are functional programming languages still relevant? Objects are nothing more than a design tool, built with functions, that aid in designing complex systems. Functions are a concise, direct way to supply input and get output. The very idea of a function is an elegant one. However, humans need a better way to understand what they've built and this is where abstract objects help. Functions don't cause a program to fall apart - how they're used do.
Methods are intended to manipulate, or retrieve the values of object attributes. If the attribute values of an object embody the state of the object, methods that change attribute values also change the state of the object. Methods are more likely to have side effects than functions. However, this is the intention of methods - to encapsulate the object behavior, including the changing states of the object. Other objects can be passed to methods as parameters. The state of these objects can, in turn, be changed by the method. Does this violate the encapsulation principle? It doesn't because the object being manipulated doesn't care who does it, as long as the public interfaces of the object are used.
What best describes a software object? The methods that realize it's public interface or the attributes that define it's structure? An object represents some concept while an interface represents some behavior, not bound to any particular concept. Imagine I have a class called Object and I ask you what this object represents based on it's run() method. With this information, we can at best determine that it is something that can run but we can't deduce why the object is able to run. A software program can run. An engine, an animal, a person - all things that can run. What if instead of identifying what the object represents by a method, I asked you to identity it by a structural feature - wheel. A object with a wheel attribute has more of an identity than a object with a run() method.
An interface, not necessarily explicit, describes the behavior of an object, not it's structure. By nature, the methods that implement an interface are a behavioral concept. If a given class implements a Runnable interface, which requires a run() method, it can run. The concept of running is tightly coupled with your class. Interfaces, and their corresponding methods, always need to be implemented, even if that implementation is inherited.
Lets take a step back and compare methods and functions again. Functions are pure behavior with input and output. They don't belong to an object so they can't alter it's state. Conversely, methods belong to an object and alter it's state. As object-based systems grow, so do the number of methods. The side effects of these methods also increase in size.
How can we make methods more like functions and maintain an abstract object design that allows the size of the system to scale? Objects are good at representing some concept with structure. The provided interfaces of those objects, the methods it implements, are the challenge. Lets try making methods their own concepts.
Classes define a special type of method - a constructor. This method is called when the object is first created to do any setup the object may need. An alternative perspective: a constructor is the object's owned behavior. It cannot be called externally once the object exists. A constructor is the essence of the object - it is responsible for making the object what it is.
The constructor method is intended to initialize the computing resources the object needs. Languages like C++ use it to allocate memory. Dynamic languages, like Python, don't share this need. Constructors in these languages are used to initialize the attributes of the object because they aren't statically defined. The constructor may call some other methods to perform some validation, or to read some data from the network or hard drive. Other objects might even be created as the result of a constructor being called. Initialization is the primary focus of the constructor method.
If a class represented nothing but behavior, if it had no structure, the constructor of that class is the behavior. The constructor parameters would be the parameters to the behavior. For example, if Runnable were a class instead of an interface, the constructor would run instead of calling methods defined by the interface. Picture the constructor as a function. Its input the parameters supplied to the constructor. Its output the changes in state to the objects supplied as input. Lets call this type of class a behavioral class.
What about functions that return values? Can behavioral classes return values? Doing so is counter-intuitive because the constructor returns the instance of the behavioral class it self. Instead, the return value is placed in a result attribute of the object. There is a problem with this approach, however. If you were to place the result of creating the behavioral class in an attribute, the object must still exist when the result is used.
On the other hand, traditional methods bound to their objects, need to stick around for the entire life of the object. From an identity perspective, it doesn't make much sense. Once the object is dead, the behavior of that object doesn't really exist either. It might still exist in the blueprint, the class of that object, but that may not necessarily be optimal. Behavior is a concept in its own right.
Methods can be inherited from parent classes. The specialized class has all the generic behavior of the parent. Would a behavioral class negate this aspect of inheritance? Not exactly. If behavior were implemented as a class, it can also inherit general behavior. We have to think differently about how the generalization would work. Traditionally, inherited methods are called in a polymorphic context. That is, they are called when an object that supports the method in question is used. If a method is a class, similar to a function, the constructor needs to call the parent constructor, usually sharing the same signature. Some languages take care of the parent constructor implicitly, like C++.
So can methods as classes, or concepts, actually work? Possibly. Method objects would take care of the behavior identity problem. This approach addresses the notion that behavior is a separate idea from that of object structure. They are similar to functions in that they have no real structure. Methods as concepts, or behavioral classes, can be used in conjunction with existing objects and methods. At least in an experimental sense.
Encapsulating the structure and behavior of an object is how software design scales in size and complexity. A developer that uses an object, doesn't know how the behavior of that object is implemented. Nor do they care. They know everything beneath the surface works as expected. Encapsulation isn't limited to objects. A developer using a function only cares that it works as expected, not how the job is carried out.
Objects, in addition to hiding method implementation, hide structure. These are the attributes that give an object it's identity. Functions have no such structure to hide. An object represents a concept, something that exists in the real world, or some intangible thing. Attributes that describe objects in a software system don't exist in functions. They suffer from a lack of identity, and that is the key difference between functions and methods.
With everything object oriented programming languages promises, are functional programming languages still relevant? Objects are nothing more than a design tool, built with functions, that aid in designing complex systems. Functions are a concise, direct way to supply input and get output. The very idea of a function is an elegant one. However, humans need a better way to understand what they've built and this is where abstract objects help. Functions don't cause a program to fall apart - how they're used do.
Methods are intended to manipulate, or retrieve the values of object attributes. If the attribute values of an object embody the state of the object, methods that change attribute values also change the state of the object. Methods are more likely to have side effects than functions. However, this is the intention of methods - to encapsulate the object behavior, including the changing states of the object. Other objects can be passed to methods as parameters. The state of these objects can, in turn, be changed by the method. Does this violate the encapsulation principle? It doesn't because the object being manipulated doesn't care who does it, as long as the public interfaces of the object are used.
What best describes a software object? The methods that realize it's public interface or the attributes that define it's structure? An object represents some concept while an interface represents some behavior, not bound to any particular concept. Imagine I have a class called Object and I ask you what this object represents based on it's run() method. With this information, we can at best determine that it is something that can run but we can't deduce why the object is able to run. A software program can run. An engine, an animal, a person - all things that can run. What if instead of identifying what the object represents by a method, I asked you to identity it by a structural feature - wheel. A object with a wheel attribute has more of an identity than a object with a run() method.
An interface, not necessarily explicit, describes the behavior of an object, not it's structure. By nature, the methods that implement an interface are a behavioral concept. If a given class implements a Runnable interface, which requires a run() method, it can run. The concept of running is tightly coupled with your class. Interfaces, and their corresponding methods, always need to be implemented, even if that implementation is inherited.
Lets take a step back and compare methods and functions again. Functions are pure behavior with input and output. They don't belong to an object so they can't alter it's state. Conversely, methods belong to an object and alter it's state. As object-based systems grow, so do the number of methods. The side effects of these methods also increase in size.
How can we make methods more like functions and maintain an abstract object design that allows the size of the system to scale? Objects are good at representing some concept with structure. The provided interfaces of those objects, the methods it implements, are the challenge. Lets try making methods their own concepts.
Classes define a special type of method - a constructor. This method is called when the object is first created to do any setup the object may need. An alternative perspective: a constructor is the object's owned behavior. It cannot be called externally once the object exists. A constructor is the essence of the object - it is responsible for making the object what it is.
The constructor method is intended to initialize the computing resources the object needs. Languages like C++ use it to allocate memory. Dynamic languages, like Python, don't share this need. Constructors in these languages are used to initialize the attributes of the object because they aren't statically defined. The constructor may call some other methods to perform some validation, or to read some data from the network or hard drive. Other objects might even be created as the result of a constructor being called. Initialization is the primary focus of the constructor method.
If a class represented nothing but behavior, if it had no structure, the constructor of that class is the behavior. The constructor parameters would be the parameters to the behavior. For example, if Runnable were a class instead of an interface, the constructor would run instead of calling methods defined by the interface. Picture the constructor as a function. Its input the parameters supplied to the constructor. Its output the changes in state to the objects supplied as input. Lets call this type of class a behavioral class.
What about functions that return values? Can behavioral classes return values? Doing so is counter-intuitive because the constructor returns the instance of the behavioral class it self. Instead, the return value is placed in a result attribute of the object. There is a problem with this approach, however. If you were to place the result of creating the behavioral class in an attribute, the object must still exist when the result is used.
On the other hand, traditional methods bound to their objects, need to stick around for the entire life of the object. From an identity perspective, it doesn't make much sense. Once the object is dead, the behavior of that object doesn't really exist either. It might still exist in the blueprint, the class of that object, but that may not necessarily be optimal. Behavior is a concept in its own right.
Methods can be inherited from parent classes. The specialized class has all the generic behavior of the parent. Would a behavioral class negate this aspect of inheritance? Not exactly. If behavior were implemented as a class, it can also inherit general behavior. We have to think differently about how the generalization would work. Traditionally, inherited methods are called in a polymorphic context. That is, they are called when an object that supports the method in question is used. If a method is a class, similar to a function, the constructor needs to call the parent constructor, usually sharing the same signature. Some languages take care of the parent constructor implicitly, like C++.
So can methods as classes, or concepts, actually work? Possibly. Method objects would take care of the behavior identity problem. This approach addresses the notion that behavior is a separate idea from that of object structure. They are similar to functions in that they have no real structure. Methods as concepts, or behavioral classes, can be used in conjunction with existing objects and methods. At least in an experimental sense.
Subscribe to:
Posts
(
Atom
)