C语言实现OOP 版本2
写版本2的原因,还是发现在不同的具体图形模块里发现了重复的release代码,这是坏味道,所以还是决定消除这些重复代码,DRY!
shape.h
#ifndef SHAPE_H #define SHAPE_H typedef struct shape_t { void *shapeData; void (*area)(void *); void (*release)(void *); }Shape; void release(void *shape); #endif
shape.c
#include <stdlib.h> #include "shape.h" void release(void *shape) { free(((Shape*)shape)->shapeData); free(shape); }
circle.h
#ifndef CIRCLE_H #define CIRCLE_H typedef struct { double r; }CircleData; typedef struct { void *shapeData; void (*area)(void *); void (*release)(void *); }Circle; Circle *makeCircle(double r); #endif
circle.c
#include <assert.h> #include <stdlib.h> #include <stdio.h> #include "shape.h" #include "circle.h" const double PI = 3.14159; static void area(void *shape) { Circle *_circle = (Circle *)shape; CircleData* data = (CircleData*)_circle->shapeData; printf("the circle area is %f \n", data->r * data->r * PI); } /* static void release(void *shape) { Circle *_circle = (Circle *)shape; CircleData* data = (CircleData*)_circle->shapeData; free(data); free(_circle); } */ Circle *makeCircle(double r) { CircleData* circleData = (CircleData*)malloc(sizeof(CircleData)); Circle* circle = (Circle*)malloc(sizeof(Circle)); assert(circleData != NULL); assert(circle != NULL); assert(r > 0); circleData->r = r; circle->shapeData = circleData; circle->area = &area; circle->release = &release; return circle; }
square.h
#ifndef SQUARE_H #define SQUARE_H typedef struct { double x; double y; }SquareData; typedef struct { void *shapeData; void (*area)(void *); void (*release)(void *); }Square; Square *makeSquare(double x, double y); #endif
square.c
#include <assert.h> #include <stdlib.h> #include <stdio.h> #include "shape.h" #include "square.h" static void area(void *shape) { Square *square = (Square *)shape; SquareData* data = (SquareData*)square->shapeData; printf("the square area is %f \n", data->x * data->y); } /* static void release(void *shape) { Square *square = (Square *)shape; SquareData* data = (SquareData*)square->shapeData; free(data); free(square); } */ Square *makeSquare(double x, double y) { SquareData* squareData = (SquareData*)malloc(sizeof(SquareData)); Square* square = (Square*)malloc(sizeof(Square)); assert(squareData != NULL); assert(square != NULL); assert(x > 0 && y > 0); squareData->x = x; squareData->y = y; square->shapeData = squareData; square->area = &area; square->release = &release; return square; }
main.c 发现没有,尽管内部进行了调整,这些的代码丝毫没变!重构就应该这样,内部的调整不太涉及到client代码,除非真的决定修改接口,修改接口内部应该优先于调整接口
#include <stdio.h> #include "shape.h" #include "circle.h" #include "square.h" void printShapeArea(Shape **shape,int length) { int i=0; for(i=0;i<length;i++) { shape[i]->area(shape[i]); shape[i]->release(shape[i]); } } int main() { Shape *p[3] = {(Shape*)makeCircle(3.2),(Shape*)makeCircle(3.2),(Shape*)makeSquare(3.1,4)}; printShapeArea(p,3); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2012-07-27 python:可变参数与apply
2012-07-27 重构实例1:抽取冗余代码 - 未通过测试而进行的第二次修正