How to interact with the strategy design patten - c++

I would like to ask a couple of questions of design patterns.
Lets take for example strategy design pattern:
class Printer{
public:
void print(Message){
}
};
class Message{
public:
void print();
};
class SingleMessage : public Message{
string s;
public:
void print();
};
class Messages : public Message{
vector<Message> v;
public:
void print();
};
According to UML of this pattern, Printer should have method print(Message). What I don't understand (and sorry if this is idiotic question) is do we need to call Message class print method or what? We need to print out message, but we can't create new Message object in class Printer, because then it would be composition. So what should we do then?
Also, maybe you can share some sort of tutorial in which design patterns would be explained (how to use them, when to use them, etc.)?

First off, the concept of composition is on a whole different level than design patterns. Most design patterns use composition – that’s totally fine.
Secondly, no, you don’t use composition here. You invoke the print function of the argument that’s passed to the printer:
class Printer{
public:
void print(Message& m) {
m.print();
}
};
I’ve gone ahead and fixed a bug: the argument needs to be passed by reference (or as a pointer), otherwise you lose the dynamic type. For that reason, the Message::print function also needs to be declared as virtual.

What I don't understand (and sorry if this is idiotic question) is do we need to call Message class print method or what?
Yes. The Message::print function should be abstract, and implemented (as a different strategy) in each class inheriting from Message.
We need to print out message, but we can't create new Message object in class Printer, because then it would be composition. So what should we do then?
You don't need to create a new instance in the printer (i.e. you don't need composition here). All you do here is choose the implementation strategy for printing by deciding what concrete implementation will be passed into the Printer::print function.
Also, maybe you can share some sort of tutorial in which design patterns would be explained (how to use them, when to use them, etc.)?
Normally design patterns are idiomatic solutions to re-occurring design problems. You can find details on wikipedia regarding when to use them. For example, this page says:
"In computer programming, the strategy pattern (also known as the
policy pattern) is a software design pattern, whereby an algorithm's
behaviour can be selected at runtime."
As a side note, this is not a very good example for the strategy pattern. A better one would have been to abstract what printing means, not what a message means:
class Message{
public:
void display(Printer& p) {
p.print(*this); // what printing strategy is applied to
// display the message depends on the
// concrete type of the parameter (on what
// Printer specialization you call
// the function with)
}
};
struct Printer{
virtual void print(Message& m);
};
struct BWPrinter: Printer {
virtual void print(Message& m);
};
struct ColorPrinter: Printer {
virtual void print(Message& m);
};
struct IOStreamPrinter: Printer {
IOStreamPrinter(std::iostream& s);
virtual void print(Message& m);
};

What you probably want to do is to provide a Printer as Strategy. You can spezialize a CoutPrinter FilePrinter or PrinterPrinter...
class Printer{
public:
virtual void print(const string& message) = 0;
};
class CoutPrinter{
public:
void print(const string& message) override {
std::cout << message << "\n";
}
};
You can then use this concept to print messages:
class Message{
public:
virtual print(Printer& printer) = 0;
};
class SingleMessage : public Message {
string s;
public:
void print(Printer& printer) override
{
printer.print(s)
}
};
class Messages {
vector<Message> messages;
std::unique_ptr<Printer> printer;
public:
/// Inject the concrete Printer strategy here
Messages(std::unique_ptr<Printer> printerStrategy) :
printer(move(printer))
{}
void print() {
for(auto& m : messages)
m.print(*printer);
}
};
You can know use constructor injection to select different printers for your Messages
int main()
{
Messages messages {std::make_unique<CoutPrinter>()};
messages.print(); // will print all messages to std::cout
}
Composite Pattern
In your example you derived Messages from Message. This is the Composite Pattern. You can combine both:
class Messages : public Messages {
vector<Message> messages;
public:
void print(Printer& printer) override {
for(auto& m : messages)
m.print(*printer);
}
};
int main()
{
Messages messages;
CoutPrinter printer;
messages.print(printer); // will print all messages to std::cout
}

Related

Running into c++ virtual template function issue due to interface based programming

