Template method pattern: changing the algorithm's architecture - oop

I'm using template method pattern in my project like following
class Template
{
public:
void algorithm();
{
A();
B();
}
private:
virtual void A()=0;
virtual void B()=0;
}
I have some subclasses implement method A & B in different ways.
But now I need a new class Template2 to implement a slightly different algorithm.
class Template2
{
public:
void algorithm();
{
A();
B();
C();
}
private:
virtual void A()=0;
virtual void B()=0;
void C()
{
//some stuff
A();
//some stuff
B();
}
}
C is identical along all subclasses, so I do not make it virtual.
Right now I create a new inheritance hierarchy based on Template2, but this seems stupid because I have to copy and paste every subclasses's code in this new hierarchy.
Is there anyway to do it in a more elegant way?
EDIT
Sorry, I did not make my point clear.
Now I have two inheritance hierarchy.
1. An abstract class Template and some subclasses A1,A2,A3,A4...
2. An abstract class Template2 and some subclasses B1,B2,B3,B4...
This works fine, but I'm wondering if there's a way to somehow merge these two hierarchies because A1 and B1 has the same code except they're derived from Template and Template2 respectively.
Whether the solution is template method pattern is irrelevant for me
Both bcperth and Spotted's answers work for me :)
Thanks a lot.

I agree with Spotted, but have you considered just adding additional algorithms to your template class? Its still Template Pattern with multiple algorithms. You get a fatter class but no code repetition. Below is an illustration.
#include <iostream>
using namespace std;
class Template
{
public:
void algorithm1()
{
A();
B();
}
void algorithm2()
{
A();
B();
C();
}
private: void C()
{
cout << endl << "start C() ";
A();
cout << "middle C() ";
B();
cout << "end C()" << endl;
}
private:
virtual void A() = 0;
virtual void B() = 0;
};
class real :public Template {
void A() { cout << "A(1) "; }
void B() { cout << "B(1) "; }
};
int main()
{
real Real;
cout << "algorithm1" <<endl;
Real.algorithm1();
cout << endl;
cout << endl << "algorithm2 << endl";
Real.algorithm2();
return 0;
}

First, forgive my poor C++ syntax.
I suggest that you decouple A() and B() from Template so that you can more easily reuse them in Template2
class Strategy
{
public:
virtual void A()=0;
virtual void B()=0;
}
Then have a common ancestor between Template and Template2:
class AbstractTemplate
{
public:
virtual void algorithm()=0;
}
And finally implementing Template and Template2 as "final" classes (=no need for subclasses).
class Template : AbstractTemplate
{
public:
Template(Strategy strategy)
{
this.strategy = strategy;
}
void algorithm()
{
strategy.A();
strategy.B();
}
private:
Strategy strategy;
}
class Template2 : AbstractTemplate
{
public:
Template2(Strategy strategy)
{
this.strategy = strategy;
}
void algorithm()
{
strategy.A();
strategy.B();
C();
}
private:
Strategy strategy;
void C()
{
//some stuff
strategy.A();
//some stuff
strategy.B();
}
}
The overlapping between Template and Template2 is minimal (considering you won't need subclasses, I think it's ok).

Related

Is this considered as good approach of using interface type in class

Say i have a code as follows
interface Interface1
{
void method1();
}
interface Interface2
{
void method2();
}
class ClassWithInterfaces : Interface1,Interface2
{
void method1(){}
void method2(){}
}
Now in my "manager" class i implement this as follows :
public OtherClass
{
Interface1 interface1;
Interface2 interface2;
public void someMethod()
{
ClassWithInterfaces classWithInterfaces = new ClassWithInterfaces();
interface1 = classWithInterfaces;
interface2 = classWithInterfaces
}
}
I don't feel that this is the right way to do it hovewer i can't come up with other solutions i can't use Dependency Injection Frameworks in my project if you ask about that. Can you tell me wheter apart from DI there is a better way of doing that?
Hello and welcome to Stack Overflow :-)
You don't have to use a framework in order to do DI. In fact, there are some languages that make it impossible to use a framework for DI - e.g., C++.
Any way, in your case, the proper way to do DI is like this:
interface Interface1
{
void method1();
}
interface Interface2
{
void method2();
}
interface Interface3 : Interface1, Interface2
{
void method1();
void method2();
}
class ClassWithInterfaces : Interface3
{
void method1(){}
void method2(){}
}
public OtherClass
{
Interface3 m_interface3;
OtherClass(Interface3 interface3)
{
m_interface3 = interface3;
}
public void someMethod()
{
m_interface3.method1();
m_interface3.method2();
}
}
// And now the usage:
public main()
{
ClassWithInterfaces classWithInterfaces = new ClassWithInterfaces();
OtherClass otherClass = new OtherClass(classWithInterfaces);
}

Using 'override' keyword

