Showing posts with label interface. Show all posts
Showing posts with label interface. Show all posts

Wednesday, May 25, 2011

Interface Connection Thinking

Software object systems, are a collection of objects, connected by relationships. Typically, objects are connected by structural relationships. I can think of a dozen real-world analogies when I'm writing code. When I think of these analogies, I'm thinking about the physical structure of the buildings, cars, engines, books, anything really, that inspires my software design. This is why object-oriented software uses the object as the fundamental unit, not the behaviour. We don't focus on the behaviour of our software when we're designing it. At least it isn't the first thing we consider when starting a new project. I don't think “what are the major behavioural components of this system”? The first thing that comes to mind when building from scratch is something along the lines of “what are the fundamental data structures I'll need to make this work?”. Maybe this approach is backward.

Emphasis on the data structures taking precedence over how the software works – the moving parts of the system – is hard to overcome because we're so used to making analogies to real-world objects and their properties. This is an essential feature of our brain – if you cannot distinguish between dangerous objects and irrelevant objects or beneficial objects, your chances of survival are slim to say the least. We differentiate between objects in the real-world based on their attributes – the things we can see. We recognize objects by nothing more than their physical attributes – their shape, their colour. My desk I work at everyday stands out relative to every other desk in the office because of its attributes. The monitor, the coffee mug, the unsorted pile of paper – all things that make the desk unique and recognizable.

This isn't to say that we don't make analogies with regard to how things function, the way they move or produce output. My desk, of course doesn't do anything very interesting, or anything at all for that matter. It just sits there – I have no real need to compare what it does to anything else. My car, on the other hand, has several interesting characteristics other than its less-tangible attributes. I can use these to make comparisons - to other cars, or other objects. The car moves – hopefully in more than one direction. It has a maximum speed and it turns. I could go on, but that would be overkill. Clearly, we're capable of making behavioural analogies too. The question is, why do we favour the structural when it comes to software design?

As we know, software is a host of objects connected to one another. I'm not sure there is as much a distinction between structural and behavioural aspects as we might think. The structure of software objects is like glue - it prevents an objects from becoming unraveled and going rogue in the system. When we're thinking abstractly, we're thinking that structure equals order. If we could only build the perfect foundation, we could add the required functionality on top. Everything will work better than it would had we not built a solid base. I'm not sure this is the correct view to take.

My reasoning is simple – interfaces describe what an object does, and suggests some structural attributes the object might have, based on its name. Interfaces are concrete in their behavioural descriptions and tentative in their structural descriptions. This is because interfaces give all the necessary details for implementing the interface methods – the behaviour. If the interface has a good, descriptive name, you can glean some potential attributes that support the implementation. The objects attributes aren't part of the interface contract whereas the operations are. This is important, I think, for at least some degree of implementation freedom. Whats really important with interface connections is that clients get what they expect from their suppliers.

Suppose we've got an IReader interface that requires a read() method be implemented by any objects that provide the interface. The read() method is supposed to return data. How it does this, exactly, is up to the implementation. Maybe the data is read from a file, maybe from an attribute stored in memory, maybe from a network connection. These are all implementation concerns, not that of the interface. The interface serves as a connector, putting the emphasis on what that implementing object does. The client object knows what it needs, in the case of the IReader interface, it needs an object that can read data.

So how does thinking in interface connections result in better software? I think it takes the focus away from the structural properties of objects and places it on the behavioural descriptions. Objects still have attributes, even when we're emphasizing the interface connections. However, these are more closely tied to the implementation than the design. Connecting objects by what they do is how you connect objects by design instead of by implementation.

Monday, February 7, 2011

Implicit Encapsulation