We are designing a new system where we have created interfaces for most of our classes so that we can create mocks (google mocks) for them for unit testing. As a result, all the functions are virtual but the issue is that I am often running into template virtual function issue due to this. I have seen some examples on how to do multi dispatch but they all seem to be using some variation of templates, it doesn't seem straightforward. So does it mean that my entire codebase will now end up with templates making it difficult to read/use and debug?
Or am I not designing good interfaces. Here is a simple example where I am writing an interface for a message queue.
Class IMessageQueue {
Public:
Virtual int send(const T & value); // I can't do this but this is exactly what I want to do, as send should be able to send any type
};
Class MessageQueue : public IMessageQueue {
Public:
Virtual int send(const T & value) { ... }
};
Class MockMQ : public IMessageQueue {
Public:
Virtual int send(const T & value) {
// mock implementation
}
};
How do I get around this problem? This is just one example but I run into lots of these type of issues due to interface based programming.
It depends if you need your IMessageQueue to dispatch specific unknown type or any type. That's not the same thing.
A specific unknown type can be managed by
template<typename T>
class IMessageQueue {
public:
virtual int send(const T& value);
}
So that you can have your IMessageQueue<MyMessage> and IMessageQueue<OtherMessage>.
If, instead, you need to be able to send any type with the same type of message queue then your option is to declare a specific interface common to all messages as in
class Message
{
protected:
Message() : { .. }
};
class MyMessage : public Message
{
..
};
class MessageQueue
{
public:
void send(const Message& message);
};

Is checking of object type really always sign of bad design?

I have a source of some lines of text, each of which is a message, representing object of some type. I'm making a parser for these lines, which should take the text line as input and give the ready to use object as output. So I make the following hierarchy of classes:
class Message
{
public:
virtual ~Message(){};
};
class ObjectTypeA : public Message
{/*...*/};
class ObjectTypeB : public Message
{/*...*/};
class ObjectTypeC : public Message
{/*...*/};
and here's how it's used:
std::shared_ptr<Message> parseLine(std::string& line);
void doWork()
{
std::string line;
while(getLine(line))
{
std::shared_ptr<Message> object=parseLine(line);
if(dynamic_cast<ObjectTypeA*>(object.get()))
doSomethingA(*static_cast<ObjectTypeA*>(object.get()));
else if(dynamic_cast<ObjectTypeB*>(object.get()))
doCompletelyUnrelatedProcessing(*static_cast<ObjectTypeB*>(object.get()));
else if(dynamic_cast<ObjectTypeC*>(object.get()))
doSomethingEvenMoreDifferent(*static_cast<ObjectTypeC*>(object.get()));
}
}
Here the parser would be a library function, and the objects don't know in advance how they will be processed. So, I can't put the processing code to a virtual function of Message implementations.
But many of the answers in this question say that if one needs to check type of the object, it's a sign of bad design. But I can't seem to see what's bad here. Is there any better way to organize the solution?
First off, it's not always a sign of bad design. There are very few absolutes in "soft" things like "good" or "bad" design. Nevertheless, it does often indicate a different approach would be preferable, for one or more of these reasons: extensibility, ease of maintenance, familiarity, and similar.
In your particular case: One of the standard ways to make arbitrary class-specific processing possible without type switches or bloating/polluting the interface of the class is to use the Visitor pattern. You create a generic MessageVisitor interface, teach the Message subclasses to call into it, and implement it wherever you need to process them:
class MessageVisitor;
class Message
{
public:
virtual ~Message(){};
virtual void accept(MessageVisitor &visitor) = 0;
};
class ObjectTypeA : public Message
{
void accept(MessageVisitor &visitor) override
{ visitor.visit(*this); }
/*...*/
};
class ObjectTypeB : public Message
{
void accept(MessageVisitor &visitor) override
{ visitor.visit(*this); }
/*...*/
};
class ObjectTypeC : public Message
{
void accept(MessageVisitor &visitor) override
{ visitor.visit(*this); }
/*...*/
};
class MessageVisitor
{
public:
virtual void visit(ObjectTypeA &subject) {}
virtual void visit(ObjectTypeB &subject) {}
virtual void visit(ObjectTypeC &subject) {}
};
You would then use it like this:
void doWork()
{
struct DoWorkMessageVisitor : MessageVisitor
{
void visit(ObjectTypeA &subject) override { doSomethingA(subject); }
void visit(ObjectTypeB &subject) override { doSomethingB(subject); }
void visit(ObjectTypeC &subject) override { doSomethingC(subject); }
};
std::string line;
while(getLine(line))
{
std::shared_ptr<Message> object=parseLine(line);
DoWorkMessageVisitor v;
object->accept(v);
}
}
Feel free to customise this with const overloads etc. as necessary.
Note that accept cannot be implemented in the base class, because you need the correct type of *this in the invocation of visit. That is where the type switch has "moved".
An alternative is to make the visit functions in MessageVisitor pure virtual instead of empty. Then, if you need to add a new message type, it will automatically force you to update all places where such type-specific processing occurs.
You're really asking for opinions on whats good and bad design. Here's mine:
Yours is bad design, because you try to do something in another class that should be handled by the subclasses, because that's what polymorphism is for.
Your mother class should have a
virtual void do_stuff_that_is_specific_to_the_subclass(...) = 0;
method, which you'd implement in your subclasses.
Here the parser would be a library function, and the objects don't know in advance how they will be processed. So, I can't put the processing code to a virtual function of Message implementations.
Why not? You should simply have a
virtual void do_stuff_that_is_specific_to_the_subclass(parser&, ...) = 0;
method that uses the parser differently for each subclass. There's no reason that what you can do in your if/else clauses couldn't just be done in the subclasses, unless it breaks encapsulation, which I'd doubt, because the only reason you've got these objects is that you want to do specific things differently for different lines.
doSomethingA, doCompletelyUnrelatedProcessing and doSomethingEvenMoreDifferent could be just overrides of pure virtual function of Message class. In your case that would be much more effecient and better as a design solution.

