Could you comment on my little program? What design pattern it is?

S

Shawn

Hi,

I am amazed at the following way transforming a Class into different
Class on the fly(Expert becomes Singer, Chef or Painter). Could you
throw in some comment for me? Is this called Strategy design pattern?

Now I do feel "has-a" is more powerful than "is-a".

Thank you very much.


<code>

interface Talent
{
void showTalent();
}

class Singing implements Talent
{
public void showTalent()
{
System.out.println("do-rei-mei");
}
}

class Painting implements Talent
{
public void showTalent()
{
System.out.println("yellow, blue, red");
}
}

class Cooking implements Talent
{
public void showTalent()
{
System.out.println("gong-bao chicken");
}
}

//Skills of Expert is undecided right now. His skills will be set on the
fly. I am truely amazed at how powerful this technique it is.
public class Expert {
private Talent myTalent = null; //undecided yet

public Expert(Talent t)
{
myTalent = t;
}

public void serve()
{
myTalent.showTalent();
}

public static void main(String[] args)
{
Expert anExpert = new Expert(new Singing()); //this expert is singer
anExpert.serve();

anExpert = new Expert(new Cooking()); //this expert is Chef
anExpert.serve();

anExpert = new Expert(new Painting()); //this expert is Painter
anExpert.serve();
}
}
</code>
 
S

Simon Brooke

Shawn ('[email protected]') said:
Hi,

I am amazed at the following way transforming a Class into different
Class on the fly(Expert becomes Singer, Chef or Painter).

No, it doesn't. Expert remains Expert. A Singer remains a Singer. The fact
that a singer is a kind of expert and inherits behaviour from expert is
just the core idea of object oriented programming. Yes, it's a powerful
abstraction...
 
P

Patricia Shanahan

Shawn said:
Hi,

I am amazed at the following way transforming a Class into different
Class on the fly(Expert becomes Singer, Chef or Painter). Could you
throw in some comment for me? Is this called Strategy design pattern?

Now I do feel "has-a" is more powerful than "is-a".

For something like skill, I would go a stage further, and use "has-some"
rather than "has-a". Many people have more than one skill. Supporting
one-to-many relationships is another advantage of composition over
inheritance.

Patricia
 
S

Shawn

Thank you for your comments. Now see something new I did in the Class
MyHouse. The chair is broken. To fix it, write a class implementing
Talent interface, plug it into Expert. Now the Expert with Talent of
RepairingFurniture (a carpenter actually) is in my house now.
Expert.server() will fix the broken chair.


<code>
interface Talent
{
void showTalent();
}

class Singing implements Talent
{
public void showTalent()
{
System.out.println("do-rei-mei");
}
}

class Painting implements Talent
{
public void showTalent()
{
System.out.println("yellow, blue, red");
}
}

class Cooking implements Talent
{
public void showTalent()
{
System.out.println("gong-bao chicken");
}
}

class Expert
{
private Talent myTalent = null;

public Expert(Talent t)
{
myTalent = t;
}

public void serve()
{
myTalent.showTalent();
}

public static void main(String[] args)
{
Expert anExpert = new Expert(new Singing()); //this expert is singer
anExpert.serve();

anExpert = new Expert(new Cooking()); //this expert is Chef
anExpert.serve();

anExpert = new Expert(new Painting()); //this expert is Painter
anExpert.serve();
}
}

public class MyHouse
{
private boolean chairBroken = true;

public boolean isChairBroken()
{
return this.chairBroken;
}

private class RepairingFurniture implements Talent
{
public void showTalent()
{
if (chairBroken == true)
{
chairBroken = false;
}
}
} //end of private class


public static void main(String[] args)
{
MyHouse myHouse = new MyHouse();
if (myHouse.isChairBroken())
{
System.out.println("The chair needs to be fixed");
}
else
{
System.out.println("The chair has been fixed");
}

Expert anExpert = new Expert(myHouse.new RepairingFurniture()); //an
Expert with talent of RepairingFurniture (a carpenter) is in my house now.
anExpert.serve(); //this expert will fix the chair for us!!!

if (myHouse.isChairBroken())
{
System.out.println("The chair needs to be fixed");
}
else
{
System.out.println("The chair has been fixed");
}
}
}
</code>
 
T

Thomas Weidenfeller

Shawn said:
Thank you for your comments. Now see something new I did in the Class
MyHouse. The chair is broken. To fix it, write a class implementing
Talent interface, plug it into Expert. Now the Expert with Talent of
RepairingFurniture (a carpenter actually) is in my house now.
Expert.server() will fix the broken chair.

Ok, so you like to play with object-oriented features. Then the
following two books might be of interest for you. However, before you go
out and buy them, check them out in a library. They are on professional
level and they are not available for pocket money:

Gamma; Helm; Johnson; Vlissides: Design Patterns: Elements of Reusable
Object-Oriented Software

Fowler: Analysis Patterns: Reusable Object Models

Oh, and one thing. In real world applications it is also a good idea to
know when to stop building abstractions and adding indirections and to
just write some straight-forward code to get things done. This is a
matter of experience.

In your example, separating Expert and Talent in a real world
application might be overengineering. If there are, for example, only
Experts who can have Talent (and not, let's say Dogs or Laymen), and if
there are only few Talents of interest, and if an Expert's role always
only requires to have one single Talent, then using

interface Expert { ... }
class Singer implements Expert { ... }
class Painter implements Expert { ... }
class Cook implements Expert { ... }

might also get the job done in a simple, maintainable, easy to
understand way. It is not as sophisticated and beautiful as modeling
Talent separately, but it might well do in practice.

/Thomas
 
L

Lew

Shawn said:
public class Expert {
private Talent myTalent = null; //undecided yet

The initialization to null is redundant. Instance variables are initialized
to "zero-like" values (null for references) by default.

Also, stating "undecided yet" in a comment is misleading since the constructor
sets the variable in this example, so no fully-constructed instance will ever
see that "yet" moment.
public Expert(Talent t)
{
myTalent = t;
}

In other words, all clients will see your Expert object only after it's fully
constructed, so the "yet" moment is practically non-existent.

BTW, you should probably forbid null for the constructor argument:

public Expert(Talent t)
{
if ( t == null )
{
throw new NullPointerException( "null talent" );
}
myTalent = t;
}

Otherwise serve() could throw that exception for you, but without useful
message verbiage. That would be an example of a bug from earlier (the
constructor) showing up later (the method call), a common programming problem
that confounds analysis and repair.

- Lew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top