Your latest client is a bank, and they’ve tasked you with requiring customers to enter their password in order to make withdrawals.

Currently, this is what they’ve got:

class Customer
attr_reader :funds def initialize(funds, password)
@funds = funds
@password = password
end def remove_funds(amount)
@funds -= amount
end
end

Let’s break that apart. You can paste that whole class into irb to follow along.

When a customer is initialized, it receives a specified amount of funds and a password is set.

diego = Customer.new(500, "udacious")
# => #<Customer:0x007fcdb48ca5a8 @funds=500 @password="udacious">

Thanks to the attr_reader, you can see the value of his current funds.

diego.funds
# => 500

And the remove_funds method allows funds to be removed from the customer’s account.

Checking on the funds again confirms this.

diego.remove_funds(50)
# => 450
diego.funds
# => 450

These methods, funds and remove_funds, are part of the Customer class’ API, or application programming interface.

An API is, according to Wikipedia, “a set of routines, protocols, and tools for building software applications”.

Well, that’s vague.

“API” is a popular term in recent years, but many people use it without quite understanding what it means. Think of methods like remove_funds as your way of interfacing with the Customer class. These methods are the keys to accessing information about a particular customer.

There isn’t currently a way to access the @password instance variable.

It could be said that the customer’s password can’t be accessed by the customer’s public API.

In this situation, that’s a good thing! You don’t want information like a password to be publicly available to other objects.

Let’s implement a method called withdraw_securely, which takes two arguments, amount andpassword.

If the password entered matches the customer’s password, go ahead and remove the funds. Otherwise, nothing happens.

class Customer
attr_reader :funds def initialize(funds, password)
@password = password
@funds = funds
end def remove_funds(amount)
@funds -= amount
end def withdraw_securely(amount, password)
if password == @password
remove_funds(amount)
end
end
end

Play around with this in irb to see it in action.

diego.withdraw_securely(50, "udacious")
# => 400
diego.withdraw_securely(100, "wrong password")
# => nil
diego.funds
# => 400

✨Hooray. Calling withdraw_securely using the correct password decreases the total funds by calling remove_funds,

while using the incorrect password does nothing.

There’s one issue here, can you spot it?

diego.remove_funds(75)
# => 325
diego.funds
# => 325

Malicious users can still withdraw funds directly using the remove_funds method!

Public and Private Interfaces in ruby的更多相关文章

  1. Ruby中访问控制符public,private,protected区别总结

    重点关注private与protected public 默认即为public,全局都可以访问,这个不解释 private C++, “private” 意为 “private to this cla ...

  2. swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明

    关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...

  3. public protect private. 草稿。

    public protect private. 草稿. #include <iostream> #include <thread> #include <memory> ...

  4. Java修饰符public,private,protected及默认的区别

    Java中访问修饰符public.private.protecte.default的意义讲解:public(接口访问权限): Java语言中访问限制最宽的修饰符,一般称之为“公共的”.被其修饰的类.属 ...

  5. C++中public,protected,private派生类继承问题和访问权限问题

    C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...

  6. 【转载】C++中public,protected,private访问

    第一:private, public, protected 访问标号的访问范围. 假如我们约定: 类内部-----指的是当前类类型的定义中,以及其成员函数的声明和定义中: 类外部-----指的是不在当 ...

  7. JAVA修饰符类型(public,protected,private,friendly)

    转自:http://www.cnblogs.com/webapplee/p/3771708.html JAVA修饰符类型(public,protected,private,friendly) publ ...

  8. php public protected private属性实例详解

    php 类中函数和类变量都有三个属性:public protected private,具体什么时候使用什么属性好纠结,特意找了个实例,这样看起来更清晰. public 表示全局,类内部外部子类都可以 ...

  9. C# 访问控制:public、private、protected和internal

    平日工作时最常用的访问控制符是public和private,当看到prism里面大量使用protected的时候,觉得还是不太理解为啥. 所以就静下心来查找并理解了一下,这里记录下,以便回顾和交流. ...

随机推荐

  1. 打个酱油,欢迎指正FizzBuzzWhizz(c#)

    平民的代码,列表法,凑个热闹,做了简单的测试,太晚了就不写测试用例了 using System; using System.Collections.Generic; using System.Linq ...

  2. jQuery基础之(二)jQuery中的$

    在jQuery中,最常用的莫过于使用美元符号$,它提供了各种各样的丰富功能.包括选择页面中一个或者一类元素.作为功能函数的前缀.windows.onload的完善,创建DOM节点等.本文介绍jQuer ...

  3. requirejs

    //index.html <!doctype html> <html> <head> <meta charset="utf-8"> ...

  4. jQuery插件开发模式

    jQuery插件开发模式 软件开发过程中是需要一定的设计模式来指导开发的,有了模式,我们就能更好地组织我们的代码,并且从这些前人总结出来的模式中学到很多好的实践. 根据<jQuery高级编程&g ...

  5. Java设计模式-状态模式(State)

    核心思想就是:当对象的状态改变时,同时改变其行为,很好理解!就拿QQ来说,有几种状态,在线.隐身.忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态,所以,状态模式就两点:1.可以通过改变状 ...

  6. Oracle自定义函数

    核心提示:函数用于返回特定数据.执行时得找一个变量接收函数的返回值; 语法如下: create or replace function function_name ( argu1 [mode1] da ...

  7. SqlParameter中的size

    SqlParameter中size对于需要指定大小的数据库中的数据类型参数有影响[如nvarchar],如果对于这些类型没有指定size则会默认根据赋的值进行推导应该指定的size,而对于那些大小固定 ...

  8. 排序算法二(时间复杂度为O(N*logN))

    快速排序: 1 package test; public class QuickSort { // 快速排序 public void quickSort(int s[], int l, int r) ...

  9. 活用scanf

    scanf()是C语言中用于读入格式化数据(formatted data)的函数. 我们可能对scanf()的一般用法已经了然,而至于scanf()读入数据的机制恐怕并不十分清楚. 下面我将比较详细地 ...

  10. 用 AIML 开发人工智能聊天机器人

    借助 Python 的 AIML 包,我们很容易实现人工智能聊天机器人.AIML 指的是 Artificial Intelligence Markup Language (人工智能标记语言),它不过是 ...