当前位置: 首页 > news >正文

大型平台网站开发抚顺市 网站建设

大型平台网站开发,抚顺市 网站建设,有什么网站可以做浏览单,镇江网友之家百姓话题前言 在面向对象编程中#xff0c;有一条非常经典的设计原则#xff1a;组合优于继承#xff0c;多用组合少用继承。 为什么不推荐使用继承#xff1f; 组合比继承有哪些优势#xff1f; 如何判断该用组合还是继承#xff1f; 为什么不推荐使用继承#xff1f; 继承…前言 在面向对象编程中有一条非常经典的设计原则组合优于继承多用组合少用继承。 为什么不推荐使用继承 组合比继承有哪些优势 如何判断该用组合还是继承 为什么不推荐使用继承 继承是面向对象的四大特性之一用来表示 is-a 的关系可以解决代码复用问题。虽然继承有诸多作用但继承层次太深、过于复杂会影响到代码的可维护性。所以对弈是否应该在项目中使用继承有很多争议很多人觉得继承是一种反模式应尽量少用。为什么会有这样的争议我们聚类自来说明下。 假设我们要设计一个关于鸟的类。我们将“鸟类”这样一个抽象的事物概念定义为一个抽象类 AbstractBird。所有细分的鸟比如麻雀、鸽子、乌鸦等都继承这个类。 大部分鸟可以飞那可以在 AbstractBird 抽象类里面定义一个 fly() 方法吗答案是否定的。尽管大部分鸟会飞但也有特例比如鸵鸟就不会飞。鸵鸟继承具有 fly() 方法的父类就具有了“飞”这样的行为这显然不符合我们的对现实世界的认识。当然你可能会说我在鸵鸟这个子类中重写 fly() 方法让它们抛出 UnSupportedMethodException 异常不就可以了吗代码如下 public class AbstractBird {// 省略其他属性和方法...public void fly() { /*...*/ } }public class Ostrich extends AbstractBird {// 省略其他属性和方法...Overridepublic void fly() {throw new UnSupportedMethodException(I cant fly.);} }这种设计思路虽然可以解决问题但不够优美。因为除了鸵鸟不会飞的鸟类还有很多如企鹅。对于这些不会飞的鸟都要重写 fly() 方法抛出异常。这样的设计一方面增加了编码的工作量另一方面也违背了我们之后要讲解的最小知识原则最少知识原则也叫迪米特法则暴露不该暴露的接口给外部增加了类适用过程中被误用的概率。 可能你又会说可以给 AbstractBird 在派生出两个更加细分的抽象类会飞的鸟 AbstractFlyableBird 和不会飞的鸟AbstractUnFlyableBird让会飞的鸟继承 AbstractFlyableBird 不会飞的鸟继承AbstractUnFlyableBird这不就可以了吗 上图中可以看出继承关系变成了三层。不过整体上来讲目前的继承关系还比较简单层次比较浅。如果在加点难度在刚刚的场景中我们只关注鸟会不会非。但是如果我们还关注“鸟会不会叫”这个时候又该如何设计类之间的继承关系呢 是否会飞是否会叫连个行为搭配起来会产生四种情况 会飞会叫会飞不会叫不会飞会叫不会飞不会叫 沿用上面的思路那么还需要再定义四个抽象类AbstractFlyableTweetableBird、AbstractFlyableUnTweetableBird、AbstractUnFlyableTweetableBird、AbstractUnFlyableUnTweetableBird。 如果还没还要关注是否会下蛋那估计组合就要爆炸了。类的继承层次会越来越深、继承关系会越来越复杂。这会导致两个方面的问题 一方面代码的可读性变差。我们要搞清楚类具有哪些属性和方法必须阅读父类的代码、父类的父类的代码…一直追溯到顶层父类的代码。另一方面也破坏了类的封装特性将父类的实现细节暴露给了子类。子类的实现依赖父类的实现两者高度耦合一旦父类代码修改就影响所有子类的逻辑。 所以继承最大的问题在于继承层次过深、继承关系过于复杂会影响到代码的可读性和可维护性。这也是为什么不推荐使用继承的原因。 那这个问题又该如何解决呢 组合比继承有哪些优势 实际上我们可以利用组合composition、接口、委托类delegation三个技术手段一块来解决刚刚继承存在的问题。 接口表示具有某些特性的行为。针对会飞这样的特性可以定义一个 Flyable 接口只会让会飞的鸟去实现这个接口。对于会叫、会下蛋这些行为我们可以类似的定义 Tweetable 接口和 EggLayable 接口。下面是具体的例子。 public interface Flyable {void fly(); }public interface Tweetable {void tween(); }public interface EggLayable{void layEgg(); }// 鸵鸟 public class Ostrich implements Tweetable, EggLayable {// 其他属性方法省略...Overridepublic void tween() { /*...*/ }Overridepublic void layEgg() { /*...*/ } }// 麻雀 public class Sparrow implements Flyable, Tweetable, EggLayable {// 其他属性方法省略...Overridepublic void fly() { /*...*/ }Overridepublic void tween() { /*...*/ }Overridepublic void layEgg() { /*...*/ } }只是只生命接口不定义实现的话每个会下蛋的鸟都要实现一遍 layEgg() 方法并且实现逻辑一样这会导致代码重复。 我们可以针对这三个接口再定义三个实现类分别是 实现 Flyable 的 FlyAbility 类实现 Tweetable 的 TweetAbility 类实现 EggLayable 的 EggLayAbility 类 然后通过组合和委托技术来消除代码重复。具体代码如下 public interface Flyable {void fly(); }public class FlyAbility implements Flyable {// 其他属性方法省略...Overridepublic void fly() { /*...*/ } } // 省略Tweetable/TweetAbility/EggLayable/EggLayAbilitypublic class Ostrich implements Tweetable, EggLayable {private TweetAbility tweetAbility new TweetAbility();private EggLayAbility eggLayAbility new EggLayAbility();// 其他属性方法省略...Overridepublic void tween() {tweetAbility.tween(); // 委托}Overridepublic void layEgg() {eggLayAbility.layEgg(); // 委托} }我们知道继承主要有三个作用表示 is-a 关系支持多态特性代码复用。而这三个作用都可以通过其他技术手段来达成。 is-a 关系通过组合和接口的 has-a 关系来替代多态特性利用接口来实现代码复用通过组合和委托来实现。 所以理论上通过组合、接口、委托三个技术手段完全可以替换掉继承在项目中不用或者少用继承关系特别是一些复杂的继承关系。 如何判断是该用组合还是继承 尽管鼓励多用组合少用继承但组合也并不是完美继承也并非是一无是处。从上面的例子来看继承改写成组合意味着要耕细粒度的类的拆分。这就以为这我们要定义更多的类和接口。类和接口的增多也就增加了代付复杂度和维护成本。所以在实际的项目开发中我们要根据情况来具体选择用继承还是组合。 如果类之间的继承结构稳定不会轻易改变继承层次比较浅比如最多有两层继承关系继承关系不复杂我们就可以大胆地使用继承。反之系统越不稳定继承层次很深继承关系复杂我们就尽量使用组合来替代继承。 初次之外还有一些设计模式会固定使用继承或组合。比如装饰者模式decorator pattern、策略模式strategy pattern、组合模式composite pattern等都使用了组合关系而模板模式template pattern使用了继承关系。 前面我们讲过继承可以实现代码复用。利用继承特性可以把相同的属性和方法抽取出来定义到父类中。子类复用父类的属性和方法达到代码复用的目的。但是有时候从业务含义上A 类和 B 类并一定具有继承关系。比如 Crawler 类和 PageAnalyzer 类它们都用到了 URL 拼接和分割的功能但并不具有继承关系既不是父子也不是兄弟。仅仅为了代码复用生硬地抽象出一个父类出来会影响代码地可读性。这个时候使用组合就更加合理、灵活。 public class Url {// 省略属性和方法... }public class Crawler {private Url url;public Crawler() {this.url new Url();}// ... }public class PageAnalyzer {private Url url;public PageAnalyzer() {this.url new Url();}// ... }如果有些场合要求必须使用继承。如果你不能改变一个函数的入参类型而入参非接口为了支持多态只能采用继承来实现。比如下面的代码其中 FeignClient 是一个外部类我们没有权限去修改这部分代码但是我们希望重写这个类在运行时执行的 encode() 函数。这个时候我们只能采用继承实现了。 public class FeignClient {// 省略其他代码...public void encode(String url) { /*...*/ } }public void demoFuction(FeignClient feignClient) {// ...feignClient.encode(url);// ... }public class CustomizeFeignClient extend FeignClient {Overridepublic void encode(String url) { /*重写encode的实现...*/ } }// 调用 FeignClient client new CustomizeFeignClient(); demoFuction(client);尽管有些人要杜绝继承100% 用组合代替继承但是我们可以不需要这么极端。之所以“多用组合少用继承”这个口号喊的响只是因为长期以来我们过度使用继承。还是那句话组合并不完美继承也不是一无是处。只要我们控制好它的副作用、发挥它们各自的优势在不同的场合下恰当地选择使用组合还是继承这才应该追求的境界。 总结 为什么不推荐使用继承 继承是面向对象的四大特性之一用来表示 is-a 的关系可以解决代码复用的问题。虽然继承的作用很多但是继承层次太深、过复杂也会影响到代码的可维护性。在这种情况下应尽量少用甚至不用继承。 组合相比继承有哪些优势 继承主要有三个优势表示 is-a 关系、支持多态、代码复用。而在三个作用可以通过组合、接口、委托三个技术手段来达成。初次之外利用组合还能解决层次过深、过复杂的继承关系影响代码可维护性的问题。 如何判断该用组合还是继承 在开发中需要根据情况来选择。如果类之间的继承结构稳定、层次比较浅、关系不复杂那就可以大胆地使用继承。反之就尽量使用组合来替代继承。初次之外一些设计模式、特殊的场景会固定使用继承或者组合。
http://www.hkea.cn/news/14517498/

