Unsure how approach design of application - java

I am trying to create an application in Java which allows for generation of large Provenance graphs from small seed graphs but I am having a little trouble figuring out the best way to design my classes.
To begin with, Provenance essentially has a graph structure, nodes and edges. I have created a Java library which acts as a mapping of the Provenance Data Model to Java Objects. This allows me to abstract my application specific information from Provenance model.
My class structure looks a little like this:
Graph (containing Sets of Node and Edge)
abstract Node (Just a String name for now)
Agent
Activity
Entity
Other subclasses of Node
abstract Edge
Generation
Association
Other subclasses of Edge
Now, what I would like to do is provide weighting on the nodes and edges which act as multipliers/saturation levels. There are a couple of ways I could use the library to achieve this aim but I'm not clear on what is the best from a development and maintainability perspective.
Firstly, I defined a Weighable interface with some simple methods such as get and set minimum and maximum weights.
Now, I could either extend each subclass Node e.g.
class WeighableAgent extends Agent implements Weighable
But then this requires an extended class for every type of node available, and required me to implement the Weighable interface at every level.
Alternatively, I could provide a mixin but it would still rely on me implementing the same functionality across each subclass.
Alternatively I could have a class that composes upon Agent, but that still requires me to implement Weighable across every composition class.
Alternatively, I could compose solely on the Node class e.g.
class WeighableNode implements Weighable {
private Node node;
public WeighableNode(Node node) {
this.node = node;
}
etc etc...
And this would allow me to only implement Weighable in one place. However, then I lose some important information about the concrete class type from anything using WeighableNode and the only way around this that I see is to provide a method:
Node getNode();
Which I'm concerned about due to the Law Of Demeter. Furthermore, this WeighableNode will be composed upon by a PresentationNode, to help with Swing which would mean I would end up chaining calls such as:
presentationNode.getWeighableNode().getNode() instanceof Agent
Which seems very unpleasant.
One final solution which I just thought of is to compose upon Node as above and then extend WeighableNode with WeighableAgent, etc etc. This means I do not need to reimplement Weighable each time and if I know I have
instanceof WeighableAgent
then the wrapped node is an Agent.
I appreciate this is quite long but I hope that an experienced developer will very quickly see the correct design practice.

Too bad Java has neither real mixins nor multiple inheritance…
Generic wrapper
I guess I'd use WeighableNode<NodeType extends Node> as a generic wrapper type. That way, all places which require nodes of a specific type could clearly state that fact. Its getNode method could return the correct class. And you wouldn't end up with too many classes all over the place.
Conversion idiom
Even if you don't use the above approach, the following idiom might be interesting:
class Node {
public T asNode(Class<T extends Node> clazz) {
return clazz.cast(this);
}
}
class NodeWrapper<N extends Node> {
private N realNode;
public T asNode(Class<T extends Node> clazz) {
try {
return super.asNode(clazz);
}
catch (ClassCastException e) {
return realNode.asNode(clazz);
}
}
}
You could change the above to return null instead of throwing an exception if you prefer. The idea is that the calling code doesn't have to worry about how to convert your node to various types. You'd e.g. simply write
presentationNode.getNode(Agent.class)
This separates implementation from interface, giving you much freedom to change things later on if the need arises. The basic Node implementation would know how to convert itself, taking care of derived classes. The NodeWrapper would add conversion using composition. You could use that as the base class for WeighableNode and your presentationNode.
Fat interface
You could implement the weighing stuff in Node itself, and use WeighedNode just as a tagging interface, or not at all. Not the nicest solution, but will help keep your number of classes down, and shouldn't do any real harm except for the bit of memory consumed by the extra data. The levels of indirection required by the other schemes will probably outweight that memory requirement by far.

Related

Abstraction in OOPs

I have come across few definitions over the years, and have never able to clearly understand what abstraction is.
I have understood the 3 main concepts of Oops but have had difficulties with this particular concept which is engraved within these other concepts.
Till now i have come to 2 conclusions, but not sure.
It is the ability to hide the implementation details of a method(Behavior), and provide the user with just the interface.
It is ability to define a method signatures(ie. only to declare them) without actually implementing them.
Which is the correct definition of abstraction with context to Object oriented programming, and if not one of the above, then what is it?
Would appreciate if supporting code is also provided :)
It is the ability to hide the implementation details of a method(Behavior), and provide the user with just the interface.
Sort of, but that's "encapsulation". They're related in the sense that "encapsulation" is a key concept of object oriented design whereas "abstraction" is a potential result of that concept.
It is ability to define a method signatures(ie. only to declare them) without actually implementing them.
That's an implementation detail, not the conceptual notion of abstraction itself.
In a simple inheritance model, "abstraction" can be thought of as referring to an object by one of its ancestor (or more abstract) types. For example, consider a hierarchy:
Lifeform
Animal
Canine
Golden Retriever
If you're performing an operation specific only to a Golden Retriever, then you can't perform that operation on any Animal. It has to be a specific Animal. So you need that specific implementation.
However, if you're performing an operation that's generic to all Lifeforms then it doesn't matter what specific implementation you receive. That operation is abstracted so that it can accept any Lifeform object, regardless of the more specific implementation.
Interfaces provide another implementation mechanism which can achieve abstractions. Object composition is still another mechanism. For example, consider this non-inheritance scenario:
public class MyObject {
private ThirdPartyObject dependency;
public MyObject() {
// initialize the dependency
}
public boolean getValue() {
return this.dependency.getValue();
}
public void setValue(boolean value) {
this.dependency.setValue(value);
}
}
This doesn't use inheritance or interfaces for anything, but it does create an abstraction. Consuming code doesn't know anything about the ThirdPartyObject or the details of its implementation. Following the Law Of Demeter the details of that implementation have been abstracted behind a custom object which you control. This can be very useful for de-coupling your code from implementation details you don't control.
Abstraction is a process where you show only “relevant” data and “hide” unnecessary details of an object from the user.
For example, when you login to your Amazon account online, you enter
your user_id and password and press login, what happens when you press
login, how the input data sent to amazon server, how it gets verified
is all abstracted away from the you.
Another example of abstraction: A car in itself is a well-defined
object, which is composed of several other smaller objects like a
gearing system, steering mechanism, engine, which are again have their
own subsystems. But for humans car is a one single object, which can be managed by the help of its subsystems, even if their inner details
are unknown.
Also to be noted that abstraction hides the implementation details but implementation can be shown even i.e. member functions with definitions can also be present, unlike Interface which provides total Abstraction.
Source: BeginnersBook.com
My summary is "hiding the details"; in the case of programming, abstraction is more like your first definition.
For supporting code, you don't really need to look too far. Abstraction is all around. Consider the common data structure string.
A string within a computer is actually bytes converted to a specific character set strung together. (no pun intended)
Therefore, when you put "hello, world" to you, it's a phrase in quotes. When the computer run it, it creates a data structure string which itself contains the bytes and various state to represent the given string. You don't (usually) care how the string object is working. It does and you move on with your goal. That is as basic of an example of abstraction as I can get.
Abstraction is the process by which data and programs are defined with a representation similar in form to its meaning, while hiding away the implementation details.Abstraction involves the facility to define objects that represent abstract “actors” that can perform work, report on and change their state, and “communicate” with other objects in the system.
Abstraction can be seen in two ways:
Data Abstraction - Data abstraction is the way to create complex data types and exposing only meaningful operations to interact with data type, where as hiding all the implementation details from outside works.
Control Abstraction - Abstraction of behavior. Provides an easier, higher level API to hide client from unnecessary execution details.
Abstraction is a way to promise that a class implementing a given abstraction will have a given behaviour. Thus, abstract classes cannot be directly instantiated, they first need to implement the abstraction.
Abstract classes are thus meant to be implemented by a concrete class that declares and defines a method matching the abstract contract. An abstraction can however provide some concrete behaviours along with abstract ones.
Abstraction is done in Java through abstract classes and through interface. In C++, abstraction is achieved through the usage of virtual methods inside a class. Note that Java interfaces were only created as (unlike C++) multiple inheritance is not allowed in this language.
In simple terms
Abstraction: Showing what is necessary and hiding unnecessary details. Ex if your class has 10 functions but only 2 should be useful by the consumer of the class that you make those functions as public and other are private, so what is visible to the consumer is what is needed, instead of showing it all.
Encapsulation: Hiding the complexity to the consumer of the class. Ex. if your class needs two variables to store min and max, you encapsulate them under getter and setter and implement all the validations and checks in the getter and setter. this way you hide the complexities.
Well I will explain abstraction with a real world example. Say in your house you do have an electric plug and many devices can connect to the same plug but plug will never have an idea which device it is connected to, in other words the details of the devices is abstracted (hidden) to the plug.
Think what if we connect a device directly to electric wire without a plug? Say connect a bulb directly to a wire, then wire knows which device it is connected to and when ever we need to replace the bulb then we have to remove the wire connection from the bulb, which means bulb is tightly coupled with the wire. In other words bulb and wire knows the details where it is connected to, means not abstracted.
In object oriented world abstraction works exactly same. The class which consume other classes function/property doesn't need to know which classes function/property it is consuming and everything should be abstracted with an interface / abstract class.
Let me code the same example. Here I have a class "ElectricPlug", which is running a device. But the class "ElectricPlug" doesn't have any idea which device it is running. It can be any class implementing the interface "IDevice", which means the implementation of "RunDevice" is abstracted from "ElectricPlug". Here is the full sample code,
class Program
{
static void Main(string[] args)
{
ElectricPlug electricPlug = new ElectricPlug(new Bulb());
}
}
public class ElectricPlug
{
private readonly IDevice _device;
public ElectricPlug(IDevice device)
{
_device = device;
}
public void Run()
{
_device.Rundevice();
}
}
public interface IDevice
{
void Rundevice();
}
public class Bulb : IDevice
{
public void Rundevice()
{
Console.WriteLine("Switched on bulb");
}
}
public class ElectricPlug
{
private readonly IDevice _device;
public ElectricPlug(IDevice device)
{
_device = device;
}
public void Run()
{
_device.Rundevice();
}
}
There are two parts of object in oops
state ( properties )
behavior ( methods )
so to hiding the implementation of behavior of any object is known as abstraction
let's take a example -->
there is a cook at my home which makes delicious food . some body comes at my home and take dinner . after dinner they asked me that who made this food . i answered
i have a cook whose name is tttt , his address is tttt and his number is 0000 ( these all are the properties of cook object )
they again asked how he made this then i answered
i don't know how he made . i only know that he can make food
so abstraction means we are telling that what task our object can do instead of how my object can do a task .