oop - C++ - Proper way to implement type-specific behavior?

Let's say I have a parent class, Arbitrary, and two child classes, Foo and Bar. I'm trying to implement a function to insert any Arbitrary object into a database, however, since the child classes contain data specific to those classes, I need to perform slightly different operations depending on the type.
Coming into C++ from Java/C#, my first instinct was to have a function that takes the parent as the parameter use something like instanceof and some if statements to handle child-class-specific behavior.
Pseudocode:
void someClass(Arbitrary obj){
obj.doSomething(); //a member function from the parent class
//more operations based on parent class
if(obj instanceof Foo){
//do Foo specific stuff
}
if(obj instanceof Bar){
//do Bar specific stuff
}
}
However, after looking into how to implement this in C++, the general consensus seemed to be that this is poor design.
If you have to use instanceof, there is, in most cases, something wrong with your design. – mslot
I considered the possibility of overloading the function with each type, but that would seemingly lead to code duplication. And, I would still end up needing to handle the child-specific behavior in the parent class, so that wouldn't solve the problem anyway.
So, my question is, what's the better way of performing operations that where all parent and child classes should be accepted as input, but in which behavior is dictated by the object type?
First, you want to take your Arbitrary by pointer or reference, otherwise you will slice off the derived class. Next, sounds like a case of a virtual method.
void someClass(Arbitrary* obj) {
obj->insertIntoDB();
}
where:
class Arbitrary {
public:
virtual ~Arbitrary();
virtual void insertIntoDB() = 0;
};
So that the subclasses can provide specific overrides:
class Foo : public Arbitrary {
public:
void insertIntoDB() override
// ^^^ if C++11
{
// do Foo-specific insertion here
}
};
Now there might be some common functionality in this insertion between Foo and Bar... so you should put that as a protected method in Arbitrary. protected so that both Foo and Bar have access to it but someClass() doesn't.
In my opinion, if at any place you need to write
if( is_instance_of(Derived1) )
//do something
else if ( is_instance_of(Derived2) )
//do somthing else
...
then it's as sign of bad design. First and most straight forward issue is that of "Maintainence". You have to take care in case further derivation happens. However, sometimes it's necessary. for e.g if your all classes are part of some library. In other cases you should avoid this coding as far as possible.
Most often you can remove the need to check for specific instance by introducing some new classes in the hierarchy. For e.g :-
class BankAccount {};
class SavingAccount : public BankAccount { void creditInterest(); };
class CheckingAccount : public BankAccount { void creditInterest(): };
In this case, there seems to be a need for if/else statement to check for actual object as there is no corresponsing creditInterest() in BanAccount class. However, indroducing a new class could obviate the need for that checking.
class BankAccount {};
class InterestBearingAccount : public BankAccount { void creditInterest(): } {};
class SavingAccount : public InterestBearingAccount { void creditInterest(): };
class CheckingAccount : public InterestBearingAccount { void creditInterest(): };
The issue here is that this will arguably violate SOLID design principles, given that any extension in the number of mapped classes would require new branches in the if statement, otherwise the existing dispatch method will fail (it won't work with any subclass, just those it knows about).
What you are describing looks well suited to inheritance polymorphicism - each of Arbitrary (base), Foo and Bar can take on the concerns of its own fields.
There is likely to be some common database plumbing which can be DRY'd up the base method.
class Arbitrary { // Your base class
protected:
virtual void mapFields(DbCommand& dbCommand) {
// Map the base fields here
}
public:
void saveToDatabase() { // External caller invokes this on any subclass
openConnection();
DbCommand& command = createDbCommand();
mapFields(command); // Polymorphic call
executeDbTransaction(command);
}
}
class Foo : public Arbitrary {
protected: // Hide implementation external parties
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Foo specific fields here
}
}
class Bar : public Arbitrary {
protected:
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Bar specific fields here
}
}
If the base class, Arbitrary itself cannot exist in isolation, it should also be marked as abstract.
As StuartLC pointed out, the current design violates the SOLID principles. However, both his answer and Barry's answer has strong coupling with the database, which I do not like (should Arbitrary really need to know about the database?). I would suggest that you make some additional abstraction, and make the database operations independent of the the data types.
One possible implementation may be like:
class Arbitrary {
public:
virtual std::string serialize();
static Arbitrary* deserialize();
};
Your database-related would be like (please notice that the parameter form Arbitrary obj is wrong and can truncate the object):
void someMethod(const Arbitrary& obj)
{
// ...
db.insert(obj.serialize());
}
You can retrieve the string from the database later and deserialize into a suitable object.
So, my question is, what's the better way of performing operations
that where all parent and child classes should be accepted as input,
but in which behavior is dictated by the object type?
You can use Visitor pattern.
#include <iostream>
using namespace std;
class Arbitrary;
class Foo;
class Bar;
class ArbitraryVisitor
{
public:
virtual void visitParent(Arbitrary& m) {};
virtual void visitFoo(Foo& vm) {};
virtual void visitBar(Bar& vm) {};
};
class Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Parent specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitParent(*this);
}
};
class Foo: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Foo specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitFoo(*this);
}
};
class Bar: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Bar specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitBar(*this);
}
};
class SetArbitaryVisitor : public ArbitraryVisitor
{
void visitParent(Arbitrary& vm)
{
vm.DoSomething();
}
void visitFoo(Foo& vm)
{
vm.DoSomething();
}
void visitBar(Bar& vm)
{
vm.DoSomething();
}
};
int main()
{
Arbitrary *arb = new Foo();
SetArbitaryVisitor scv;
arb->accept(scv);
}

