首页 > 其他分享 >分解思想和抽象思想

分解思想和抽象思想

时间:2022-09-24 13:55:22浏览次数:55  
标签:p2 p1 思想 Point int 分解 抽象 100 mainForm

理解松耦合的设计思想。

理解设计原则比掌握某一个具体的设计模式更重要。

设计模式伴随的方法 —— 重构。

面向对象的设计模式 —— GOF 23 种为主干。


为什么要设计模式?解决不断重复的问题。可复用是面向对象的目标。94年《设计模式:可复用面向对象软件的基础》。

底层思维:向下,从机器底层微观上理解对象构造。1. 语言构造 2. 编译转换 3. 内存模型 4. 运行机制。 语言层面上的对象机制:封装,继承,多态。

抽象思维:向上,现实世界抽象为程序代码。1. 架构领域的架构模式; 2. 数据库领域的数据库模式;3. 组件封装; 4. 面向对象。 掌握好什么是“好的面向对象设计”。


解决复杂问题的方法:1.分解 2.抽象

分解

大问题分解为若干个小问题,复杂问题分解为若干个简单的问题。C语言,结构性语言是典型的分解思想。

代码示例:

#include <iostream>
#include <vector>

using namespace std;


/****************************/

class Point {
public:
    int x;
    int y;
};

// 直线
class Line
{
public:
    Point start;
    Point end;

    Line(const Point &start, const Point &end)
    {
        this->start = start;
        this->end = end;
    }
};

// 矩形
class Rect
{
public:
    Point leftUp;
    int width;
    int height;

    Rect(const Point& leftUp, int width, int height)
    {
        this->leftUp = leftUp;
        this->width = width;
        this->height = height;
    }
};


// 增加一个类
class Circle
{

};

/*************************/

enum class Shape
{
    Line,
    Rect,
    Circle,
};

class MainForm
{
public:
    MainForm() {}

    virtual void onm ouseDown(const int x, const int y)
    {
        p1.x = x;
        p1.y = y;
    }
    virtual void onm ouseUp(const int x, const int y, Shape shape)
    {
        p2.x = x;
        p2.y = y;

        switch (shape)
        {
        case Shape::Line:
        {
            lineVector.push_back(Line(p1, p2));
        }
        break;
        case Shape::Rect:
        {
            rectVector.push_back(Rect(p1, p2.x - p1.x, p2.y - p1.y));
        }
        break;
        // 改变
        case Shape::Circle:
        {
            // ....
        }
        break;
        default:
            break;
        }

    }
    virtual void OnPaint()
    {//刷新

        // 针对直线
        for (int i = 0; i < lineVector.size(); i++) {
            cout << "直线,起点(" << lineVector[i].start.x << "," << lineVector[i].start.y << ") " <<
                "终点(" << lineVector[i].end.x << "," << lineVector[i].end.y << ")" << endl;
        }

        cout << endl;

        // 针对矩形
        for (int i = 0; i < rectVector.size(); i++) {
            cout << "矩形,起点(" << rectVector[i].leftUp.x << "," << rectVector[i].leftUp.y << ")" <<
                "宽度:" << rectVector[i].width << "高度:" << rectVector[i].height << endl;
        }

        // 改变  针对圆
        for (;;) {
            // ....
            break;
        }
    }

private:
    Point p1;
    Point p2;

    // 数据结构存放
    vector<Line> lineVector;
    vector<Rect> rectVector;
    //改变
    vector<Circle> circleVector;
};

/*********************************/

int main()
{
    MainForm mainForm;

    // 画直线
    mainForm.OnMouseDown(0, 0);
    mainForm.OnMouseUp(100, 100, Shape::Line);
    mainForm.OnMouseDown(0, 0);
    mainForm.OnMouseUp(110, 110, Shape::Line);

    // 画矩形
    mainForm.OnMouseDown(10, 10);
    mainForm.OnMouseUp(1000, 1000, Shape::Rect);
    mainForm.OnMouseDown(100, 100);
    mainForm.OnMouseUp(1000, 1000, Shape::Rect);

    // 刷新
    mainForm.OnPaint();

    getchar();
    return 0;
}