Navigating around instantiating an abstract class, is there a flaw of in my OOP design?

After reading a number of questions regarding abstract classes and interfaces, I am still unsure about how I should go about designing my code, so at the risk of having missed a possible duplicate, here's my situation.
I am working on a number of utility classes that are meant to handle a nasty hierarchy of a particular type of object. While the precise details of the object is irrelevant, it should suffice to say that it's not a general solution whatsoever. So I started by writing a CustomNode and a CustomHierarchy class.
A bit later on I realized that it's much smarter to produce a more general solution, which can be reused in different context and easily tested without having to create lots of mock instances of the aforementioned complicated class. I could easily provide all the common code in interfaces and abstract classes, and just provide the specific bits where they are needed! (this I believe is the whole point with OOP?)
So far I have:
an interface Relatable which simply holds an enum of possible relations that nodes might have to one another, and a method signature of getRelation(Relatable other)
an abstract class Node<E> which implements the Relatable and contains all utility methods (e.g. addChild() or getNextSibling(). The only method this class is missing is the getRelation(Relatable other).
a concrete class Hierarchy<E> which will define how to build up the hierarchy of the nodes, starting from a Collection<E> which holds the data.
The idea is to extend the Node<E> and Hierarchy<E> classes with appropriate subclasses based on the problem at hand. The first two are done without any major hustle but I am having problems with the Hierarchy<E> class since it has a private method addNodeToHierarchy(E data) which tries to instantiate a Node<E> and place it in the hierarchy. This obviously fails as the node class is abstract and can't be instantiated.
I understand why this is not working, but I am not sure how I should go about circumventing this problem. Is there a flaw in my design? Should I add a static createNewNode(E data) method in the Node<E> and use that instead? Another option I can think of is to detach the Node from getting the relation and go with a Relator interface instead. This can't be a unique problem by any chance, so what's "good practice" in this situation?
Thanks in advance,
Decide who should know how a Node<E> must be constructed from from an instance of E. It could be the instance of E, it could be the Node class, it could be the Hierarchy, or it could be the caller of addNodeToHierarchy().
If it's the caller of addNodeToHierarchy(), then either you make it take an instance of Node<E> instead of an instance of E, or you make it take an instance of some NodeFactory<E>, to which the method will delegate to transform the data into a node. This factory could also be passed as an argument to the hierarchy constructor if all the nodes are constructed by the same factory.

Is it good practice for a class to implement itself in a generic interface?

Apologies for the question title, I couldn't put this into words easily.
I've just come across this in some code:
public class MyClass implements Message<MyClass> {...}
I understand what it does but I've never seen a class declared in this way before.
The disadvantage I see is that now MyClass is a Message and needs to include implemented methods that are unrelated to its primary purpose.
One advantage I see (other than it reduces the number of other classes I would otherwise need to write) is that for things like Comparable, MyClass would know how to compare itself to other instance, which in turn would make for more concise code.
Is this good practice? Are there any rules-of-thumb?
This is more or less the only way in Java to have an interface with methods that refer to the implementing class itself. So, for example, you might write a binary tree node interface:
interface TreeNode<N extends TreeNode<N>> {
N getLeftChild();
N getRightChild();
void setLeftChild(N node);
void setRightChild(N node);
}
and then you have classes like
class TreeNodeWithInt extends TreeNode<TreeNodeWithInt> {
int value;
TreeNodeWithInt leftChild;
TreeNodeWithInt rightChild;
public TreeNodeWithInt getLeftChild() { return leftChild; }
public void setLeftChild(TreeNodeWithInt newLeft) { leftChild = newLeft; }
...
}
If we didn't have the N type parameter, you would be forced to write unsafe code like
class TreeNodeWithInt extends TreeNode {
int value;
TreeNodeWithInt leftChild;
TreeNodeWithInt rightChild;
public void setLeftChild(TreeNode node) {
// note the dangerous cast!
leftChild = (TreeNodeWithInt) node;
}
}
The key issue here is that interfaces aren't allowed to refer to the type of the class that's implementing the interface, when they describe the input and return types of methods. So instead, you include a "self" generic type parameter. It's a relatively common idiom in code that makes extensive use of generics.
As you've correctly identified, it's frequently used with Comparable specifically, because you should only be able to compare objects to other objects of the same type. Indeed, Collections.sort is specified to take a List<T> where T extends Comparable<? super T>, which means that T is comparable to at least other values of type T, but possibly others as well.
(Finally, as you might expect -- since it's the only way to achieve this behavior, it's not "good" or "bad" practice. That said, the goal of the technique is to avoid writing methods that compile without warnings but can end up throwing ClassCastException, which is itself a good practice.)
It is neither "good practice" or "bad practice".
The real question is whether it accurately models what you are trying to achieve. In some cases it will, in others it won't.
And if a particular use of the "meta-pattern" results in unwanted and / or meaningless methods, then you have a strong case that it is not the right solution.
Are there any rules-of-thumb?
If it doesn't work in a particular use-case, don't use it in that use-case :-)
While my example is phrased in C#, it translates to Java, and makes sense as a useful idiom for doing common tasks for the class, especially for domain classes. That said, it's neither good nor bad practice.
class Product : IEquatable<Product>, ICloneable<Product>, IComparable<Product>
or in Java
class Product implements IEquatable<Product>, ICloneable<Product>, IComparable<Product>
In this example, I can define a product that knows how to check itself for equality with another, clone itself (perhaps in a generic reusable way), compare itself and so on.
I often use something like the above with code generation, putting as much of the generic at the root level as possible, and extending the more specific things at leaf levels.
Good question, and as Stephen C mentioned, this is neither a good or bad practice. In fact, I your description is not really accurate. This is not a case of a class implementing itself, but a class saying that it is the parameter for the parameterized interface it wants to implement.
public class MyClass implements Message<MyClass> {...}
This effectively means that Message is a "parameterized" interface, meaning, the interface itself accepts a parameter. In this case, the parameter just happens to be the same class that is implementing the parameterized class. But it could be something else. Imagine this:
public class UserDAO implements DAO<User> {...}

