0 面向过程 && 面向对象

        在软件开发中,面向过程(Procedure Oriented,PO)和面向对象(Object Oriented,OO)是两种主要的编程范式,它们有着不同的设计思想和实现方式。下面从多个维度对这两种开发方式进行对比分析:

软件开发方式编程思想

面向过程

(Procedure Oriented)

以过程为中心,分析解决问题的步骤,并用函数依次实现步骤。

面向对象

(Object Oriented)

以对象为中心,把构成问题的事物分解为各个对象,描述某个对象在整体解决方案中的行为。

用更生活化的比喻来解释这两种软件开发方式的区别:

面向过程:像做菜的食谱

  1. 做五子棋这道"菜",我们按步骤来:

    • 第一步:准备食材(初始化游戏)

    • 第二步:黑棋下锅(落黑子)

    • 第三步:看菜色(绘制画面)

    • 第四步:尝咸淡(判断输赢)

    • ...(重复类似步骤)

    • 最后上菜(输出结果)

  2. 就像照着食谱一步步操作,每个步骤都是一个独立的操作指令

面向对象:像餐厅的团队协作

  1. 把游戏分成几个"工作岗位":

    • 顾客(玩家):负责点单(输入落子位置)

    • 厨师(棋盘系统):负责做菜和摆盘(更新和显示棋盘)

    • 店长(规则系统):负责检查菜品质量(判断胜负)

  2. 每个岗位各司其职:

    • 顾客下单后告诉厨师

    • 厨师做好菜让店长检查

    • 店长确认没问题才上菜

更直观的对比:

面向过程面向对象
思维方式关注"怎么做"(步骤)关注"谁来做"(角色)
代码组织像写操作手册(第一步、第二步...)像分配工作任务(你负责A,他负责B)
修改维护改步骤会影响整个流程调整某个角色不影响其他部分
适合场景简单明确的任务(比如计算器)复杂的协作系统(比如游戏)

再直观的表述:

  • 面向过程就是:"先这样做,再那样做,最后这样做"

  • 面向对象就是:"小明你负责这个,小红你负责那个,你们配合完成"


1. 核心思想对比

面向过程

  • 以"过程/函数"为中心组织代码

  • 关注解决问题的步骤和流程

  • 数据与操作分离

  • 自顶向下逐步细化的设计方法

  • 典型代表:C语言

面向对象

  • 以"对象"为中心组织代码

  • 关注参与问题解决的实体及其关系

  • 数据与操作封装在一起

  • 自底向上构建对象模型的设计方法

  • 典型代表:C++、Python、Java

3. 优缺点对比

维度面向过程面向对象
代码复用函数级复用类级复用(继承/组合)
维护性修改可能影响多个函数修改通常局限在类内部
扩展性添加新功能需要修改流程通过继承/多态轻松扩展
复杂度管理适合简单流程适合复杂系统
执行效率

通常更高

(直接函数调用)

略低

(存在对象创建和方法调用开销)

适合场景

算法实现、系统程序、

数学计算

GUI开发、业务系统、大型应用

4. 设计模式对比

面向过程典型模式

  • 模块化编程

  • 分层架构

  • 状态机

面向对象典型模式

  • 创建型设计模式

  • 结构型设计模式

  • 行为型设计模式

5. 实际应用选择建议

选择开发方式时应考虑:

  1. 项目规模

    • 小型工具/脚本:面向过程可能更简单直接

    • 中大型系统:面向对象更有优势

  2. 性能要求

    • 高性能计算:偏向面向过程

    • 一般应用:面向对象足够

  3. 团队技能

    • 熟悉OO概念的团队:选择面向对象

    • 硬件/嵌入式开发:可能更适合面向过程

  4. 维护预期

    • 长期维护项目:面向对象更易维护

    • 一次性脚本:面向过程更快捷

  1. 不要拘泥于单一范式,根据实际问题选择合适的方案

  2. 初学者建议先掌握面向过程,再学习面向对象

  3. 大型项目通常采用面向对象为主,关键算法部分可能用面向过程实现

  4. 理解两种范式的本质差异比死记硬背概念更重要

两种范式各有所长,优秀的开发者应该根据具体场景灵活选择,甚至混合使用。在实际项目中,经常可以看到面向对象的外层架构包裹着面向过程的核心算法实现,这种组合往往能发挥各自的优势。


为了更通俗易懂地解释两者的差异,此处以五子棋游戏为例。

6.面向过程的设计

使用C语言编写:五子棋游戏

1) 分析解决方法,将其分为九个步骤:开始游戏、落黑子、绘制画面、判断输赢、落白子、绘制画面、判断输赢、返回步骤、输出结果:

2)用函数依次实现上述步骤,并在主函数内依次调用各个步骤的函数。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define SIZE 15  // 棋盘大小 15x15
#define EMPTY 0
#define BLACK 1
#define WHITE 2

// 全局变量
int board[SIZE][SIZE];  // 棋盘
int currentPlayer;      // 当前玩家

