5
\$\begingroup\$

I want to learn about Design Patterns and be able to apply them in Excel VBA. So to learn about patterns I bought a book that seems promising: Head First Design Patterns; it presents the material clearly. However, the code exercises/examples are in Java 8. VBA does not have direct counterparts for some things (e.g. Extends) so I need to work out how to accomplish the same/similar in VBA.

I am following along with the exercises and doing what I think parallels the Java in VBA. What I am asking here is "am I on the right track?"

More detail: the specific aspect (I think) is the Extends use in Java (MallardDuck Extends Duck); VBA has no Extends, so the specific question would be does the technique I used of passing the Duck to my VBA MallardDuck in the Create method and setting the fly and quack behaviors accomplish the Extends use in Java?

Here’s the Java for a part of on exercise:

public abstract class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;

    public Duck() {
    }

    public void setFlyBehavior(FlyBehavior fb) {
        flyBehavior = fb;
    }

    public void setQuackBehavior(QuackBehavior qb) {
        quackBehavior = qb;
    }

    abstract void display();

    public void performFly() {
        flyBehavior.fly();
    }

    public void performQuack() {
        quackBehavior.quack();
    }

    public void swim() {
        System.out.println("All ducks float, even decoys!");
    }
}

public class MallardDuck extends Duck {

    public MallardDuck() {

        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();

    }

    public void display() {
        System.out.println("I'm a real Mallard duck");
    }
}

public class MiniDuckSimulator {

    public static void main(String[] args) {

        MallardDuck mallard = new MallardDuck();
        FlyBehavior cantFly = () -> System.out.println("I can't fly");
        QuackBehavior squeak = () -> System.out.println("Squeak");
        RubberDuck rubberDuckie = new RubberDuck(cantFly, squeak);
        DecoyDuck decoy = new DecoyDuck();

        Duck model = new ModelDuck();

        mallard.performQuack();
        rubberDuckie.performQuack();
        decoy.performQuack();

        model.performFly();    
        model.setFlyBehavior(new FlyRocketPowered());
        model.performFly();
    }
}

Here's what I’ve done in VBA - There are some differences in the Main procedures because I haven't completely mimicked the Java in VBA. I am more interested in the Duck and Mallard implementations.

Any suggestions are greatly appreciated.

Duck class module:

'@Folder("SimUDuck.Objects.HeadFirst")
Option Explicit
Private Type TObject
    FlyBehavior As IFlyBehavior
    QuackBehavior As IQuackBehavior
    DuckModel As IDuckModel
End Type
Private this As TObject

Private Sub Class_Terminate()
    With this
        Set .FlyBehavior = Nothing
        Set .QuackBehavior = Nothing
    End With
End Sub

Public Property Get DuckModel() As IDuckModel
    Set DuckModel = this.DuckModel
End Property
Public Property Set DuckModel(ByVal model As IDuckModel)
    With this
        Set .DuckModel = model
    End With
End Property
Public Property Get FlyBehavior() As IFlyBehavior
    Set FlyBehavior = this.FlyBehavior
End Property
Public Property Set FlyBehavior(ByVal behavior As IFlyBehavior)
    Set this.FlyBehavior = behavior
End Property
Public Property Get QuackBehavior() As IQuackBehavior
    Set QuackBehavior = this.QuackBehavior
End Property
Public Property Set QuackBehavior(ByVal behavior As IQuackBehavior)
    Set this.QuackBehavior = behavior
End Property

Public Sub performFly()
    this.FlyBehavior.Fly
End Sub
Public Sub performQuack()
    this.QuackBehavior.Quack
End Sub
Public Sub Swim()
    'todo
End Sub
Public Sub Display()
    this.DuckModel.Display
End Sub

MallardDuck class module:

'@PredeclaredId
'@Folder("SimUDuck.Models.HeadFirst")
Option Explicit
Private Type TModel
    Display As String
End Type
Private this As TModel
Implements IDuckModel
Private Sub IDuckModel_Display()
    Debug.Print this.Display '"I'm A Mallard Duck"
End Sub

Public Function CreateDuck(ByVal duck As DuckObject) As IDuckModel
    With duck
        Set .FlyBehavior = New FlyWithWingsBehavior
        Set .QuackBehavior = New QuackBehavior
    End With
    With New MallardDuckModel
        .Display = "I'm A Mallard Duck"
        Set CreateDuck = .Self
    End With
End Function
Public Property Get Self() As IDuckModel
    Set Self = Me
End Property
Public Property Get Display() As String
    Display = this.Display
End Property
Public Property Let Display(ByVal value As String)
    this.Display = value
End Property
Public Sub MainDuck()
    Dim duck As DuckObject
    Set duck = New DuckObject
    With New MallardDuckModel
        Dim model As IDuckModel
        Set model = .CreateDuck(duck)
    End With
    With duck
        Set .DuckModel = model
        .performFly
        .performQuack
        .Display
        Dim FlyBehavior As IFlyBehavior
        Set FlyBehavior = New FlyRocketPoweredBehavior
        Set .FlyBehavior = FlyBehavior
        Dim QuackBehavior As IQuackBehavior
        Set QuackBehavior = New SqueakBehavior
        Set .QuackBehavior = QuackBehavior
        .performFly
        .performQuack
        .Display
    End With
    Set duck = New DuckObject
    With New ModelDuckModel
        Set model = .CreateDuck(duck)
    End With
    With duck
        Set .DuckModel = model
        .performFly
        .performQuack
        .Display
    End With
End Sub
\$\endgroup\$
9
  • 2
    \$\begingroup\$ @dfhwze I'm confused. This isn't the first design-patterns question on this site, and it isn't going to be the last. OP is presenting a pattern they read about in Java, and implemented it in VBA, and now they're asking for feedback on any/all aspects of the code. Did CR's scope suddenly become about "specific problems" overnight or I missed a memo? \$\endgroup\$ Commented Sep 28, 2019 at 19:24
  • 1
    \$\begingroup\$ @SmileyFtW to be fair it's indeed a bit hard to work out the pieces, since many of them are left out. I would recommend to edit your post to clearly identify the VBA classes (not sure I got the names right), and consider including more of the code - don't worry about making a long post, and note that TAB characters should be replaced by 4 spaces (I fixed that in your original post). \$\endgroup\$ Commented Sep 28, 2019 at 19:35
  • 1
    \$\begingroup\$ @MathieuGuindon Taking out the Java tag and formatting Java code the way you did is already a major improvement. It felt like a cross-language review request before. \$\endgroup\$ Commented Sep 28, 2019 at 19:48
  • 1
    \$\begingroup\$ @dfhwze - the specific aspect (I think) is the Extends use in Java (MallardDuck Extends Duck); VBA has no Extends, so the specific question would be does the technique I used of passing the Duck to my VBA MallardDuck in the Create method and setting the fly and quack behaviors accomplish the Extends use in Java? I will bone up on formatting questions to avoid messes like my first post was, \$\endgroup\$ Commented Sep 28, 2019 at 20:47
  • 2
    \$\begingroup\$ You should include your last comment in the question, since noone will read through these comments :p \$\endgroup\$ Commented Sep 28, 2019 at 20:49

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.