相关文章:

  • 技术类网站模板重庆seo教程
  • 慈溪做网站什么价百度指数三个功能模块
  • 企业网站赏析宁波网站seo哪家好
  • wap网站 微信动态发布网站和静态发布网站
  • 广东网站建设方案报价宝安哪有网站建设
  • 果麦传媒的网站怎么做的成都网站开发哪个好
  • 蚌埠做网站有哪些公司wordpress setup-config.php空白
  • 网站设计建设公司域名怎么创建网站吗
  • 做信息网站的盈利方式有哪些一个网站设计的费用
  • 网站个人备案需要什么资料网站快速备案公司
  • 成品网站1688入口网页版怎样广告片制作
  • 手机怎么防止网站跳转网站建设手机源码
  • 做网站嘉兴my网站域名
  • vr 做的网站会员网站开发
  • 网站建设行业怎么样上海做网站建设的公司
  • 小程序二次开发多少钱论坛seo招聘
  • 购物网站建设需求模板网站管理工作一般包括
  • 销售平台网站建设方案建设外贸网站公司简介
  • 网站服务器怎么搭建怎样提升网站关键词
  • 重庆手机网站建设建设银行信用卡去网站
  • 汕头企业网站推广方法自己买个服务器做代挂网站
  • 为企业做网站要向谁索要资料抚州的电子商务网站建设公司
  • 三网合一网站 东莞装修设计的网站
  • 湖北网址大全yoast seo教程
  • 荣成市信用建设网站免飞网站
  • 网站制作加教程视频网络平台推广具体是干啥
  • asp网站开发技术背景介绍然后制作网页
  • 公司网站模板怎么做wordpress 偷网页
  • sz住房和城乡建设部网站定西模板型网站建设
  • 小程序游戏源码wordpressseo网站设计外包