Ruby设计模式透析:组合(Composite)

听说你们公司最近新推出了一款电子书阅读应用,市场反应很不错,应用里还有图书商城,用户可 以在其中随意选购自己喜欢的书籍。你们公司也是对此项目高度重视,加大了投入力度,决定给此应用 再增加点功能。

好吧,你也知道你是逃不过此劫了,没过多久你的leader就找到了你。他告诉 你目前的应用对每本书的浏览量和销售量做了统计,但现在想增加对每个书籍分类的浏览量和销售量以 及所有书籍总的浏览量和销售量做统计的功能,希望你可以来完成这项功能。

领导安排的工作 当然是推脱不掉的,你只能硬着头皮上了,不过好在这个功能看起来也不怎么复杂。

你比较喜 欢看小说,那么就从小说类的统计功能开始做起吧。首先通过get_all_novels方法可以获取到所有的小 说名,然后将小说名传入get_browse_count方法可以得到该书的浏览量,将小说名传入get_sale_count 方法可以得到该书的销售量。你目前只有这几个已知的API可以使用,那么开始动手吧!

def 

get_novels_browse_count
    browse_count = 0
    all_novels = get_all_novels()
    all_novels.each do |novel|
        browse_count += get_browse_count(novel)
    end
    browse_count
end

def get_novels_sale_count
    sale_count = 0
    all_novels = get_all_novels()
    all_novels.each do |novel|
        sale_count += get_browse_count(novel)
    end
    sale_count
end

很快你就写下了以上两个方法,这两个方法都是通过获取到所有的小说名,然后一一计算 每本小说的浏览量和销售量,最后将结果相加得到总量。

小说类的统计就完成了,然后你开始 做计算机类书籍的统计功能,代码如下所示:

def get_computer_books_browse_count
    browse_count = 0
    all_computer_books = get_all_computer_books()
    all_computer_books.each do |computer_book|
        browse_count += get_browse_count(computer_book)
    end
    browse_count
end

def get_computer_books_sale_count
    sale_count = 0
    all_computer_books = get_all_computer_books()
    all_computer_books.each do |computer_book|
        sale_count += get_browse_count(computer_book)
    end
    sale_count
end

除了使用了get_all_computer_books方法获取到所有的计算机类书名,其它的代码基本和 小说统计中的是一样的。

现在你才完成了两类书籍的统计功能,后面还有医学类、自然类、历 史类、法律类、政治类、哲学类、旅游类、美食类等等等等书籍。你突然意识到了一些问题的严重性, 工作量大倒还不算什么,但再这么写下去,你的方法就要爆炸了,这么多的方法让人看都看不过来,别 提怎么使用了。

这个时候你只好向你的leader求助了,跟他说明了你的困惑。只见你的leader 思考了片刻,然后自信地告诉你,使用组合模式不仅可以轻松消除你的困惑,还能出色地完成功能。

他立刻向你秀起了编码操作,首先定义一个Statistics类,里面有两个方法:

class 

Statistics  

    def get_browse_count
        raise "You should override this method in subclass."
    end

    def get_sale_count
        raise "You should override this method in subclass."
    end

end

这两个方法都是简单地抛出一个异常,因为需要在子类中重写这两个方法。

然后 定义一个用于统计小说类书籍的NovelStatistics类,继承刚刚定义的Statistics类,并重写 Statistics中的两个方法:

class NovelStatistics < Statistics  

    def get_browse_count
        browse_count = 0
        all_novels = get_all_novels()
        all_novels.each do |novel|
            browse_count += get_browse_count(novel)
        end
        browse_count
    end

    def get_sale_count
        sale_count = 0
        all_novels = get_all_novels()
        all_novels.each do |novel|
            sale_count += get_browse_count(novel)
        end
        sale_count
    end

end

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索统计
, 方法
, count
, count()
, 功能
, end
, 5 all商城代码
, 浏览量
, count(*)
get模式
,以便于您获取更多的相关知识。

时间: 2024-09-17 04:48:50

Ruby设计模式透析:组合(Composite)的相关文章

Ruby设计模式透析:单例(Singleton)

写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你 分析数据,但是Ruby原生带有的puts方法却很少在真正的项目开发中使用. 为什么作为Ruby新 手神器的puts,到了真正项目开发当中会被唾弃呢?其实只要细细分析,你就会发现它的很多弊端.比 如不可控制,所有的日志都会在项目上线后照常打印,从而降低运行效率:又或者不能将日志记录到本 地文件,一旦打印被清除,日志将再也找不回来:再或者打印的内容没有Tag区分,你将很难辨别这一 行日志是在哪个类里打印的. 你的

Ruby设计模式透析:模板方法(Template Method)