// 函数声明
void initGame();
void placeStone(int player);
void drawBoard();
bool checkWin(int x, int y);
void gameLoop();
void announceResult(int winner);

int main() {
    initGame();
    gameLoop();
    return 0;
}

// 1. 开始游戏 - 初始化棋盘和玩家
void initGame() {
    // 初始化棋盘
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            board[i][j] = EMPTY;
        }
    }
    
    // 黑棋先行
    currentPlayer = BLACK;
    
    printf("五子棋游戏开始!\n");
}

// 2. 落黑子 / 5. 落白子
void placeStone(int player) {
    int x, y;
    
    while (1) {
        printf("%s方落子,请输入坐标(行 列, 范围1-%d): ", 
               player == BLACK ? "黑" : "白", SIZE);
        scanf("%d %d", &x, &y);
        
        // 转换为数组索引
        x--;
        y--;
        
        // 检查输入是否合法
        if (x >= 0 && x < SIZE && y >= 0 && y < SIZE && board[x][y] == EMPTY) {
            board[x][y] = player;
            break;
        } else {
            printf("无效的落子位置,请重新输入!\n");
        }
    }
    
    // 检查是否获胜
    if (checkWin(x, y)) {
        drawBoard();
        announceResult(player);
        exit(0);
    }
}

// 3. 绘制画面 / 6. 绘制画面
void drawBoard() {
    // 清屏
    system("clear || cls");
    
    // 打印列号
    printf("   ");
    for (int i = 1; i <= SIZE; i++) {
        printf("%2d ", i);
    }
    printf("\n");
    
    // 打印棋盘
    for (int i = 0; i < SIZE; i++) {
        printf("%2d ", i + 1);  // 行号
        for (int j = 0; j < SIZE; j++) {
            if (board[i][j] == BLACK) {
                printf(" ● ");
            } else if (board[i][j] == WHITE) {
                printf(" ○ ");
            } else {
                printf(" + ");
            }
        }
        printf("\n");
    }
}

// 4. 判断输赢 / 7. 判断输赢
bool checkWin(int x, int y) {
    int player = board[x][y];
    int directions[4][2] = {{1, 0}, {0, 1}, {1, 1}, {1, -1}}; // 四个方向: 水平, 垂直, 对角线, 反对角线
    
    for (int d = 0; d < 4; d++) {
        int count = 1;  // 当前棋子已经算一个
        
        // 正向检查
        int nx = x + directions[d][0];
        int ny = y + directions[d][1];
        while (nx >= 0 && nx < SIZE && ny >= 0 && ny < SIZE && board[nx][ny] == player) {
            count++;
            nx += directions[d][0];
            ny += directions[d][1];
        }
        
        // 反向检查
        nx = x - directions[d][0];
        ny = y - directions[d][1];
        while (nx >= 0 && nx < SIZE && ny >= 0 && ny < SIZE && board[nx][ny] == player) {
            count++;
            nx -= directions[d][0];
            ny -= directions[d][1];
        }
        
        if (count >= 5) {
            return true;
        }
    }
    
    return false;
}

// 8. 返回步骤 - 游戏主循环
void gameLoop() {
    while (1) {
        drawBoard();
        placeStone(currentPlayer);
        
        // 切换玩家
        currentPlayer = (currentPlayer == BLACK) ? WHITE : BLACK;
    }
}

// 9. 输出结果
void announceResult(int winner) {
    printf("\n恭喜%s方获胜!\n", winner == BLACK ? "黑" : "白");
}

代码说明
  1. 程序结构

    • 按照面向过程的设计思路,将游戏逻辑划分为9个步骤对应的函数

    • 使用全局变量存储棋盘状态和当前玩家

  2. 主要函数

    • initGame(): 初始化游戏,清空棋盘,设置黑棋先行

    • placeStone(): 处理玩家落子逻辑,包括输入验证和胜负检查

    • drawBoard(): 绘制当前棋盘状态,显示黑白棋子位置

    • checkWin(): 检查落子后是否形成五子连珠

    • gameLoop(): 游戏主循环,交替处理黑白双方落子

    • announceResult(): 宣布游戏结果

  3. 游戏规则

    • 黑棋先行,双方轮流落子

    • 先形成五子连珠的一方获胜

    • 支持水平、垂直和对角线方向的连珠判断

  4. 使用说明

    • 编译后运行程序

    • 按照提示输入落子坐标(行 列),范围1-15

    • 游戏会自动判断胜负并结束

 


 

7.面向对象的设计

使用Python语言编写:五子棋游戏

1)将五子棋游戏分为3个对象:黑白双方、棋盘系统(负责绘制画面)、规则系统(负责判断输赢):

2)为所有对象赋予属性、行为。第一类对象(黑白双方)负责接受用户输入,并将棋子布局的变化告知第二类对象(棋盘系统)。第二类对象(棋盘系统)接收变化信息后,将其显示于屏幕,同时利用第三类对象(规则系统)对棋局进行判定。