输出:

直线,起点(0,0) 终点(100,100)
直线,起点(0,0) 终点(110,110)

矩形,起点(10,10)宽度:990高度:990
矩形,起点(100,100)宽度:900高度:900

如上,如果要新增一个画圆的功能,有很多地方需要去修改改变代码。

抽象

处理复杂性有一个通用的技术,即抽象。由于不能掌握全部的复杂对象,我们选择忽视它的非本质细节,而去处理泛化和理想化了的对象模型。

面向对象的设计模式,基本上是围绕着抽象这个概念去进行的。

代码示例:

#include <iostream>
#include <vector>
#include <math.h>

using namespace std;


/****************************/

class Point {
public:
    int x;
    int y;
};

// 接口
class IShape {
public:
    virtual void Draw() = 0;
    virtual ~IShape() { }
};

// 直线
class Line : public IShape
{
public:
    Point start;
    Point end;

    Line(const Point &start, const Point &end)
    {
        this->start = start;
        this->end = end;
    }

    // 自己画自己,类功能,各司其职。
    virtual void Draw() override
    {
        cout << "直线,起点(" << start.x << "," << start.y << ") " <<
            "终点(" << end.x << "," << end.y << ")" << endl;
    }
};

// 矩形
class Rect : public IShape
{
public:
    Point leftUp;
    int width;
    int height;

    Rect(const Point& leftUp, int width, int height)
    {
        this->leftUp = leftUp;
        this->width = width;
        this->height = height;
    }

    virtual void Draw() override
    {
        cout << "矩形,起点(" << leftUp.x << "," << leftUp.y << ")" <<
            "宽度:" << width << " 高度:" << height << endl;
    }
};


// 增加一个类
class Circle : public IShape
{
public:
    Point m_center;
    int R;
    Circle(const Point &center, int r) :m_center(center), R(r) {}

    virtual void Draw() override
    {
        cout << "圆形,圆心(" << m_center.x << "," << m_center.y << ")" <<
            "半径:" << R << endl;
    }
};

/*************************/

enum class ShapeType
{
    Line,
    Rect,
    Circle,
};

class MainForm
{
public:
    MainForm() {}
    virtual ~MainForm()
    {
        vector<IShape *>::iterator itor = m_ShapeVector.begin();
        while (itor != m_ShapeVector.end()) {
            delete (*itor);
            *itor = nullptr;
            itor = m_ShapeVector.erase(itor);
            itor++;
        }
    }