Understanding large data structures in software is hard. Using abstract entities helps us understand what we're building by hiding information about the structure that we aren't interested in. This is what encapsulation is all about. Software objects are simplifications of some idea, so, anything. The cohesiveness of abstractions in a software system, how understandable they are, what information they expose, the impact they have on other abstractions in the system - we don't consider things things once we've hacked something together that works. Of utmost importance is that it works, not how comprehensible the classes are. How do we measure abstraction quality? Encapsulation is a design principle, one that allows us to remove irrelevant aspects from the problem at hand, which makes it hard to objectify. We can look at some trade-offs of various encapsulation approaches. For instance, some programming languages allow us privatize object attributes - hide them from other objects. As developers, have an amplified ability to hide irrelevant details that aren't beneficial to us. How valuable is explicitly changing the visibility of an object attribute so as to hide it?

What makes an attribute irrelevant to the outside world? Not only irrelevant, but dangerous if exposed due to misuse by other developers. Subscribing to this attitude when it comes to information hiding is somewhat useless - your code is always going to be abused no matter how you try to protect it. We can safeguard against misuse to some degree by hiding attributes as you can't change what you can't see. Once I've marked my attribute as private, it is as though it never existed. If we wanted to get fancy with how our abstraction is discerned, we could implement and endless combination of public, private, and protected visibility settings. This type of configuration, we don't want to be stuck with. I can see the code, so I can see the attribute marked as private in one way or another - it isn't as though I'm completely ignorant of it's existence. I just can't use it there is usually no apparent reason as to why. What makes an attribute irrelevant to the outside world?
Private attributes inaccessible to other objects exist as part of the internal structure of the object. They give the object it's character, even if we can't see it from the outside. For instance, public attributes can be derived from private ones. Say I have a Product class with two private attributes - sellerCost and profitMargin. A public attribute, buyerCost, could then derive it's value from the two private attributes. The outside world only cares about the buyerCost, not how it was computed. The two private attributes are encapsulated - nobody can see them. Attempts to access sellerCost or profitMargin are met with failure. Where do we set the value of these private attributes?

The constructor is a good place to set attribute values. Passing object attribute values to the constructor isn't the same as modifying the attributes after instantiation. Think of it this way - creating an object is more than just saying "create a new product". You create objects by saying things like "create a new product with a seller price of $15 and a profit margin of 25%". This creates a product instance, different from those with a $500 seller price and 16% profit margin. If we're able to change these values after the object's existence has been established, we're in effect creating a new object. This is an abstract idea, you can obviously change attribute values all you want once an object is created as long as it isn't static. If we know we're supposed to set attributes in the constructor, we know that we're using an object that relies on initial values that don't change throughout the duration of it's life. Knowing this leads to better understanding of the system under construction because we can see the expected values used by derived attributes.
Objects change state in a running system, meaning, an object's attributes change value. Otherwise, we'd have a completely static system that just creates objects and doesn't do anything interesting with them. In the spirit of encapsulation, one approach to changing the state of an object is by using setters. Setters are nothing more than simple methods that set the value of a private attribute. There are also getters - methods that return the value of a private attribute. All we're doing by adopting this methodology is forcing developers to take a scenic route to storing and retrieving object values. Why not just read the attribute directly? Why not assign a value to an attribute directly? If you have a method that does this for you, you're not improving the encapsulated design of your code. Remember, the idea is to hide data that is irrelevant to the outside world, not to impose an unnecessary data conduit. When the state of an object changes or when data is read from an object, you may want to trigger some event. This is easy to do with setters and getters - set the data, trigger the event. However, this isn't within the scope of encapsulation - if setters and getters provide you with convenience, then by all means, go for it. Just don't assume that you've hidden all irrelevant attributes properly.

We've established that the visibility of an attribute doesn't necessarily dictate the level of encapsulation an object exhibits. It is up to the developer who designs that class to implement an outer wrapper that the outside world can see. Is this possible without explicitly saying so in the code? Can I implement a class that when instantiated, provides an adequate interface to fulfill the object's responsibilities? An interface says more about information hiding than the attribute visibility does. We can explicitly hide stuff all we want, but the interface, the contract says how it'll be used. No developer in their right mind is going to say "how can I abuse this object as much as possible by playing with it's innards even though I shouldn't". We really don't care to know how things work under the hood. We like to think about it as it just works. If the desire to tinker was just too strong, we'd write our own code to do the same thing. Reinventing the wheel is so last decade. When change happens, when inane requirements arrive, the provided level of encapsulation no longer provides the basic necessities of the system. Developers need to start playing out of bounds - we need to rethink what is relevant and what isn't.

