Asked  7 Months ago    Answers:  5   Viewed   37 times

One stumbles upon this phrase when reading about design patterns.

But I don't understand it, could someone explain this for me?

 Answers

55

Interfaces are just contracts or signatures and they don't know anything about implementations.

Coding against interface means, the client code always holds an Interface object which is supplied by a factory. Any instance returned by the factory would be of type Interface which any factory candidate class must have implemented. This way the client program is not worried about implementation and the interface signature determines what all operations can be done. This can be used to change the behavior of a program at run-time. It also helps you to write far better programs from the maintenance point of view.

Here's a basic example for you.

public enum Language
{
    English, German, Spanish
}

public class SpeakerFactory
{
    public static ISpeaker CreateSpeaker(Language language)
    {
        switch (language)
        {
            case Language.English:
                return new EnglishSpeaker();
            case Language.German:
                return new GermanSpeaker();
            case Language.Spanish:
                return new SpanishSpeaker();
            default:
                throw new ApplicationException("No speaker can speak such language");
        }
    }
}

[STAThread]
static void Main()
{
    //This is your client code.
    ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
    speaker.Speak();
    Console.ReadLine();
}

public interface ISpeaker
{
    void Speak();
}

public class EnglishSpeaker : ISpeaker
{
    public EnglishSpeaker() { }

    #region ISpeaker Members

    public void Speak()
    {
        Console.WriteLine("I speak English.");
    }

    #endregion
}

public class GermanSpeaker : ISpeaker
{
    public GermanSpeaker() { }

    #region ISpeaker Members

    public void Speak()
    {
        Console.WriteLine("I speak German.");
    }

    #endregion
}

public class SpanishSpeaker : ISpeaker
{
    public SpanishSpeaker() { }

    #region ISpeaker Members

    public void Speak()
    {
        Console.WriteLine("I speak Spanish.");
    }

    #endregion
}

alt text

This is just a basic example and actual explanation of the principle is beyond the scope of this answer.

EDIT

I have updated the example above and added an abstract Speaker base class. In this update, I added a feature to all Speakers to "SayHello". All speaker speak "Hello World". So that's a common feature with similar function. Refer to the class diagram and you'll find that Speaker abstract class implement ISpeaker interface and marks the Speak() as abstract which means that the each Speaker implementation is responsible for implementing the Speak() method since it varies from Speaker to Speaker. But all speaker say "Hello" unanimously. So in the abstract Speaker class we define a method that says "Hello World" and each Speaker implementation will derive the SayHello() method.

Consider a case where SpanishSpeaker cannot Say Hello so in that case you can override the SayHello() method for Spanish Speaker and raise proper exception.

Please note that, we have not made any changes to Interface ISpeaker. And the client code and SpeakerFactory also remain unaffected unchanged. And this is what we achieve by Programming-to-Interface.

And we could achieve this behavior by simply adding a base abstract class Speaker and some minor modification in Each implementation thus leaving the original program unchanged. This is a desired feature of any application and it makes your application easily maintainable.

public enum Language
{
    English, German, Spanish
}

public class SpeakerFactory
{
    public static ISpeaker CreateSpeaker(Language language)
    {
        switch (language)
        {
            case Language.English:
                return new EnglishSpeaker();
            case Language.German:
                return new GermanSpeaker();
            case Language.Spanish:
                return new SpanishSpeaker();
            default:
                throw new ApplicationException("No speaker can speak such language");
        }
    }
}

class Program
{
    [STAThread]
    static void Main()
    {
        //This is your client code.
        ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
        speaker.Speak();
        Console.ReadLine();
    }
}

public interface ISpeaker
{
    void Speak();
}

public abstract class Speaker : ISpeaker
{

    #region ISpeaker Members

    public abstract void Speak();

    public virtual void SayHello()
    {
        Console.WriteLine("Hello world.");
    }

    #endregion
}

public class EnglishSpeaker : Speaker
{
    public EnglishSpeaker() { }

    #region ISpeaker Members

    public override void Speak()
    {
        this.SayHello();
        Console.WriteLine("I speak English.");
    }

    #endregion
}

public class GermanSpeaker : Speaker
{
    public GermanSpeaker() { }

    #region ISpeaker Members

    public override void Speak()
    {
        Console.WriteLine("I speak German.");
        this.SayHello();
    }

    #endregion
}

public class SpanishSpeaker : Speaker
{
    public SpanishSpeaker() { }

    #region ISpeaker Members

    public override void Speak()
    {
        Console.WriteLine("I speak Spanish.");
    }

    public override void SayHello()
    {
        throw new ApplicationException("I cannot say Hello World.");
    }

    #endregion
}

alt text

Tuesday, June 1, 2021
 
sholsinger
answered 7 Months ago
38

There is no consensus as in the Silver Bullet sense. For established patterns, you have multiple options like

  • Subject/Observer,
  • Signal Slot,
  • Event Dispatcher or
  • Pipes and Filters

to name a few.

Which you use is up to you, but you should make sure your system architecture supports the modularity. Have a look at these slides for some ideas

  • http://qafoo.com/talks/11_06_ipc_spring_modular_application_architecture.pdf
Saturday, May 29, 2021
 
ManojGeek
answered 7 Months ago
54

Depending upon the complexity of your data class you may wish to use a Visitor pattern. If you have some kind of nested data structure then Visitor may well be what you need.

If formatting is something relatively simple, for example you are producing variations on something such as a comma separated list then you can take an approach like this.

Your formatter objects all implement an interface such as (pseudo code)

 IFormatter ( start(); addInt(name, value), addString(name, value) .... end() );

then the data class has a method

  public void formatMyself( IFormatter formatter ) {

        formatter.start()
        formatter.addString("aField", myA);
        formatter.addInteger("bfield", myB);
        formatter.end();          
  }

This makes the class being formatted responsible for the choice of data to be formatted, and the formatter responsible for the details of the format.

Saturday, August 14, 2021
 
Kevin
answered 4 Months ago
55

The part after the slash is how many subnet mask bits to use. Since the use of classless routing you use slash instead of saying class A or B whatever. Example:

192.168.1.1/24 is 192.168.1.1 255.255.255.0

255.255.255.0 is using 24 of the 32 bits to create the subnet.

in binary it looks like this:

11111111.11111111.11111111.00000000

so a /30 would look like:

255.255.255.252 or in binary 
11111111.11111111.11111111.11111100

the remaing 00 is for hosts; the 1's are the network.

Sunday, September 5, 2021
 
ChronoFish
answered 3 Months ago
78

The TERM environment variable tells your program what type of terminal its running on. Each type of terminal displays data and responds to commands in its own way. For example, a VT100 terminal works quite differently from a IBM 3270 terminal.

The error message you're seeing says that the TERM environment variable isn't set, probably because you're trying to launch your program from within Xcode. You can add environment variables to be set in Xcode 4's scheme settings. As rob mayoff points out below, though, Xcode's console isn't a proper terminal emulator, so trying to run your program within Xcode isn't going to give you the results you're looking for.

Saturday, December 4, 2021
 
Uwe
answered 2 Days ago
Uwe
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share