Any good examples of inheriting from a concrete class? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Background:
As a Java programmer, I extensively inherit (rather: implement) from interfaces, and sometimes I design abstract base classes. However, I have never really felt the need to subclass a concrete (non-abstract) class (in the cases where I did it, it later turned out that another solution, such as delegation would have been better).
So now I'm beginning to feel that there is almost no situation where inheriting from a concrete class is appropriate. For one thing, the Liskov substitution principle (LSP) seems almost impossible to satisfy for non-trivial classes; also many other questions here seem to echo a similar opinion.
So my question:
In which situation (if any) does it actually make sense to inherit from a concrete class?
Can you give a concrete, real-world example of a class that inherits from another concrete class, where you feel this is the best design given the constraints? I'b be particularly interested in examples that satisfy the LSP (or examples where satisfying LSP seems unimportant).
I mainly have a Java background, but I'm interested in examples from any language.
You often have a skeletal implementations for an interface I. If you can offer extensibility without abstract methods (e.g. via hooks), it is preferable to have a non-abstract skeletal class because you can instantiate it.
An example would be a forwarding wrapper classes, to be able to forward to another object of a concrete class C implementing I, e.g. enabling decoration or simple code-reuse of C without having to inherit from C. You can find such an example in Effective Java item 16, favor composition over inheritance. (I do not want to post it here because of copyrights, but it is really simply forwarding all method calls of I to the wrapped implementation).
I think the following is a good example when it can be appropriate:
public class LinkedHashMap<K,V>
extends HashMap<K,V>
Another good example is inheritance of exceptions:
public class IllegalFormatPrecisionException extends IllegalFormatException
public class IllegalFormatException extends IllegalArgumentException
public class IllegalArgumentException extends RuntimeException
public class RuntimeException extends Exception
public class Exception extends Throwable
One very common case I can think of is to derive from basic UI controls, such as forms, textboxes, comboboxes, etc. They are complete, concrete, and well able to stand on their own; however, most of them are also very basic, and sometimes their default behavior isn't what you want. Virtually nobody, for instance, would use an instance of an unadulterated Form, unless possibly they were creating an entirely dynamic UI layer.
For example, in a piece of software I wrote that recently reached relative maturity (meaning I ran out of time to focus primarily on developing it :) ), I found I needed to add "lazy loading" capability to ComboBoxes, so it wouldn't take 50 years (in computer years) for the first window to load. I also needed the ability to automatically filter the available options in one ComboBox based on what was shown in another, and lastly I needed a way to "mirror" one ComboBox's value in another editable control, and make a change in one control happen to the other as well. So, I extended the basic ComboBox to give it these extra features, and created two new types: LazyComboBox, and then further, MirroringComboBox. Both are based on the totally serviceable, concrete ComboBox control, just overriding some behaviors and adding a couple others. They're not very loosely-coupled and therefore not too SOLID, but the added functionality is generic enough that if I had to, I could rewrite either of these classes from scratch to do the same job, possibly better.
Generally speaking, the only time I derive from concrete classes is when they're in the framework. Deriving from Applet or JApplet being the trivial example.
This is an example of a current implementation that I'm undertaking.
In OAuth 2 environment, since the documentation is still in draft stage, the specification keeps changing (as of time of writing, we're in version 21).
Thus, I had to extend my concrete AccessToken class to accommodate the different access tokens.
In earlier draft, there was no token_type field set, so the actual access token is as follows:
public class AccessToken extends OAuthToken {
/**
*
*/
private static final long serialVersionUID = -4419729971477912556L;
private String accessToken;
private String refreshToken;
private Map<String, String> additionalParameters;
//Getters and setters are here
}
Now, with Access tokens that returns token_type, I have
public class TokenTypedAccessToken extends AccessToken {
private String tokenType;
//Getter and setter are here...
}
So, I can return both and the end user is none the wiser. :-)
In Summary: If you want a customized class that has the same functionality of your concrete class without changing the structure of the concrete class, I suggest extending the concrete class.
I mainly have a Java background, but I'm interested in examples from any language.
Like many frameworks, ASP.NET makes heavy use of inheritance to share behaviour between classes. For example, HtmlInputPassword has this inheritance hierarchy:
System.Object
System.Web.UI.Control
System.Web.UI.HtmlControls.HtmlControl // abstract
System.Web.UI.HtmlControls.HtmlInputControl // abstract
System.Web.UI.HtmlControls.HtmlInputText
System.Web.UI.HtmlControls.HtmlInputPassword
in which can be seen examples of concrete classes being derived from.
If you're building a framework - and you're sure you want to do that - you may well finding yourself wanting a nice big inheritance hierarchy.
Other use case would be the to override the default behavior:
Lets say there is a class which uses standard Jaxb parser for parsing
public class Util{
public void mainOperaiton(){..}
protected MyDataStructure parse(){
//standard Jaxb code
}
}
Now say I want to use some different binding (Say XMLBean) for the parsing operation,
public class MyUtil extends Util{
protected MyDataStructure parse(){
//XmlBean code code
}
}
Now I can use the new binding with code reuse of super class.
The decorator pattern, a handy way of adding additional behaviour to a class without making it too general, makes heavy use of inheritance of concrete classes. It was mentioned here already, but under somewhat a scientific name of "forwarding wrapper class".
Lot of answers but I though I'd add my own $0.02.
I override concreate classes infrequently but under some specific circumstances. At least 1 has already been mentioned when framework classes are designed to be extended. 2 additional ones come to mind with some examples:
1) If I want to tweak the behavior of a concrete class. Sometimes I want to change how the concrete class works or I want to know when a certain method is called so I can trigger something. Often concrete classes will define a hook method whose sole usage is for subclasses to override the method.
Example: We overrode MBeanExporter because we need to be able to unregister a JMX bean:
public class MBeanRegistrationSupport {
// the concrete class has a hook defined
protected void onRegister(ObjectName objectName) {
}
Our class:
public class UnregisterableMBeanExporter extends MBeanExporter {
#Override
protected void onUnregister(ObjectName name) {
// always a good idea
super.onRegister(name);
objectMap.remove(name);
}
Here's another good example. LinkedHashMap is designed to have its removeEldestEntry method overridden.
private static class LimitedLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
#Override
protected boolean removeEldestEntry(Entry<K, V> eldest) {
return size() > 1000;
}
2) If a class shares a significant amount of overlap with the concrete class except for some tweaks to functionality.
Example: My ORMLite project handles persisting Long object fields and long primitive fields. Both have almost the identical definition. LongObjectType provides all of the methods that describe how the database deals with long fields.
public class LongObjectType {
// a whole bunch of methods
while LongType overrides LongObjectType and only tweaks a single method to say that handles primitives.
public class LongType extends LongObjectType {
...
#Override
public boolean isPrimitive() {
return true;
}
}
Hope this helps.
Inheriting concrete class is only option if you want to extend side-library functionality.
For example of real life usage you can look at hierarchy of DataInputStream, that implements DataInput interface for FilterInputStream.
I'm beginning to feel that there is almost no situation where inheriting from a concrete class is appropriate.
This is one 'almost'. Try writing an applet without extending Applet or JApplet.
Here is an e.g. from the applet info. page.
/* <!-- Defines the applet element used by the appletviewer. -->
<applet code='HelloWorld' width='200' height='100'></applet> */
import javax.swing.*;
/** An 'Hello World' Swing based applet.
To compile and launch:
prompt> javac HelloWorld.java
prompt> appletviewer HelloWorld.java */
public class HelloWorld extends JApplet {
public void init() {
// Swing operations need to be performed on the EDT.
// The Runnable/invokeLater() ensures that happens.
Runnable r = new Runnable() {
public void run() {
// the crux of this simple applet
getContentPane().add( new JLabel("Hello World!") );
}
};
SwingUtilities.invokeLater(r);
}
}
Another good example would be data storage types. To give a precise example: a red-black tree is a more specific binary tree, but retrieving data and other information like size can be handled identical. Of course, a good library should have that already implemented but sometimes you have to add specific data types for your problem.
I am currently developing an application which calculates matrices for the users. The user can provide settings to influence the calculation. There are several types of matrices that can be calculated, but there is a clear similarity, especially in the configurability: matrix A can use all the settings of matrix B but has additional parameters which can be used. In that case, I inherited from the ConfigObjectB for my ConfigObjectA and it works pretty good.
In general, it is better to inherit from an abstract class than from a concrete class. A concrete class must provide a definition for its data representation, and some subclasses will need a different representation. Since an abstract class does not have to provide a data representation, future subclasses can use any representation without fear of conflicting with the one that they inherited.
Even i never found a situation where i felt concrete inheritence is neccessary. But there could be some situations for concrete inheritence specially when you are providing backward compatibility to your software. In that case u might have specialized a class A but you want it to be concrete as your older application might be using it.
Your concerns are also echoed in the classic principle "favor composition over inheritance", for the reasons you stated. I can't remember the last time I inherited from a concrete class. Any common code that needs to be reused by child classes almost always needs to declare abstract interfaces for those classes. In this order I try to prefer the following strategies:
Composition (no inheritance)
Interface
Abstract Class
Inheriting from a concrete class really isn't ever a good idea.
[EDIT] I'll qualify this statement by saying I don't see a good use case for it when you have control over the architecture. Of course when using an API that expects it, whaddaya gonna do? But I don't understand the design choices made by those APIs. The calling class should always be able to declare and use an abstraction according to the Dependency Inversion Principle. If a child class has additional interfaces to be consumed you'd either have to violate DIP or do some ugly casting to get at those interfaces.
from the gdata project:
com.google.gdata.client.Service is designed to act as a base class that can be customized for specific types of GData services.
Service javadoc:
The Service class represents a client connection to a GData service. It encapsulates all protocol-level interactions with the GData server and acts as a helper class for higher level entities (feeds, entries, etc) that invoke operations on the server and process their results.
This class provides the base level common functionality required to access any GData service. It is also designed to act as a base class that can be customized for specific types of GData services. Examples of supported customizations include:
Authentication - implementing a custom authentication mechanism for services that require authentication and use something other than HTTP basic or digest authentication.
Extensions - define expected extensions for feed, entry, and other types associated with a the service.
Formats - define additional custom resource representations that might be consumed or produced by the service and client side parsers and generators to handle them.
I find the java collection classes as a very good example.
So you have an AbstractCollection with childs like AbstractList, AbstractSet, AbstractQueue...
I think this hierarchy has been well designed.. and just to ensure there's no explosion there's the Collections class with all its inner static classes.
You do that for instance in GUI libraries. It makes not much sense to inherit from a mere Component and delegate to a Panel. It is likely much easyer to inherit from the Panel directly.
Just a general thought. Abstract classes are missing something. It makes sense if this, what is missing, is different in each derived class. But you may have a case where you don't want to modify a class but just want to add something. To avoid duplication of code you would inherit. And if you need both classes it would be inheritance from a concrete class.
So my answer would be: In all cases where you really only want to add something. Maybe this just doesn't happen very often.

When do you decide to use a visitors for your objects?

I always thought an object needs the data and the messages to act on it. When would you want a method that is extrinsic to the object? What rule of thumb do you follow to have a visitor? This is supposing that you have full control of the object graph.
The visitor pattern is particularly useful when applying an operation to all elements of a fairly complicated data structure for which traversal is non-trivial (e.g. traversing over the elements in parallel, or traversing a highly interconnected data structure) or in implementing double-dispatch. If the elements are to be processed sequentially and if double-dispatch is not needed, then implementing a custom Iterable and Iterator is usually the better choice, especially since it fits in better with the other APIs.
I always thought an object needs the
data and the messages to act on it.
When would you want a method that is
extrinsic to the object? What rule of
thumb do you follow to have a visitor?
This is supposing that you have full
control of the object graph.
It's sometimes not convenient to have all behaviors for a particular object defined in one class. For instance in Java, if your module requires a method toXml to be implemented in a bunch of classes originally defined in another module, it's complicated because you can not write toXml somewhere else than the original class file, which mean you can not extend the system without changing existing sources (in Smalltalk or other languages, you can group method in extension which are not tied to a particular file).
More generally, there's a tension in statically typed languages between the ability to (1) add new functions to existing data types, and (2) add new data types implementations supporting the same functions -- that's called the expression problem (wikipedia page).
Object oriented languages excel at point 2. If you have an interface, you can add new implementations safely and easily. Functional languages excel at point 1. They rely on pattern matching/ad-hoc polymorphism/overloading so you can add new functions to existing types easily.
The visitor pattern is a way to support point 1 in an object-oriented design: you can easily extend the system with new behaviors in a type-safe way (which wouldn't be the case if you do kind of manual pattern matching with if-else-instanceof because the language would never warn you if a case is not covered).
Visitors are then typically used when there is a fixed set of known types, which I think is what you meant by "full control of the object graph". Examples include token in a parser, tree with various types of nodes, and similar situations.
So to conclude, I would say you were right in your analysis :)
PS: The visitor pattern works well with the composite pattern, but they are also useful individually
Sometimes its just a matter of organization. If you have n-kinds of objects (ie: classes) with m-kinds of operations (ie: methods), do you want to have the n * m class/method pairs to be grouped by class or by method? Most OO languages strongly lean towards having things grouped by class, but there are cases where organizing by operation makes more sense. For example, in a multi-phase processing of object graphs, like in a compiler, is often more useful to think about each phase (ie: operation) as a unit rather than to think about all of operations that can happen to a particular sort of node.
A common use-case for the Visitor pattern where it's more than just strictly organizational is to break unwanted dependencies. For example, it's generally undesirable to have your "data" objects depend on your presentation layer, especially if you imagine that you may have multiple presentation layers. By using the visitor pattern, details of the presentation layer live in the visitor objects, not in methods of the data objects. The data objects themselves only know about the abstract visitor interface.
I use it a lot when I find I want to put a method that will be stateful onto Entity/DataObject/BusinessObject but I really don't want to introduce that statefulness to my object. A stateful visitor can do the job, or generate a collection of stateful executor objects from my non-stateful data objects. Particularly useful when processing of the work is going to be farmed out to executor threads, many stateful visitor/workers can reference the same group of non-stateful objects.
For me, the only one reason to use visitor pattern is when I need to perform double dispatch on graph-like data structure like tree/trie.
When you have the following problem:
Many distinct and unrelated operations need to be performed on node objects in a heterogeneous aggregate structure. You want to avoid “polluting” the node classes with these operations. And, you don’t want to have to query the type of each node and cast the pointer to the correct type before performing the desired operation.
Then you can use a Visitor pattern with one of the following intents:
Represent an operation to be performed on the elements of an object structure.
Define a new operation without changing the classes of the elements on which it operates.
The classic technique for recovering lost type information.
Do the right thing based on the type of two objects.
Double dispatch
(From http://sourcemaking.com/design_patterns/visitor)
The visitor pattern is most useful when you need behaviour to vary by object type (in a class hierarchy), and that behaviour can be defined in terms of the public interface provided by the object. The behaviour is not intrinsic to that object and doesn't benefit from or require encapsulation by the object.
I find visitors often naturally arises with graphs/trees of objects, where each node is part of a class hierarchy. To allow clients to walk the graph/tree and handle any each type of node in a uniform way, the Visitor pattern is really the simplest alternative.
For example, consider an XML DOM - a Node is the base class, with Element, Attribute and other types of Node define the class hierarchy.
Imagine the requirement is to output the DOM as JSON. The behaviour is not intrinsic to a Node - if it were, we would have to add methods to Node to handle all formats that the client might need (toJSON(), toASN1(), toFastInfoSet() etc.) We could even argue that toXML() doesn't belong there, although that might be provided for convenience since it is going to be used by most clients, and is conceptually "closer" to the DOM, so toXML could be made intrinsic to Node for convenience - although it doesn't have to be, and could be handled like all the other formats.
As Node and its subclasses make their state fully available as methods, we have all the information needed externally to be able to convert the DOM to some output format. Instead of then putting the output methods on the Node object, we can use a Visitor interface, with an abstract accept() method on Node, and implementation in each subclass.
The implementation of each visitor method handles the formatting for each node type. It can do this because all the state needed is available from the methods of each node type.
By using a visitor, we open the door to implementing any output format desired without needing to burden each Node class with that functionality.
I would always recommend using a visitor when you have full knowledge of what classes that implement an interface. In this way you won't do any not-so-pretty instanceof-calls, and the code becomes a lot more readable. Also, once a visitor has been implemented can be reused in many places, present and future.
Visitor pattern is a very natural solution to double dispatch problems. Double dispatch problem is a subset of dynamic dispatch problems and it stems from the fact that method overloads are determined statically at compile time, unlike virtual(overriden) methods, which are determined at runtime.
Consider this scenario:
public class CarOperations {
void doCollision(Car car){}
void doCollision(Bmw car){}
}
public class Car {
public void doVroom(){}
}
public class Bmw extends Car {
public void doVroom(){}
}
public static void Main() {
Car bmw = new Bmw();
bmw.doVroom(); //calls Bmw.doVroom() - single dispatch, works out that car is actually Bmw at runtime.
CarOperations carops = new CarOperations();
carops.doCollision(bmw); //calls CarOperations.doCollision(Car car) because compiler chose doCollision overload based on the declared type of bmw variable
}
This code below is adopted from my previous answer and translated to Java. The problem is somewhat different from the above sample, but demonstrates the essence of Visitor pattern.
//This is the car operations interface. It knows about all the different kinds of cars it supports
//and is statically typed to accept only certain ICar subclasses as parameters
public interface CarVisitor {
void StickAccelerator(Toyota car);
void ChargeCreditCardEveryTimeCigaretteLighterIsUsed(Bmw car);
}
//Car interface, a car specific operation is invoked by calling PerformOperation
public interface Car {
public string getMake();
public void setMake(string make);
public void performOperation(CarVisitor visitor);
}
public class Toyota implements Car {
private string make;
public string getMake() {return this.make;}
public void setMake(string make) {this.make = make;}
public void performOperation(CarVisitor visitor) {
visitor.StickAccelerator(this);
}
}
public class Bmw implements Car{
private string make;
public string getMake() {return this.make;}
public void setMake(string make) {this.make = make;}
public void performOperation(ICarVisitor visitor) {
visitor.ChargeCreditCardEveryTimeCigaretteLighterIsUsed(this);
}
}
public class Program {
public static void Main() {
Car car = carDealer.getCarByPlateNumber("4SHIZL");
CarVisitor visitor = new SomeCarVisitor();
car.performOperation(visitor);
}
}

Categories