At this point, we need to step back and say "hey, looks like a lot of hacking is going on with the Logger class, I think we'd better rethink visibility there". But this never happens. Developers aren't going to say to one another how much a decision to make something private has made their lives miserable. No, it just goes unspoken - privacy is irrevocable. The same predicament holds true for publicly visible attributes - are they forever available to anyone interested or at one point or another does it make sense to hide them? I've always worked under the assumption that visibility is a "set in stone" type of ideology. The reason is simple - if you have something public and you suddenly restrict access, you're asking for trouble. Obviously this is a lot of work to go and fix because we'll no doubt find many subtle issues even after we find an alternative way of doing things since we no longer have access to the weight of the product. You take an integer field that your using somewhere in your application, suppose, innocently enough, your just reading it because you need to perform some calculation. Imagine that. Now this simple act of hiding the integer value, because it is causing problems somewhere else in your code, is now creating a new problem. Now for the other side of the coin - pulling the curtain and displaying something that we didn't even know existed. Great, now I don't have any problems doing what I need to do. I'm free to read any attribute values, I can use them to compute whatever I want and I don't have to worry about picking and choosing or about implementing workarounds. But what about the other problem, the whole thing about developers having access and abusing it? Wouldn't this just break things entirely since I can't trust anyone to do things right and only the most minimalist interface feasible is ever given out to developers? Not exactly. This is actually much safer to do because having something visible, waiting to be read, updated, or deleted entirely for that matter, will not break anything. This is contrasted with taking access away - big problems here. And can we actually plan for this kind of change? We're not exactly going to have error handling for invisible object properties. This chore is for humans to manage.

Another way to think about visibility with regard to object design is file system permissions. These are a lot more fine-grained than those of attribute visibility. With file system permissions, we have the ability to say that someone can read a file, but can't update it. Someone can execute a file while others can't. The number of combinations that can be used on just a handful of files is staggeringly complex. No wonder we don't have something like this in code. Its just trouble waiting to reek havoc. How would that work if we were to think about doing something more fine-grained, like file system permissions? Who would permissions be assigned to? Other software objects? Developers? Would permissions be granted on classes, or individual attributes? Suppose we could manage complexity at this level - a little intimidating isn't it? The problem here is that we're taking some of the creativity out of software design. And this is part of the problem with even simple restrictions like private vs public - we need at least some level of freedom to break things by playing with the internals of the map class. Mistakes will be made, no doubt, but this is part of the process. Object design isn't some black magic that will eliminate the burden of trial and error.
Complexity aside, let's revisit the idea of interfaces. They're more powerful for designing an encapsulated structure than visibility is, or so I'm claiming here anyway. If the contract designates what an object is supposed to do, and not how, we should be content with this as our restriction on how we go about deciding who can access what. Can interfaces guide our decisions regarding access policies? I would certainly think so. Remember, interfaces appropriate the visible attributes, not the hidden ones. How can I be sure that hiding the size attribute of my file class is a good idea until I see how the instances interact with others in the system?

If we don't worry about explicitly hiding information, we save time and effort. We're not concerning ourselves with what makes sense to expose, and what doesn't. In Python, we don't specify the visibility of an attribute or operation. It feels like a weight has been lifted when we adopt this attitude. It feels like I've put up a sign on my class that says "use at your own risk". Even in languages such as Python, there are feeble attempts made to make data private. One such method is prefixing the attribute name with an underscore. This doesn't actually reflect the verity of encapsulation. All we're doing here is sending a visual cue to human readers from the source code. This isn't necessarily wrong, it looks bad, but isn't wrong. I think it sends the wrong message however, because, using an arbitrary marker to signify an out of bounds entity, only signifies privacy, not why. It is probably better to use a descriptive name, one that makes readers think - I bet that attribute is private.

