Case Study 3
•A curve is defined by some finite points, each point is represented by an x and y value. Assume that the curve has about 1000 points
User wants to find points that meet the following criteria
–x> 2y
–y = x
– Y > x^2
–X is even
–Y is odd
–X= some value
–Y= some value
–X = some value + some other value * 5
In future we can have many more such operations to be performed on the curve.
Come up with the class diagrams or class declarations
-------------------------
Case Study 4
•I am working on an Imposition application where I have to provide some default layouts to the user that will place images on a page. The default layouts can be like lay all the images horizontally, vertically or in a table like format with n number of rows and m number of column or in a diagonal or around the perimeter of the page. Please come up with classes and their interaction. Assume that our graphics team is very creative and will come up with more of such layouts in future. Focus on Page and layouts.
Soln to Case Study 4:
ReplyDeleteClass Layout
{
public:
void Draw() = 0;
};
Class HorizontalLayout: public Layout
{
public:
void Draw()
{
cout << "Draw Horizontally";
}
};
Class VerticalLayout: public Layout
{
public:
void Draw()
{
cout << "Draw Vertically";
}
};
Class Page
{
Private :
Layout *m_layout;
public:
Page(Layout *layout)
{
m_layout = layout;
}
SetLayout(Layout *layout)
{
m_layout = layout;
}
void Draw()
{
m_layout->Draw()
}
};
class PageLayoutFactory
{
public:
static Page * GetPageLayout(wxString layoutType);
};
static Page * PageLayoutFactory::GetPageLayout(string layoutType)
{
Page *page = new Page;
if (layoutType.CmpNoCase("Horizontal") == 0)
{
HorizontalLayout *horizontal_layout = new HorizontalLayout;
Page->SetLayout(horizontal_layout);
}
else if(layoutType.CmpNoCase("Vertical") == 0)
{
VerticalLayout *vertical_layout = new VerticalLayout;
Page->SetLayout(vertical_layout);
}
}
main()
{
Page * page1 = PageLayoutFactory::GetPageLayout("Horizontal");
page1->Draw();
Page * page2 = PageLayoutFactory::GetPageLayout("Vertical");
page2->Draw();
}
Forgot to return the page pointer from the function GetPageLayout().
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHad to remove the last post...
ReplyDeleteThis is perfect, do you know which pattern is it?
Strategy Pattern
ReplyDeleteThis link is quite useful:
ReplyDeletehttp://sourcemaking.com/design_patterns/abstract_factory
anurag::
ReplyDeleteI was about to provide some solution for Case study 4and found Alka solution which is very good and I don't need to provide any thing new except one point which I may do diffrently i.e . PageLayoutFactory class , I think over here we are making creation of two completely diffrent objects tightly coupled , basically we always creating page on the basis of layout which I think should be independent of each other and we should use SetLayout method ( or some other registration method) directly from the client and set in the page object.
I will create separate factories for page and Layout say namely "PageFactory" and 'LayoutFactory" and then call it like this in main..
Page * page1 = PageFactory.GetInstance("some value")
Layout * layout1 = Layoutfactory.getInstance("some Value")
Page1->Setlayout(layout1).
Page1->Draw();
solution to Case study 3;
ReplyDeleteVery brief may not be clear at places, idea is to provide the structure how this will work.
Using Visitor pattern::
struct point
{
int x;
int y;
};
typedef vector Listpoints;
class ICurve
{
public:
virtual void accept(class IVisitor*) = 0;
};
class Curve: public ICurve
{
public:
void Draw()
{
cout << "Draw";
}
void accept(Visitor *v)
{
v->visit(this);
}
private:
Listpoints m_listpoints;
};
class IVisitor
{
public:
virtual void visit(Curve*) = 0;
};
class X2YVisitor: public IVisitor
{
public:
X2YVisitor()
{
m_listpoints.clear();
}
void visit(Curve*)
{
// algo to check if x == 2y with collection of point inside curve
// if matches insert it into the visitors colection of points
m_listpoints.push_back(point);
}
Listpoints & getPoints()
{
// loop through collection and display all the points matching the criteria
}
private:
Listpoints m_listpoints;
};
class XYVisitor: public IVisitor
{
public:
XYVisitor: ()
{
m_listpoints.clear();
}
void visit(Curve*)
{
// algo to check if x == 2y with collection of point inside curve
// if matches insert it into the visitors colection of points
m_listpoints.push_back(point);
}
Listpoints & getPoints()
{
// loop through collection and display all the points matching the criteria
}
private:
Listpoints m_listpoints;
};
int main()
{
X2YVisitor X2Yoperation;
XYVisitor XYoperation;
ICurve * pCurve = new Curve();
// curve setting some points inside curve
pCurve->accept( &X2Yoperation);
pCurve->accept( &XYoperation);
X2Yoperation.getPoints();
XYoperation.getPoints();
}
Is there any class in wxWidgets that plays the role of Strategy while laying out controls on a panel?
ReplyDeletewxSizer
ReplyDeleteCase study 3:-
ReplyDeletestruct Point{
int x;
int y;
};
class Curve{
Point pts[1000];
public:
Curve(){};
class Iterator{
Point *pPoint;
public:
Iterator(Point *p){
pPoint = p;
};
bool operator!=(const Iterator &lhs) const{
//provide implentation
}
Point operator*(){
return *pPoint;
}
Iterator& operator++(){
pPoint++;
return (*this);
}
}
Iterator begin(){
return Iterator(pts);
};
Iterator end(){
return Iterator(pts + 100);
};
};
//methods to to perform operations on the curve.
void minusxgt2y(Curve &cr){
Curve::Iterator curveIter;
for(curveIter=cr.begin();curveIter!=cr.end();++curveIter){
Point p=*curveIter;
//process point p
}
};
main(){
Curve cr;
minusxgt2y(Curve &cr);
}
I second Anurag's comment on the solution for Case Study#4. The page and layout need not be tightly coupled. In my design the Factory would be just for the Layout hierarchy.
ReplyDeleteThe creation of page objects would be based on user request and may be made directly in main.
Also, the draw function should be virtual shouldn't it?
//For case study 3
ReplyDeleteclass Point
{
private:
int m_x,m_y;
public:
int GetX(){ return m_x;}
int GetY(){ return m_y;}
};
/* For simple conditions CompareXYValue
should be refactored*/
class CompareXY
{
public:
CompareXY(){};
virtual bool CompareXYValue(Point & p)
{
return (p.GetX() == p.GetY());
}
}
/* For complex conditions dervie a class from CompareXY
and override CompareXYValue*/
class myCompareXY public: CompareXY
{
public:
myCompareXY(){};
bool CompareXYValue(Point &p)
{
return ((p.GetX() == (2 * p.GetY()))
}
}
class Curve
{
private:
vector m_vecPoints;
public:
Curve(){ };
Initilize();
void ListPoints(CompareXY *p)
{
for(size_t i = 0; i < m_vecPoints.size(); i++)
{
if(p->CompareXYValue(m_vecPoints[i]))
{
cout<<m_vecPoints[i];
}
}
}
}
int main()
{
Curve myCurve;
myCurve.Initilize();
CompareXY *p = new myCompareXY();
myCurve.ListPoints(p);
return 0;
}
I think case study 4 is MVC pattern i.e a combination of Factory and Strategy patterns
ReplyDeleteThe other solution for Case Study 3 is using Functors (function objects).
ReplyDeleteCase Study3:
ReplyDeleteHere's my thought.
class Point
{
int x;
int y;
};
class Curve
{
vector m_vec;
Draw()
SetPoints()
};
class PointAlgos
{
static vector FindPointsXGreaterY(vector m_vec)
{
}
static vector FindPointsXEven()
{
}
static vector FindPointsYOdd()
{
}
};
User:
vector myVec
Curve s(myVec);
.
.
.
vector curvPoints = s.getCurvePoints();
PointAlgos::FindPointsXGreaterY(curvPoints);
PointAlgos::FindPointsXEven((curvPoints);
I want to understand why Anurag arrived at using Visitor.
Anurag can you provide some reasons on using visitor and not doing the way I've done it.
This comment has been removed by the author.
ReplyDeleteclass Point
ReplyDelete{
public:
Point(int x, int y);
int getX() {return x;}
int getY() {return y;}
private:
int m_x,m_y;
};
std::vector m_curve;
class PointFunc
{
public:
virtual bool CheckPoint(Point &p) = 0;
};
class XGreater2Y:public PointFunc
{
public:
virtual bool CheckPoint(Point &p)
{
if(p.getX() > (2*p.getY()))
return true;
return false;
}
}
class XequalsY:public PointFunc
{
public:
virtual bool CheckPoint(Point &p)
{
if(p.getX() == p.getY())
return true;
return false;
}
};
class YgreaaterXPow2:public PointFunc
{
public:
virtual bool CheckPoint(Point &p)
{
if(p.getY() > (p.getY()*p.getY()))
return true;
return false;
}
};
class ComparePointMgr
{
public:
void RegisterPointFunc(PointFunc *func)
{
m_point_func_list.push_back(func);
}
bool CurveMatchesPoints(std::vector &curve)
{
std::vector::iterator p_itr = curve.begin();
while(p_itr != curve.end())
{
Point p = *p_itr;
std::vector::iterator itr = m_point_func_list.begin();
while(itr != m_point_func_list.end())
{
PointFunc *func = *itr;
if(func->CheckPoint(p))
{
//add to list
}
++itr;
}
++p_itr;
}
}
private:
std::vector m_point_func_list;
}