    virtual void onm ouseDown(const int x, const int y)
    {
        p1.x = x;
        p1.y = y;
    }
    virtual void onm ouseUp(const int x, const int y, ShapeType shape)
    {
        p2.x = x;
        p2.y = y;

        switch (shape)
        {
        case ShapeType::Line:
        {
            m_ShapeVector.push_back(new Line(p1, p2));
        }
        break;
        case ShapeType::Rect:
        {
            m_ShapeVector.push_back(new Rect(p1, p2.x - p1.x, p2.y - p1.y));
        }
        break;
        // 改变     后面这里用工厂模式,都不用修改
        case ShapeType::Circle:
        {
            double r = sqrt((p2.x - p1.x) *  (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
            m_ShapeVector.push_back(new Circle(p1, static_cast<int>(r)));
        }
        break;
        default:
            break;
        }

    }
    virtual void OnPaint()
    {//刷新
        for (int i = 0; i < m_ShapeVector.size(); i++) {
            m_ShapeVector[i]->Draw(); // 多态调用
        }
    }

private:
    Point p1;
    Point p2;

    // 数据结构存放
    vector<IShape *> m_ShapeVector;
};

/*********************************/

int main()
{
    MainForm mainForm;

    // 画直线
    mainForm.OnMouseDown(0, 0);
    mainForm.OnMouseUp(100, 100, ShapeType::Line);
    mainForm.OnMouseDown(0, 0);
    mainForm.OnMouseUp(110, 110, ShapeType::Line);

    // 画矩形
    mainForm.OnMouseDown(10, 10);
    mainForm.OnMouseUp(1000, 1000, ShapeType::Rect);
    mainForm.OnMouseDown(100, 100);
    mainForm.OnMouseUp(1000, 1000, ShapeType::Rect);

    // 画圆
    mainForm.OnMouseDown(100, 100);
    mainForm.OnMouseUp(1000, 1000, ShapeType::Circle);
    mainForm.OnMouseDown(101, 101);
    mainForm.OnMouseUp(1100, 1100, ShapeType::Circle);

    // 刷新
    mainForm.OnPaint();

    getchar();
    return 0;
}

输出:

直线,起点(0,0) 终点(100,100)
直线,起点(0,0) 终点(110,110)
矩形,起点(10,10)宽度:990 高度:990
矩形,起点(100,100)宽度:900 高度:900
圆形,圆心(100,100)半径:1272
圆形,圆心(101,101)半径:1412

抽象能够很好的应对引入一种变化的情况。复用性比较好,分解改的地方太多。

什么是好的软件设计?软件设计的金科玉律:复用!




参考:GeekBand

标签:p2,p1,思想,Point,int,分解,抽象,100,mainForm
From: https://www.cnblogs.com/huvjie/p/16725188.html

相关文章

  • c++ -- 做题思想
    二分思想:比较显然的就是求某一个确定的值,那么看看他是不是单调的,连续的.        其次就是,把问题通过二分来进行转化,之前的不好做,通过二分转化一......
  • Flatten(因式分解)
    题意给定\(N\)个正整数\(A_1,A_2,\dots,A_N\)。考虑正整数\(B_1,B_2,\dots,B_N\)满足如下条件:对于任意\(i,j\),有\(1\leqi<j\leqN,A_iB_i=A_jB_j\)。求\(B......
  • Java 抽象类
    抽象类概念抽象是对用户隐藏实现细节的过程,在Java中,抽象是使用抽象类和接口实现的。在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来......
  • C#:多态之虚方法、抽象类、接口、 类的序列化、MD5加密。
     (总的来说多态的作用便是解决代码的冗余问题,但代码更加具有可读性,更加的简洁)多态的第一种表现形式:虚方法usingSystem;usingSystem.Collections.Generic;usingSystem......
  • 流式思想概述和两种获取Stream流的方式
    流式思想概述整体来看,流式思想类似于工厂车间的“生产流水线”。 当需要对多个元素进行操作(特别是多步操作)的时候,考虑到性能及便利性,我们应该首先拼好一个“模型”步......
  • 深入理解CAS思想之原子操作类详解
    前置知识(CAS部分)(1)什么是CAS1.CAS(CompareAndSwap,比较并交换),通常指的是这样一种原子操作:针对一个变量,首先比较它的内存值与某个期望......
  • Java集合类思想(一)
    Java集合类思想(一)一、集合与数组数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用。集合(只能存储对象,对象类型可......
  • Java并发编程解析 | 基于JDK源码解析Java领域中并发锁之同步器Semaphore,CyclicBarrier
    苍穹之边,浩瀚之挚,眰恦之美;悟心悟性,善始善终,惟善惟道!——朝槿《朝槿兮年说》写在开头在并发编程领域,有两大核心问题:一个是互斥,即同一时刻只允许一个线程访问共享......
  • Java并发编程解析 | 基于JDK源码解析Java领域中ReentrantLock锁的设计思想与实现原理
    苍穹之边,浩瀚之挚,眰恦之美;悟心悟性,善始善终,惟善惟道!——朝槿《朝槿兮年说》写在开头在并发编程领域,有两大核心问题:一个是互斥,即同一时刻只允许一个线程访问共享......
  • Day7 Javase抽象接口以及异常的捕获和抛出
    Day7面向对象编程抽象abstract修饰抽象类,如果修饰方法就是抽象方法。抽象方法可以写方法体,然后让继承抽象类的类去重写抽象方法。java的类是单继承的,但是接口可以实现......