So what is the benefit to explicit data encapsulation in object-oriented software? Information hiding is the key idea that allows us as developers to take a concept and transform it into something more abstract. It is the inner details we often don't care about when we encounter something useful. In, the real world, the products we use on a daily basis have replaceable components. They also have internal parts that we're blissfully ignorant of. Had these inner pieces of an object's core been exposed, we'd risk damaging it. This is why we want to hide these details. This is the secret sauce that makes the thing work. It is the nature of the object. So applied to software, this idea works well - we don't want to expose the innards of our software components to other developers. I'm sure that enforcing these privacy characteristics isn't necessary. It is better to use a contract, this means defining an interface for you're object, either explicitly, or implicitly. Remember, interfaces do not describe the inner-workings of software objects. Interfaces are contracts and are only capable of describing the externally-visible behavior and or data of software objects. Using interfaces as the blueprint for visible properties, instead of explicitly hiding information is more descriptive for developers and thus more valuable.

Monday, March 30, 2009

Gaphor editor adapters

The Gaphor UML modeling tool, which is written in Python, uses a pop-up style editor widget which allows in-line editing of certain diagram elements. The widget itself isn't overly-interesting. It makes trivial changes to modeling elements quicker which is always helpful in any software solution. What we are interested in here is the method used to display the widget based on the element type. Gaphor relies heavily on the Zope interface and component frameworks. The Zope interface framework is utilized by Gaphor to define various interfaces that are provided by classes throughout the application. The component framework is utilized for the purpose of registering components and adapters. What exactly are adapters? Adapters are a type of component, automatically created by Zope when using the interface and component framework in conjunction with one another. This doesn't happen by itself; there are some carefully placed rules involved with defining adapters. When used right, Zope adapters are a very powerful tool that provide maximum usage of an interface. Gaphor defines an extensive set of Zope adapters. Here we are interested in the editor adaptor.

There are actually several adapters created for the IEditor interface, one for each diagram element that supports the editor widget. The Gaphor adapter approach is an alternative design to providing behavior that varies by type. A more traditional approach may have been to create a class hierarchy for the editor widget. Each class in the hierarchy would correspond to a different diagram element type. The differing behavior would then be implemented in each class in the hierarchy while similar behavior remains untouched and varying behavior gets replaced in a polymorphic manor. This is similar to how the editor adapters in Gaphor are defined and registered. One key difference in the design is how each class, or adapter, is instantiated when the need arises. With the class hierarchy approach, we would need extra logic to ensure that the correct instance type is created to use in conjunction with the diagram element widget. With Zope adapters, we simply instantiate the IEditor interface providing the object we are adapting to as a parameter. In the Gaphor case, the IEditor interface is instantiated with the diagram element widget as a parameter. The correct adapter instance is then returned by the Zope component framework, complete with the alternate functionality specific to that diagram element type. A similar effect can be achieved with the class hierarchy design. The class that is instantiated would accept the widget that is being adapted.

The adapter approach is a solid one because it emphasizes the importance of the interface contract provided by classes and the modularity offered by creating components. Being able to directly instantiate an interface speaks loudly in terms of what can be used in that context.

Thursday, March 19, 2009

The need for a REST interface in object-oriented applications

REST is a set of design criteria used for designing web-centric architectures. Much of the HTTP protocol incorporates ideas found in REST such as being connectible, resources, and a uniform interface. This uniform interface consists of methods that can operate on resources such as GET, POST, PUT, and DELETE. These are the most common method employed by RESTful applications. The idea of resources states that each resource within a system is uniquely addressable. In fact, this is also part of the uniform interface found in RESTful designs. Many web clients, other than the web browser, use SOAP as the message transformation framework. However, SOAP is not as flexible as a RESTful design and yet there exist many clients and client libraries, in several languages for SOAP services. There are also RESTful clients and client libraries, although, no nearly as many. By the very nature of a RESTful design, objects in an object-oriented system map well to resources of a RESTful architecture. Perhaps developers should keep this in mind and have classes provide a RESTful interface.