C++: Adding methods to a polymorphic class hierarchy without violating SRP?

I have a design issue that I constantly keep encountering.
For the sake of illustration, let's assume that I have a polymorphic class hierarchy
class A { public: virtual ~A() {} ... };
class B: public A { ... };
class C: public B { ... };
class D: public A { ... };
...
I want to be able to print instances of these classes in a polymorphic way, i.e. each class has its own way of printing itself. The obvious way of achieving this would be to add
virtual void print(OutputStream &os) = 0;
into the base class and override this method in every subclass. However, if the original responsibility of the classes is not related to printing, this will add another responsibility to them, thus violating SRP.
My question is: what is a proper way of achieving the desired behavior without violating SRP?
In this post, a solution based on the Visitor design pattern is proposed. However, then I would need to create a class which has to know about every subclass of A. I would like to be able to add and remove subclasses without a need to always modify the visitor.
Is there some other, SRP-preserving way than the two ways described above?
There is an acyclic visitor pattern that eliminates the need to know about every subclass. It relies on dynamic_cast, but may be what you need.
There is nothing wrong with a class printing itself. It does not violate SRP because printing does not constitute a responsibility.
Remember that responsibility is defined as a reason to change. You don't change a class because your requirements for printing change. The class should only send name-value pairs to the entity responsible for printing, called the formatter. This procedure of sending name-value pairs never ever changes by itself. Any changes in it are only prompted by other changes, unrelated to printing (when you e.g. add a field, you also add its representation to the printing procedure).
The formatter should know nothing about the classes it prints, but simply present the name-value pairs according to some set of requirements. The formatter changes when the printing requirements change. Therefore printing would be the sole responsibility of the formatter.
You'll need to go for some sort of visitor of double dispatch solution in order to do this. The double dispatch approach is a bit more lightweight, so how about something like this:
In A:
class Processor
{
public:
virtual void Process(const A &a)const {}
virtual void Process(const B &b)const {}
virtual void Process(const C &c)const {}
virtual void Process(const D &d)const {}
virtual void Process(const E &e)const {}
};
In A:
class A
{
public:
virtual void Process(const Processor &processor)
{
processor.Process(*this);
}
};
Then, in each derived class override Process with an identical definition:
virtual void Process(const Processor &processor)
{
processor.Process(*this);
}
This will ensure that the correct overload in Process is called.
Now, create a stream processor:
class StreamProcessor : public Processor
{
private:
OutputStream &m_OS;
public:
StreamProcessor(OutputStream &os) : m_OS(os)
{
}
virtual void Processor(const A &a)const
{
m_os << "got a A";
}
virtual void Processor(const B &b)const
{
m_os << "got a B";
}
virtual void Processor(const C &c)const
{
m_os << "got a C";
}
// etc
};
And then:
OutputStream &operator<<(OutputStream &os, A &a)
{
PrintProcessor(os);
a.Process(PrintProcessor);
return os;
}
You can provide an interface for printing responsibility and keep common responsibilities under your class hierarchy. Example:
class Printer { public: virtual void print(OutputStream &os) = 0; }
class A { public: virtual ~A() {} ... };
class B: public A, public Printer { ... }; // this needs print function, use interface.
class C: public B { ... };
class D: public A { ... };