import numpy as np


class Player:
    """玩家类,负责接受用户输入并落子"""

    def __init__(self, color, name):
        self.color = color  # 玩家颜色 (1:黑, 2:白)
        self.name = name  # 玩家名称

    def make_move(self, board):
        """玩家落子"""
        while True:
            try:
                # 获取玩家输入
                move = input(f"{self.name}方落子,请输入坐标(行 列, 范围1-15): ")
                x, y = map(int, move.split())

                # 转换为数组索引并验证
                if 1 <= x <= 15 and 1 <= y <= 15 and board.is_empty(x - 1, y - 1):
                    return x - 1, y - 1  # 返回0-based索引
                else:
                    print("无效的落子位置,请重新输入!")
            except ValueError:
                print("输入格式错误,请按'行 列'格式输入!")


class Board:
    """棋盘系统,负责绘制画面和记录棋子位置"""

    def __init__(self):
        self.grid = np.zeros((15, 15), dtype=int)  # 15x15空棋盘
        self.black_symbol = '●'
        self.white_symbol = '○'
        self.empty_symbol = '+'

    def is_empty(self, x, y):
        """检查位置是否为空"""
        return self.grid[x, y] == 0

    def place_stone(self, x, y, color):
        """在指定位置放置棋子"""
        self.grid[x, y] = color

    def display(self):
        """绘制棋盘"""
        # 清屏
        print("\033c", end="")

        # 打印列号
        print("   " + " ".join(f"{i:2}" for i in range(1, 16)))

        # 打印棋盘内容
        for i in range(15):
            print(f"{i + 1:2} ", end="")
            for j in range(15):
                if self.grid[i, j] == 1:  # 黑棋
                    print(f" {self.black_symbol} ", end="")
                elif self.grid[i, j] == 2:  # 白棋
                    print(f" {self.white_symbol} ", end="")
                else:  # 空位
                    print(f" {self.empty_symbol} ", end="")
            print()


class RuleSystem:
    """规则系统,负责判断输赢"""

    @staticmethod
    def check_win(board, x, y):
        """检查是否五子连珠"""
        color = board.grid[x, y]
        directions = [(1, 0), (0, 1), (1, 1), (1, -1)]  # 四个检查方向

        for dx, dy in directions:
            count = 1  # 当前棋子已经算一个

            # 正向检查
            nx, ny = x + dx, y + dy
            while 0 <= nx < 15 and 0 <= ny < 15 and board.grid[nx, ny] == color:
                count += 1
                nx += dx
                ny += dy

            # 反向检查
            nx, ny = x - dx, y - dy
            while 0 <= nx < 15 and 0 <= ny < 15 and board.grid[nx, ny] == color:
                count += 1
                nx -= dx
                ny -= dy

            if count >= 5:
                return True
        return False


class GomokuGame:
    """五子棋游戏主类"""

    def __init__(self):
        self.board = Board()
        self.rule_system = RuleSystem()
        self.players = [
            Player(1, "黑"),
            Player(2, "白")
        ]
        self.current_player = 0  # 当前玩家索引

    def play(self):
        """开始游戏"""
        print("五子棋游戏开始!")

        while True:
            # 显示棋盘
            self.board.display()

            # 当前玩家落子
            player = self.players[self.current_player]
            x, y = player.make_move(self.board)
            self.board.place_stone(x, y, player.color)

            # 检查是否获胜
            if self.rule_system.check_win(self.board, x, y):
                self.board.display()
                print(f"\n恭喜{player.name}方获胜!")
                break

            # 切换玩家
            self.current_player = 1 - self.current_player


if __name__ == "__main__":
    game = GomokuGame()
    game.play()
设计说明
  1. 类结构设计

    • Player类:代表玩家,负责接受输入并落子

      • 属性:颜色、名称

      • 行为:获取落子位置

    • Board类:代表棋盘系统,负责维护和显示棋盘状态

      • 属性:棋盘网格、棋子符号

      • 行为:放置棋子、显示棋盘、检查位置是否为空

    • RuleSystem类:代表规则系统,负责判断胜负

      • 行为:检查是否五子连珠

    • GomokuGame类:游戏主类,协调各对象交互

  2. 对象协作流程

    1. 游戏初始化时创建棋盘、规则系统和玩家对象

    2. 当前玩家通过make_move()获取落子位置

    3. 棋盘系统接收落子并更新状态

    4. 规则系统检查是否满足胜利条件

    5. 如果没有获胜,切换玩家继续游戏

  3. 扩展性

    • 可以轻松添加AI玩家(只需继承Player类并实现不同的make_move方法)

    • 可以修改RuleSystem实现不同的规则变体

    • 可以扩展Board类支持不同大小的棋盘

  4. 使用说明

    • 运行程序后,黑白双方轮流输入落子坐标

    • 输入格式为"行 列"(范围1-15)

    • 先形成五子连珠的一方获胜

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值