What would a RESTful object-oriented interface look like? That is, what would the methods and attributes be? The first step to implementing a REST interface would be define methods that map to the HTTP methods. For example, consider the following example.
#Example; A RESTful Python interface.

class REST(object):
def GET(self):
raise NotImplementedError("GET()")

def POST(self):
raise NotImplementedError("POST()")

def PUT(self):
raise NotImplementedError("PUT()")

def DELETE(self):
raise NotImplementedError("DELETE()")

Here, we have a Python class called REST. This class defines the GET(), POST(), PUT(), and DELETE() HTTP methods. Each method, when invoked will raise a NotImplementedError exception because this class is meant to be an interface. For a class to provide this interface, it would inherit from this class and redefine all methods, providing an implementation. What about attributes? If a instance of REST were to act as a proxy to some RESTful resource, it would need to know its URI. So uri would be a good candidate for an interface attribute. There are many other meta-data attributes associated with the HTTP protocol they we aren't concerned with here. What we want to highlight is the REST interface developers could potentially use when designing objects. On the topic of attributes, another question springs to mind. What about resource attributes. If all we know about a particular resource is the methods it supports and its uri, how can we represent the resource in the context of an object-oriented system? This would most likely be another interface that we would use in conjunction with the REST interface, used to interpret the representation of the remote resource. An alternative is to use WADL to define what resources should look like. However, WADL is too much like SOAP. The rigidity involved defeats the purpose of a RESTful architecture.

The REST interface discussed so far is really only useful as a proxy to a remote resource. That is, the object we are designing that provides this interface would use this interface to make an HTTP request to the HTTP server providing the resource. An analog would be the web browser application providing the REST interface and invoking the GET() method to retrieve a web page.

The "REST" interface could also be the resource itself. If the developer is designing an object-oriented HTTP web application, they could design object within that system, exposed to the web, that provide the REST interface. The method information is always encoded in the HTTP request, otherwise it wouldn't be HTTP. If the base HTTP server forwards this request to an object that provides this interface, that object will always know what to do with the request. This same object can also act as a proxy and so on, forming a chain of RESTful resources.

However, as with all distributed computing, this chain of resources poses a design challenge. How does the system manage new resource locations? If the system is to scale at all, it will need to. However, this problem will come down the road. Right now, the problem is the RESTful implementation at the design level in object-oriented systems. With a RESTful interface, these problems would be much easier to solve.

Wednesday, February 25, 2009

Interfaces and errors

The basic idea behind defining interfaces and classes that provide those interfaces is to create a contract. This contract specifies that any instances of this class will carry out the behaviour specified within the contract faithfully. It is said that if some instance that provides a given interface, any context in which that instance is used that requires behaviour specified in the contract, the instance is behaving as expected. The instance is error free.

On the other hand, if some behavior is invoked, on some instance, in some required interface context, and the instance does not conform to the contract, the instance does is not behaving correctly.

For example, here is an example of a functional provided interface.

Here we have a simple interface called IDoable. This interface specifies that any classes that provide this interface must implement a do_something() method. The Doer class that provides this interface is valid and functional because it implements the do_something() method.

What about an invalid provided interface? Consider the following non-functional example.


This time, the Doer class does not faithfully carry out the contract specified by the IDoable interface. So if an instance of Doer is used in the context of a required IDoable interface, this will not work as expected.

Depending on the implementation language, the instance may not even have an opportunity to behave in certain contexts because of the lack of one or more required interfaces. Other languages, don't care what type of instances are used in a given context let alone what interfaces they provide. So in either case, the failure of an instance to provide an interface can be taken care of. There will be a compilation error or a runtime error.

