Thursday, July 22, 2010

Assignment Day 3

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.

18 comments:

  1. Soln to Case Study 4:

    Class 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();
    }

    ReplyDelete
  2. Forgot to return the page pointer from the function GetPageLayout().

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Had to remove the last post...

    This is perfect, do you know which pattern is it?

    ReplyDelete
  5. This link is quite useful:
    http://sourcemaking.com/design_patterns/abstract_factory

    ReplyDelete
  6. anurag::

    I 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();

    ReplyDelete
  7. solution to Case study 3;

    Very 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();

    }

    ReplyDelete
  8. Is there any class in wxWidgets that plays the role of Strategy while laying out controls on a panel?

    ReplyDelete
  9. Case study 3:-

    struct 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);
    }

    ReplyDelete
  10. 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.

    The 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?

    ReplyDelete
  11. //For case study 3

    class 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;
    }

    ReplyDelete
  12. I think case study 4 is MVC pattern i.e a combination of Factory and Strategy patterns

    ReplyDelete
  13. The other solution for Case Study 3 is using Functors (function objects).

    ReplyDelete
  14. Case Study3:
    Here'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.

    ReplyDelete
  15. This comment has been removed by the author.

    ReplyDelete
  16. class Point
    {
    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;
    }

    ReplyDelete