My code gives the following error:
error C3668: 'B::getData': method with override specifier 'override' did not override any base class methods
#include<iostream>
#include <tuple>
using namespace std;
class A {
public:
int a;
int getData() {
return a;
}
};
class B : public A {
public:
int b;
B() {
b = 100;
}
int getData() override {
return b;
}
};
int main() {
B b;
cout << b.getData() << endl;
}
Why does error occurs and how can I resolve it ??
Your original function in A has to be virtual to be overrided.
class A {
public:
int a;
virtual int getData() {
return a;
}
};
More info about override is here. And related: info on virtual and final

reference variables and objects

I wanted to know why this did not work, as in why didn't the compiler invoke the restart method within the computer class...
Consider the following scenario:
I have 3 classes as shown below:
public class Computer {
public int compStatus = 0; //0 means off, 1 means on.
public void turnOn(){
this.compStatus = 1;
}
public void turnOff(){
this.compStatus = 0;
}
public void restart(){
if(compStatus ==1){
System.out.println("Turning off");
compStatus = 0;
System.out.println("Turning on");
compStatus = 1;
System.out.println("Restart successful");
}
}
}
Now the sub-class:
public class Macintosh extends Computer {
public void openXCode(){
if(compStatus == 1){
System.out.println("XCode Compiler opened.");
}
else{
System.out.println("Mac is off.");
}
}
public void restart(){
System.out.println("Mac restarted");
}
}
The tester class:
public class CompTest {
public static void main(String[] args){
Computer testObj = new Macintosh();
testObj.turnOn();
testObj.restart(); ///ERROR HERE
}
}
I am aware that the compiler checks if the restart method is in the class of the reference variable 'Computer' not the class of the actual object at the other end of the reference 'macintosh'. So if what I have said is true, why is the restart method not invoked?
You have to call the base class method in order to actually restart. Your method is just hiding the base method. You should override the method and then call it base.restart to do what you want.

how to check the an interface type in c++/cli

i want to convert that line from c# to c++/cli
Idocobj is IPart
IPart is an interface and Idocobj is an object.Are there any way to do this conversion.
i used this code :
Idocobj->GetType() == IPart::typeid
but it dosen't work
You can use dynamic_cast to check for "is". Here is an example:
using namespace System;
namespace NS
{
public interface class IFoo
{
void Test();
};
public ref class Foo : public IFoo
{
public: virtual void Test() {}
};
public ref class Bar
{
public: virtual void Test() {}
};
}
template<class T, class U>
bool isinst(U u) {
return dynamic_cast< T >(u) != nullptr;
}
int main()
{
NS::Foo^ f = gcnew NS::Foo();
NS::Bar^ b = gcnew NS::Bar();
if (isinst<NS::IFoo^>(f))
Console::WriteLine("f is IFoo");
if (isinst<NS::IFoo^>(b) == false)
Console::WriteLine("f is not IFoo");
Console::ReadKey();
}
But normally, you never use "is".... you always want to do something with the check... so normally you should use "as" which directly mapps to dynamic_cast:
NS::IFoo^ ifoo = dynamic_cast<NS::IFoo^>(f);
if (ifoo != nullptr)
{
// Do something...
ifoo->Test();
}

OO inheritance question

Consider the following 2 methods:
class A{
void Method1(){
if(!something) return;
DoX();
DoY();
DoZ();
}
class B{
void Method2(){
if(!something) return;
DoX();
DoY();
DoP();
}
}
obviously a superclass could be written to avoid dry principle:
class Super{
virtual void Method(){
if(!something) return; //problem...
DoX();
DoY();
}
}
class A:Super{
override void Method(){
inherited Method();
DoZ();
}
}
class B:Super{
override void Method(){
inherited Method();
DoP();
}
}
The problem is the !something check where it would run out in the first example whereas in the second, it will run out of the super class's method, but do either DoZ() or DoP() in the derived class;
My question: What is the best way to solve this kind of problem? The one that comes to my hand is making the super class's method a function that returns bool
virtual bool Method(){ if(!something) return false;}
override bool Method(){ if(!inherited Method()) return;}
is this the best workaround?
How about:
class Super {
void Method() {
if (!something) return;
DoX();
DoY();
DoThingy();
}
abstract void DoThingy();
}
class A : Super {
override DoThingy() {
DoZ();
}
}
class B : Super {
override DoThingy() {
DoP();
}
}
Why not declaring another virtual method for DoP or Doz, you can wrap them if you want to keep them public with their respective names.
Like superclass :
virtual void wrapping(){};
Then each child :
void wrapping() { DoP(); }
void wrapping() { DoZ(); }
Don't know if I've been clear.
Another option: Keep the checks in the derived methods. Maybe a derived class might need a slightly different condition?
class Super{
virtual void Method(){
DoX();
DoY();
}
}
class A:Super{
override void Method(){
if(!something) return;
inherited Method();
DoZ();
}
}
class B:Super{
override void Method(){
if(!something) return;
inherited Method();
DoP();
}
}