Dependency injection and event handling

class ITransportProvider
{
public:
virtual ~ITransportProvider() { }
protected:
virtual void SendData() = 0;
// Concrete TransportProvider will call OnReceiveDataEvent
// virtual void RegisterHandlers(std::function<void()> onReceiveDataEvent);
}
class Device
{
public:
Device(shared_ptr<ITransportProvider> transport)
: m_Transport(transport)
{
// transport->RegisterHandlers(boost::bind(&Device::OnReceiveData, this));
}
void SendData()
{
m_Transport->SendData();
}
// Which design pattern to use to get concrete TransportProvider's OnReceiveData event?
//void OnReceiveData()
//{
//}
private:
shared_ptr<ITransportProvider> m_Transport;
};
I've always added a "RegisterHandlers" in my ITransportProvider and make Device call it in its c'tor.
I'd like to know if its correctness in the eyes of DI/IoC gurus and would love to hear all suggestions.
EDIT:
To clarify, I'm asking if there's a better way of decoupling TransportProvider from Device besides the above way which is via DI and the Observer pattern.
You have a reasonable design. Decoupling can be handled at many different levels in different ways with various trade-offs. Your design is good for the case where you know the sending and receiving are related, but there is no particular compile-time relationship between Device instances and Transport implementations. If there was a compile-time relationship, you might use policy-based design:
class TransportProviderA
{
public:
void SendData();
virtual void OnReceiveData() = 0;
}
template <typename TransportPolicy>
class Device : public TransportPolicy
{
public:
Device(const TransportPolicy &transport_policy)
: TransportPolicy(transport_policy)
{
}
// SendData provided by TransportPolicy
virtual void OnReceiveData(); // overrides TransportPolicy's template method.
};
Then use it like this:
Device<TransportPolicyA> my_device(TransportPolicyA());