`
庄表伟
  • 浏览: 1159243 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

敲响OO时代的丧钟——OO设计原则批判

阅读更多

OO设计原则!

  这是很多开发资源网站必备的一个栏目、专题、至少也要转载一篇放在自己的网站上的东西。所有的程序员,如果你不开发面向对象的程序也就罢了——反正你已经落伍很久了,如果你要想开发OO程序,而竟然没有把那些OO设计原则熟读背诵,搞得滚瓜烂熟。那么你就完了,一个公司面试你的时候,问你:“你对SRP的理解是怎么样的?”,而你居然不知道SRP是什么,那么这家公司你也就别想进去了。作为OO程序员的《旧约圣经》(设计模式自然是《新约圣经》)他怎么就会那么神圣呢?

  介绍OO设计原则的文章很多,我在google上搜索了一下:“约有58,200项符合OO设计原则的查询结果”。真正能够介绍得透彻的,还真是没几个。正好我手边有一本Bob大叔的《UML for JAVA Programmers》那上面的介绍,在我看来,是最好的OO设计原则介绍之一了。另外一本不在手边的《敏捷软件开发 原则、模式与实践》也是Bob大叔的,还要详尽一些。如果要批判,自然要找这样的靶子来练!

 

  1、单一职责原则(SRP)

一个类只能因为一个原因而改变。

  “A class should have one, and only one, reason to change.”

   这个原则何等的简单,又是何等的模糊呢?什么叫做一个原因呢?我们来看下面这个类:


java代码: 

class User{
    private String name;
    private int age;
    public void setName(String name){
        this.name=name;
    }
    public void setAge(int age){
        this.age=age;
    }
}


请问,这个类是不是违反了SRP原则呢?设置用户的名字与设置用户的年龄,是一个原因,还是两个原因呢?Bob大叔在自己的书里举了一个例子,说明了违反SRP原则的情况,一个Employee类,包含了计算工资和扣税金额、在磁盘上读写自己、进行XML格式的相互转换、并且能够打印自己到各种报表。我说拜托啊大叔!一个类里的方法多到如此惊人的程度,自然是违反了SRP原则,但是我们要为它瘦身,该瘦到什么程度呢?按照大叔继续给出的自己的答案,它把计算工资和扣税金额的两个功能留给了Employee,其他的分离了出去。这个答案正确吗?员工的工资和税收是自己算的?还是有一个“财务部”对象来计算的呢?且不说那么扫兴的事情,就看看那个类图里分离出来的那几个类:

EmployeeXMLConverter、EmployeeDatabase、TaxReport、EmployeeReport、PayrollReport。这些类还需要有自己的内部数据吗?请注意,他们事实上都是通过接受Employee对象的内部数据而工作的,换句话说,这些所谓的类,根本就不是什么类,只不过是一个个用Class关键字包裹起来的函数库!当我们看到一个臃肿的Employee类,被拆成6个各不相同的类之后,内心自然升起了“房子打扫干净之后的喜悦”。但是,且慢!灰尘到哪里去了呢?当我们把一个类拆成6个类之后,那个原本的类自然已经遵守了SRP原则,然后新诞生的5个类,是不是也该遵守SRP原则呢?如果我们不能将一个原则应用于整个系统设计中的所有的对象,仅仅像小孩打扫卫生一样,把灰尘扫到隔壁房间,这剩下的事情,谁来处理呢?

好吧,我们不要这么严厉,毕竟这只是一个原则,追问太深似乎并不合适。我只想再搞清楚几个问题:按照SRP原则,C++中是不是一律不应该出现多重继承呢?按照SPR原则,Java中的一个类是不是一律不应该既继承一个类,又实现一个对象呢?一个简单的POJO,被动态增强之类的办法,添加出来的新的持久化能力,是不是也是违反SRP原则的呢?归根结蒂,我的问题是:按照SPR原则,我那些剩下的,但是又必须要找地方写的代码,究竟应该写在哪里呢?

 

  2、开放-封闭原则(OCP)

 软件实体(类、模块、方法等)应该允许扩展,不允许修改。

  “Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.”

  这个原则倒是非常的清楚明白,你不能改已经写好的代码,而应该扩展已有的代码!如何做到这一点呢?Bob大叔举了一个经典的例子:个人认为这个例子说明的是一个使用接口,隔离相互耦合的类的通常做法。而且这个做法不应叫做OCP,而应该叫做DIP。查了一下c2.com里的OCP的解释:

 

  In other words, (in an ideal world...) you should never need to change existing code or classes: All new functionality can be added by adding new subclasses and overriding methods, or by reusing existing code through delegation.

 

  但是在Bob大叔的OCP解释中,这个原则的具体实现被偷换了概念,从“鼓励多使用继承”,变成了“鼓励面向接口编程”。为什么?因为继承式OCP实践已经被证明会带来相当多的副作用,而面向接口编程又如何呢?我们在讨论DIP的时候再详细讨论吧。

 

  有一个在JavaEye的讨论的连接可以参考:对于OCP原则的困惑

 

  3、里斯科夫替换原则(LSP)

  子类型必须能够替代他们的基本类型。

  “Subtype must be substitutable for their base types.”

  对于这个问题,我都不用多说什么,只引用Bob大叔在c2上的一句话,以作为我的支持。

  “I believe that LSP is falsely believed by some few to be a principle of OO design, when really it isn't.”

 

  4、依赖关系倒置原则(DIP)

  A.上层模块应该不依赖于下层模块,它们都依赖于抽象。

  B.抽象不应该依赖于细节,细节应该依赖于抽象。

  “A. High level modules should not depend upon low level modules. Both should depend upon abstractions. ”

  “B. Abstractions should not depend upon details. Details should depend upon abstractions.”

  Bob大叔还补充说明了一下,这个原则的意思就又变了:更确切的说,不要依赖易变的具体类。也就是说,不容易变的具体类,还是可以依赖的。那么,当我们开始一次系统开放的时候,那些类是易变的具体类呢?那些类是不易变的具体类呢?怎么才算是易变、怎么才算是不易变呢?我们来看看代码吧:


java代码: 

class A{
    public void doA(){
    }
}

class B{
    A a=new A();
    a.doA();
}


   按照DIP原则,Class B依赖于一个具体实现类Class A,因此是可耻的!最起码你应该写成这样:


java代码: 

interface A{
    public void doA(){
    }
}

class AImpl implements A{
    public void doA(){
    }
}

class B{
    A a=new AImpl();
    a.doA();
}


  这样,AImpl和B都依赖于Interface A,很漂亮吧。还不够好,A a=new AImpl();还是很丑陋的,应该进一步隔离!A a=AFactory.createA();在AFactory里,再写那些见不得人的new AImpl();代码。然后呢?这还没完,更加Perfect的办法,是采用XML配置+动态IOC装配来得到一个A,这样,B就能够保证只知道这个世界上有一个Interface A,而不知道这个Interface A是从哪里来的了。这么做的理由是什么呢?有一个很吓人的理由:“如果A被B直接使用,那么对于A的任何改动,就会影响到B了。这就叫依赖,而这样的依赖会很危险!”

 

  我们来看看这颇有说服力的话,漏洞何在?A的变化有两种情况,一种是只修改A中的方法的内部实现,无论是直接使用A还是使用Interface A的某一个实现,这时候B的代码都不用改。另一种是修改了方法的调用接口,如果是直接使用A的Class B,就需要修改相关的调用代码,而如果是使用接口的呢?就需要同时修改Class B和Interface A。这样看来,采用接口方式,反而需要修改更多的代码!这使用接口的好处何在?

 

  5、接口隔离原则(ISP)

  客户端不应该依赖于自己不用的方法。

  “The dependency of one class to another one should depend on the smallest possible interface.”

 

  这个我就不说了!因为这个原则和SPR原则是矛盾的!就像合成复用原则(CRP)与LSP原则矛盾一样。

 

  关于这个批判,我昨天晚上只写了一半,今天算是虎头蛇尾的写完了。最后录一段Bob大叔的话,作为结尾:

 

  什么时候应该运用这些原则呢?首先要给您一个痛苦的告诫,让所有系统在任何时候都完全遵循所有原则是不明智的。

  运用这些原则的最好方式是有的放矢,而不是主动出击。在您第一次发现代码中有结构性的问题。或者第一次意识到某个模块受到另一个模块的改变的影响时,才应该来看看这些原则中是否有一条或者多条可以用来解决问题。

  ......

  找到得分点的最佳办法是大量写单元测试。如果能够先写测试,再写要测试的代码,效果会更好。

  让我来翻译一下上面的告诫。原则不是你可以用来预防问题的,而是当你已经陷入麻烦的时候,你可以停下来悔恨一下。至于解决之道,依然不是很清楚,因此,你需要写大量的单元测试。而且,大量的单元测试并不是帮你检查你的设计漏洞,而是帮你更真切的感受自己的设计是否正确。至于他究竟是不是正确,这就看个人自己的感觉了。更为惊人的是,在测试驱动开发的建议中,如何驱动开发的准则,竟然是循环的来自于OO设计原则的。

 

  这样的OO设计原则,就像老爸老妈给我们的人生教诲:“你要做好人啊”,别的什么都没说。而且我们还遇到了话都说不清的糊涂爹娘,怎么才算好人,不清楚,怎么才算坏人呢?被警察抓了,肯定就是坏人了。至于如何才能做得更好?自己体会吧。

 

(未完待续)

分享到:
评论
7 楼 wunglee 2007-01-07  
从上面对你的“颠覆”论据的一一化解来看,我个人认为,对于不成熟的想法,最好还是三思而后言,至少不要用“敲响OO时代的丧钟——OO设计原则批判”这样张狂的语句,不然,很容易招致众人对你产生“浅薄而不知天高地厚”的印象
6 楼 wunglee 2007-01-07  
5、接口隔离原则(ISP)
  “因为这个原则和SPR原则是矛盾的!”怎么理解?这么简单一句实在难以理解你“颠覆”的依据,我就不好进一步理论了
5 楼 wunglee 2007-01-07  
4、依赖关系倒置原则(DIP)
  你的唯一疑惑就在于“另一种是修改了方法的调用接口,如果是直接使用A的Class B,就需要修改相关的调用代码,而如果是使用接口的呢?就需要同时修改Class B和Interface A。这样看来,采用接口方式,反而需要修改更多的代码!这使用接口的好处何在?”这句话问题的关键在于我们没有搞清楚为什么需要使用抽象接口,抽象的目的是为了概括出“万变中的不变”,所以依赖于抽象的本质目的在于依赖于稳定,如果被依赖者是类,并且足够稳定,直接依赖它也没有什么不对,正是因为类的实现往往是不稳定和不可置换的,所以我们才要面向接口编程,如果接口本身都不稳定,那就没有必要使用DIP,直接调用类就好了!
4 楼 wunglee 2007-01-07  
3、里斯科夫替换原则(LSP)
   你能具体一点说明你反驳的理由吗?
3 楼 wunglee 2007-01-07  
2、开放-封闭原则(OCP)
  没有看出你对这个原则有什么反对意见,你仅仅认为Bob大叔对于解决OCP的方法是采用了DIP,那么,这个原则本身我们就是一致认同的了
2 楼 wunglee 2007-01-07  
1、单一职责原则:
    a、和你一样,不认同职责单一是指“类”,我觉得应该是“接口”,接口一定是指责单一的,但类不一定,它可以同时实现多个接口,由于客户永远只能面对接口,所以,用户永远看不到这个类,它实现的其他接口也和这个用户无关;
  b、职责的本质是外部引起它变化的原因,那么设置用户的名字与设置用户的年龄,是一个原因,还是两个原因呢?我个人认为,首先,这个“变化”针对的是对象的“行为”而不是“属性”,其次,对于两个“行为”,如果外部的原因同时引起它们产生变化,那就是一个原因,否则,就是两个原因;
1 楼 wunglee 2007-01-07  
你对这些原则的理解不够深入,所以才会有以上的疑惑,下面,我来帮助你解惑

相关推荐

    毕业设计物联网实战项目基于Eclipse Theia开源框架开发的物联网在线编程IDE.zip

    【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    Android毕设实战项目基于Android的医院挂号系统.zip

    【项目资源】: 适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    (源码)基于Python的KMeans和EM算法结合图像分割项目.zip

    # 基于Python的KMeans和EM算法结合图像分割项目 ## 项目简介 本项目结合KMeans聚类和EM(期望最大化)算法,实现对马赛克图像的精准分割。通过Gabor滤波器提取图像的多维特征,并利用KMeans进行初步聚类,随后使用EM算法优化聚类结果,最终生成高质量的分割图像。 ## 项目的主要特性和功能 1. 图像导入和预处理: 支持导入马赛克图像,并进行灰度化、滤波等预处理操作。 2. 特征提取: 使用Gabor滤波器提取图像的多维特征向量。 3. 聚类分析: 使用KMeans算法对图像进行初步聚类。 利用KMeans的聚类中心初始化EM算法,进一步优化聚类结果。 4. 图像生成和比较: 生成分割后的图像,并与原始图像进行比较,评估分割效果。 5. 数值比较: 通过计算特征向量之间的余弦相似度,量化分割效果的提升。 ## 安装使用步骤 ### 假设用户已经下载了项目的源码文件 1. 环境准备:

    HCIP第一次作业:静态路由综合实验

    HCIP第一次作业:静态路由综合实验

    毕设单片机实战项目基于stm32、esp8266和Android的智能家居系统-设备端.zip

    【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    统计学基于Python的Johnson-SU分布参数计算与优化:数据拟合及弹性网络参数优化方法实现(复现论文或解答问题,含详细可运行代码及解释)

    内容概要:本文详细介绍了Johnson-SU分布的参数计算与优化过程,涵盖位置参数γ、形状参数δ、尺度参数ξ和伸缩参数λ的计算方法,并实现了相应的Python代码。文中首先导入必要的库并设置随机种子以确保结果的可复现性。接着,分别定义了四个参数的计算函数,其中位置参数γ通过加权平均值计算,形状参数δ基于局部均值和标准差的比值,尺度参数ξ结合峰度和绝对偏差,伸缩参数λ依据偏态系数。此外,还实现了Johnson-SU分布的概率密度函数(PDF),并使用负对数似然函数作为目标函数,采用L-BFGS-B算法进行参数优化。最后,通过弹性网络的贝叶斯优化展示了另一种参数优化方法。; 适合人群:具有Python编程基础,对统计学和机器学习有一定了解的研究人员或工程师。; 使用场景及目标:①需要对复杂数据分布进行建模和拟合的场景;②希望通过优化算法提升模型性能的研究项目;③学习如何实现和应用先进的统计分布及优化技术。; 阅读建议:由于涉及较多数学公式和编程实现,建议读者在阅读时结合相关数学知识,同时动手实践代码,以便更好地理解和掌握Johnson-SU分布及其优化方法。

    TSP问题的3种智能优化方法求解(研究生课程《智能优化算法》结课大作业).zip

    TSP问题的3种智能优化方法求解(研究生课程《智能优化算法》结课大作业).zip

    毕业设计物联网实战项目基于Rtthread和MQTT搭建的物联网网关.zip

    【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    基于STM32F103C8T6的温湿度传感器(HAL库版),通过串口向电脑端反馈数据(附通过ESP8266-01s模块连接WIFI上传云平台的资料代码-固件库版本).zip

    【项目资源】: 单片机项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    自动发布Java项目(Tomcat)Shell脚本

    自动发布Java项目(Tomcat)Shell脚本

    (源码)基于webpack和Vue的前端项目构建方案.zip

    # 基于webpack和Vue的前端项目构建方案 ## 项目简介 本项目是基于webpack和Vue构建的前端项目方案,借助webpack强大的打包能力以及Vue的开发特性,可用于快速搭建现代化的前端应用。项目不仅完成了基本的webpack与Vue的集成配置,还在构建速度优化和代码规范性方面做了诸多配置。 ## 项目的主要特性和功能 1. 打包功能运用webpack进行模块打包,支持将scss转换为css,借助babel实现语法转换。 2. Vue开发支持集成Vue框架,能使用Vue单文件组件的开发模式。 3. 构建优化采用threadloader实现多进程打包,cacheloader缓存资源,极大提高构建速度开启热更新功能,开发更高效。 4. 错误处理与优化提供不同环境下的错误映射配置,便于定位错误利用webpackbundleanalyzer分析打包体积。

    Hands-On Large Language Models - Jay Alammar 袋鼠书 《动手学大语言模型》

    Hands-On Large Language Models - Jay Alammar 袋鼠书 《动手学大语言模型》PDF

    《基于YOLOv8的舞蹈动作分析系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    (源码)基于Arduino Feather M0和Raspberry Pi的传感器数据采集与监控系统.zip

    # 基于Arduino Feather M0和Raspberry Pi的传感器数据采集与监控系统 ## 项目简介 本项目是一个基于Arduino Feather M0和Raspberry Pi的传感器数据采集与监控系统。系统通过Arduino Feather M0采集传感器数据,并通过WiFi将数据传输到Raspberry Pi。Raspberry Pi运行BalenaOS,集成了MySQL、PHP、NGINX、Apache和Grafana等工具,用于数据的存储、处理和可视化。项目适用于环境监测、物联网设备监控等场景。 ## 项目的主要特性和功能 1. 传感器数据采集使用Arduino Feather M0和AM2315传感器采集温度和湿度数据。 2. WiFi数据传输Arduino Feather M0通过WiFi将采集到的数据传输到Raspberry Pi。

    《基于YOLOv8的音响设备识别系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    Android毕设实战项目这是一个android 图书管理系统.zip

    【项目资源】: 适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    毕业设计物联网实战项目基于智龙2.0开发板和窄带物联网模块BC95。操作系统为RTT2.1。.zip

    【项目资源】: 物联网项目适用于从基础到高级的各种项目,特别是在性能要求较高的场景中,比如操作系统开发、嵌入式编程和底层系统编程。如果您是初学者,可以从简单的控制台程序开始练习;如果是进阶开发者,可以尝试涉及硬件或网络的项目。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。

    (源码)基于Arduino的WiFi按钮项目.zip

    # 基于Arduino的WiFi按钮项目 ## 一、项目简介 本项目是一个基于ESP8266芯片的Arduino项目,主要实现WiFi连接、电压检测、LED灯控制以及向服务器发送POST请求等功能。通过简单的按钮操作,可以实现与服务器通信并获取相关信息,同时能检测电池电压并提示用户。 ## 二、项目的主要特性和功能 1. WiFi连接项目能够自动连接到指定的WiFi网络。 2. 电压检测通过ADC(模数转换器)检测电池电压,并在电压低于阈值时发出警告。 3. LED灯控制通过控制LED灯的亮灭来提示用户不同的状态信息(如连接成功、电压低等)。 4. 服务器通信项目可以向指定的服务器发送POST请求并处理返回的HTTP响应。 ## 三、安装使用步骤 1. 环境准备确保已安装Arduino IDE和ESP8266插件。 2. 下载源码下载项目的源码文件并解压。 3. 打开项目在Arduino IDE中打开解压后的main.cpp文件。

    scipy-0.10.1-cp26-cp26mu-manylinux1_x86_64.whl

    该资源为scipy-0.10.1-cp26-cp26mu-manylinux1_x86_64.whl,欢迎下载使用哦!

    计算机毕业设计;计算机毕设;Java毕业设计;小程序毕业设计

    计算机毕业设计;计算机毕设;Java毕业设计;小程序毕业设计;企业、旅游、党建、学校、人事、酒店、民宿、预约、考试、外卖、点餐、外贸、宠物、图书、销售、商城、就业、助农、仓储、交易、美食、博客、婚庆、二手、养老、医院、医疗、药品、招聘、考勤、宿舍、物流、租赁、公益等

Global site tag (gtag.js) - Google Analytics