This still leaves us with some unanswered questions. In the event of a runtime error, due to the lack of a required interface, is this the result of a design error or should the instance simply not be there. In the case of the design error, chances are that the instance is valid in the context, there is simply a mistake in the implementation of the class. This could in fact be as simple as a missing operation or an invalid operation signature. What about when the instance has no business being in the context which is attempting to invoke behaviour on it? This is obviously not a design flaw in terms of the required interface and the instance that does not provide it. How do you deal with such situations? In interpreted languages, this can be a little trickier. Then, the question is why was this instance placed in the specified context in the first place if it doesn't belong there? We know that all classes that provide the interface in question are implemented perfectly.

There really is no answer. You really have to look at the architectural layers of your application at this point. If instances that cause these types of mishaps belong to the problem domain, you could be in good shape. If hierarchies of problem classes are constructed in such a way as to provide a means to handle these interface errors in the problem domain as well.

Other problem developers can stumble over is the over-reliance on interface conformance. When instances provide the necessary interface in a given context, this doesn't mean that the invoked behavior will execute error-free. Should these errors be handled outside of the problem domain. Again, this is really dependent on your architectural layers and how they are implemented. If rigorous testing results in flawless class implementations in all the problem domain and the application domain, we could then tie the interface errors to the problem domain. Anything else can be considered at the application level and be dealt with accordingly.

Building all these interfaces around the problem domain is a lot of work. Sometimes it is simpler to just define some common exceptions and deal with them, be it application or domain layer.

Monday, December 22, 2008

Gaphor services

The Gaphor UML modeling tool offers a simple service framework under the covers. The Gaphor application itself defines some core services that fit within this framework. For example, it defines an ActionManager service that is used to handle various actions within the application.

All services that are defined within Gaphor (or as extensions to Gaphor), implement the IService interface. This interface is defined in the interfaces module. Here is a simple illustration of what this interface looks like.



As you can see, this straight-forward interfaces requires that any Gaphor services implement an init and a shutdown method.

The ActionManager service is a good example of a Gaphor service. This service is responsible for maintaining actions in the application. It is also a service that is responsible for loading other services. For example, the FileManager service is also an action provider since it implements the IActionProvider interface. The ActionManager service loads all components that provide the IActionProvider interface and registers them as action providers within the application.

Tuesday, December 2, 2008

An interface/generalization design pattern

Last month, I wrote about an interface/generalization design pattern. I thought I'd post a diagram which I feel better illustrates the pattern.



Again, to some the pattern up:
  • The base interface specifies the contract that all classes who realize this interface must implement.
  • The base class which realizes the base interface. This instances of this class will ensure that the expected default behavior of some collaboration can always be carried out in the case that a more specialized sub-class cannot be instantiated.
  • You may create a sub-class of the base class which realizes the base interface. This class has the ability to redefine certain methods of the base class while using the default implementation of others.
  • You may create a regular class that realizes the base interface. It can be thought of as a child of the base class because it will behave the same as any other children of the base class. The main difference being that this class must implement the entire interface. There are no defaults here.

Thursday, November 27, 2008

An interface/generalization design pattern

Interfaces are useful for specifying a contract that one or many classes may realize. Generalization is useful for a similar purpose. If class A is inherited by class B, all the structural and behavioral features of class A because features of class B. In effect, class B realizes the interface of class A.

A good software development practice would then be to create a base class for each interface in your application that realizes each interface respectively. This way, any subsequent classes that are implemented can realize interfaces in your application in one of two ways. The first, directly realize the interface using the programming language constructs. The second, generalize the base class that corresponds to the interface you wish to realize.

By creating a base class for each interface that is ready to use by subclasses, you can implement some of the simpler methods in the base class. Subclasses may then only need to implement one or a few methods while still indirectly realizing the interface. One can argue that the interface level can be cut out completely. You could. The interface simply serves as an abstract conceptual tool for developers. You could only use generalization and override methods as needed. Both ways are valuable object oriented design but I think you'll find combining generalization and interfaces much more flexible and fun.

Monday, November 24, 2008

Interfaces in Gaphor

I wrote earlier about Python interfaces and the Gaphor UML modeling tool demonstrates the use of Python interfaces quite nicely. Here, we show the interfaces that several classes in Gaphor implement. What is notable here is the simplistic design. There is not an entire plethora of interfaces to choose from. Only those that are important for accomplishing the applications' goals.