今天你还是像往常一样来上班,一如既往地开始了你的编程工作. 项目经理告诉你,今天想 在服务器端增加一个新功能,希望写一个方法,能对Book对象进行处理,将Book对象的所有字段以XML 格式进行包装,这样以后可以方便与客户端进行交互.并且在包装开始前和结束后要打印日志,这样方 便调试和问题定位. 没问题!你觉得这个功能简直是小菜一碟,非常自信地开始写起代码. Book对象代码如下: class Book attr_accessor :book_name, :pages, :price, :aut

Ruby设计模式透析:适配器(Adapter)

今天一大早,你的leader就匆匆忙忙跑过来找到你:"快,快,紧急任务!最近ChinaJoy马上就要 开始了,老板要求提供一种直观的方式,可以查看到我们新上线的游戏中每个服的在线人数." 你看了看日期,不是吧!这哪里是马上要开始了,分明是已经开始了!这怎么可能来得及呢? "没关系的."你的leader安慰你道:"功能其实很简单的,接口都已经提供好了,你只需要 调用一下就行了." 好吧,你勉为其难地接受了,对于这种突如其来的新需求,你早已习惯. 你

Ruby设计模式透析:策略(Strategy)

今天你的leader兴致冲冲地找到你,希望你可以帮他一个小忙,他现在急着要去开会.要帮什么忙 呢?你很好奇. 他对你说,当前你们项目的数据库中有一张用户信息表,里面存放了很用户的 数据,现在需要完成一个选择性查询用户信息的功能.他说会传递给你一个包含许多用户名的数组,你 需要根据这些用户名把他们相应的数据都给查出来. 这个功能很简单的嘛,你爽快地答应了. 由于你们项目使用的是MySQL数据库,你很快地写出了如下代码: require 'mysql' class QueryUtil def fin

Java设计模式透析:组合(Composite)

听说你们公司最近新推出了一款电子书阅读应用,市场反应很不错,应用里还有图书商城,用户 可以在其中随意选购自己喜欢的书籍.你们公司也是对此项目高度重视,加大了投入力度,决定给此 应用再增加点功能. 好吧,你也知道你是逃不过此劫了,没过多久你的leader就找到了你. 他告诉你目前的应用对每本书的浏览量和销售量做了统计,但现在想增加对每个书籍分类的浏览量和 销售量以及所有书籍总的浏览量和销售量做统计的功能,希望你可以来完成这项功能. 领导 安排的工作当然是推脱不掉的,你只能硬着头皮上了,不过好在这个

Java设计模式透析:适配器(Adapter)

今天一大早,你的leader就匆匆忙忙跑过来找到你:"快,快,紧急任务!最近ChinaJoy马上就 要开始了,老板要求提供一种直观的方式,可以查看到我们新上线的游戏中每个服的在线人数." 你看了看日期,不是吧!这哪里是马上要开始了,分明是已经开始了!这怎么可能来得及呢 ? "没关系的."你的leader安慰你道:"功能其实很简单的,接口都已经提供好了,你只 需要调用一下就行了." 好吧,你勉为其难地接受了,对于这种突如其来的新需求,你早已 习惯.

Java设计模式透析:模板方法(Template Method)

今天你还是像往常一样来上班,一如既往地开始了你的编程工作. 项目经理告诉你,今天 想在服务器端增加一个新功能,希望写一个方法,能对Book对象进行处理,将Book对象的所有字段以 XML格式进行包装,这样以后可以方便与客户端进行交互.并且在包装开始前和结束后要打印日志, 这样方便调试和问题定位. 没问题!你觉得这个功能简直是小菜一碟,非常自信地开始写起 代码. Book对象代码如下: public class Book { private String bookName; private int

Java设计模式透析:单例(Singleton)

写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助 你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至 像findbugs等代码检查工具还会认为使用System.out.println()是一个bug. 为什么作为Java 新手神器的System.out.println(),到了真正项目开发当中会被唾弃呢?其实只要细细分析,你就会 发现它的很多弊端.比如不可控制,所有的日志都会在项目上线后照常打印,从

Java设计模式透析:策略(Strategy)

今天你的leader兴致冲冲地找到你,希望你可以帮他一个小忙,他现在急着要去开会.要帮什么 忙呢?你很好奇. 他对你说,当前你们项目的数据库中有一张用户信息表,里面存放了很用 户的数据,现在需要完成一个选择性查询用户信息的功能.他说会传递给你一个包含许多用户名的数 组,你需要根据这些用户名把他们相应的数据都给查出来. 这个功能很简单的嘛,你爽快地 答应了.由于你们项目使用的是MySQL数据库,你很快地写出了如下代码: public class QueryUtil { public void fi