Monday, June 30, 2008

Interfaces in Python.

Defining interfaces that your classes will provide is an essential programming practice if you plan to develop extensible code. That is, when you define interfaces, you are defining your internal architecture. The interfaces you define will give you a starting point in which you can discover more meaningful abstractions in your application domain.

Interfaces are not a replacement for object-oriented analysis. You can't just put together a set of interfaces that you think might work and hope for the best. Rather, your interfaces should be derived from concepts created by doing analysis and development. That being said, you will discover how your interfaces need to be refined and expanded upon as you are implementing classes that realize your interfaces. Don't get stuck in the waterfall approach to software development.

Zope provides an interface package which allows Python developers to define interfaces and implement classes that realize them. For example, say I want to define a blog entry interface. Using the zope.interface package, I might do something similar to:

import zope.interface

class IBlogEntry(zope.interface.Interface):
"""A simple blog account interface."""
title = zope.interface.Attribute("""The title of the blog entry.""")
content = zope.interface.Attribute("""The main content of the blog entry.""")
date = zope.interface.Attribute("""The publish date of the blog entry.""")

def setTitle(self, title):
"""Set the title of the blog entry."""

def setContent(self, content):
"""Set the content of the blog entry."""

def setDate(self, date):
"""Set the date of the blog entry."""

def getTitle(self):
"""Return the title of the blog entry."""

def getContent(self):
"""Return the content of the blog entry."""

def getDate(self):
"""Return the date of the blog entry."""

def publish(self):
"""Publish the blog entry."""

class BlogEntry:
zope.interface.implements(IBlogEntry)
And of course we would then have to implement all the attributes and methods defined in IBlogEntry. We can then test if IBlogEntry is implemented by any given BlogEntry instance as follows:

blog_entry_obj=BlogEntry()
IBlogEntry.providedBy(blog_entry_object)

Of course, this interface gives us a good idea of what an blog entry implementation might look like. We can easily implement a different blog entry class because the interface provides us with an interchangeable template. As long as these methods an attributes are implemented, our class may be used where the IBlogEntry interface is required.

Is there a way we could re-factor our interface to get more use out of it? I think so. In a system which incorporates blog entry abstractions, it is most probable that there will be similar abstractions. Similar in the sense that these other abstractions will have a title, content, and date. Lets take a look at an alternative interface implementation of interfaces provided by BlogEntry.


import zope.interface

class ITitle(zope.interface.Interface):
"""A simple title interface for abstractions with a title."""
title = zope.interface.Attribute("""The title of the abstraction.""")

def setTitle(self, title):
"""Set the title of the abstraction."""

def getTitle(self):
"""Return the title of the abstraction."""

class IContent(zope.interface.Interface):
"""A simple content interface for abstractions with content."""
content = zope.interface.Attribute("""The content of the abstraction.""")

def setContent(self, content):
"""Set the content of the blog entry."""

def getContent(self):
"""Return the content of the blog entry."""

class IDate(zope.interface.Interface):
"""A simple date interface for abstractions with dates."""
date = zope.interface.Attribute("""The date of the abstraction.""")

def setDate(self, date):
"""Set the date of the blog entry."""

def getDate(self):
"""Return the date of the blog entry."""

class IPublish(zope.interface.Interface):
"""A simple publishing interface for publishing abstractions."""

def publish(self):
"""Publish the abstractions."""

class BlogEntry:
zope.interface.implements(ITitle)
zope.interface.implements(IContent)
zope.interface.implements(IDate)
zope.interface.implements(IPublish)

In this implementation, we have removed all references to blog entry in the interfaces we have defined. This is a good practice when there are several non-trivial abstractions involved in the system being implemented. We can then reuse our interfaces for several class implementations rather than keeping them specific to blog entry.

Finally, keep your interfaces simple. The goal in using interfaces is to keep the implementation of abstractions consistent. This is not accomplished be further complicating the code by adding interfaces that are more complex than necessary.