构建流畅的API设计策略:Fluent API探索

流畅接口是由Martin Fowler和Eric Evans创造的,流畅API意味着你构建一个API需要遵循以下要点:

1.API用户能够容易理解API

2.API为完成一个任务能够执行一系列动作,比如Java中可以看成是一系列方法调用,方法链。

3.每个方法名称应该是与业务领域相关的专门术语

4.API应该能提示指导API用户下一步用什么,以及某个时刻用户可能采取的操作。


假设你要设计一个业务域的API,比如是零售行业,那么应该有一些零售领域存在的共同的术语 ,在一定情境(任务)或上下文下,应该会采取一系列行动来完成这项任务或上下文情境。比如说,一张发票的生成必须遵循一定的步骤。

现在,当你设计一个API接口时,设计方式是:当用户调用计费服务用于发票生成时,用户可以流利地执行每一步,以完成发票的生成,API会帮助用户对计费服务调用步骤的执行。

当一个API方法被用户调用时,该方法将执行其任务并返回一个对象,这将有助于指导用户下一步该做什么-直到所有步骤执行。不同于一个标准API,它是使用一个连续的方式调用API的方法,以便成功完成一个任务。因此,API用户必须非常了解服务的步骤(服务的方法)。


案例:假设我们为一个餐馆设计一个API,作为餐馆客户,他会执行以下动作步骤:

1.用户进入餐馆

2.查询价目选择菜单

3.订餐

4.吃饭

5.付费。


在标准的API(非流畅API)设计中,会如下做法:

1.创建一个“餐厅”界面。

2.创建一个餐厅实现类。组成菜单类menucard。

3.创造餐厅属性名称,包括getter和setter等方法。

4.在menucard类中,有条目列表。暴露的一些方法,如showmenu(), ordermenu(),等。

5.每个条目都有名称和成本等特性以及相应的getter和setter。

6.当用户调用这个API的API,他/她会调用一个方法序列(进入餐厅,调用showmenu(),然后调用ordermenu(),等)。完成上述客户步骤。


上面这张设计不是流畅的,完成一项任务需要很多顺序语句执行,API用户必须了解这些顺序。

看看流畅API设计:

1.创建一个接口iresturant,有两种方法A.

2.打印餐厅名字,注意 返回类型 返回自身,因为在显示名称以后,用户希望看到的菜单。

3. show()方法返回menucard。

(这里暗示有两种方法:一是名字和另一个show(下一个操作用户要执行的)

4. IMENU有4个重要的方法showmenu():order(),eat(),pay(),所有方法返回menuhandler实现,所以我们可以执行这些动作中的一个。这是再次暗示。


Java代码:

package com.example.fluentapi.contract;

public interface IResturant {

public IResturant name(String name);

public IMenu show();

}

package com.example.fluentapi.contract;

public interface IMenu{

public IMenu order(int index);

public IMenu eat();

public IMenu pay();

public IItem get(int index);

}

package com.example.fluentapi.contract;

public interface IItem {

public IItem name();

public Integer cost();

}

实现:

package com.example.fluentapi.impl;

import com.example.fluentapi.contract.IMenu;

import com.example.fluentapi.contract.IResturant;

public class Arsalan implements IResturant{

String name;

String IMenu;

public IResturant name(String name) {

this.name=name;

System.out.println("Enter to hotel :: "+ name);

return this;

}

public IMenu show() {// TODO Auto-generated method stubArsalanMenuHandler handler = new ArsalanMenuHandler();

handler.showMenu();

return handler;

}

}

package com.example.fluentapi.impl;

import java.util.ArrayList;

import java.util.List;

import com.example.fluentapi.contract.IItem;

import com.example.fluentapi.contract.IMenu;

public class ArsalanMenuHandler implements IMenu{

List menuList = new ArrayList();

List selectedList = new ArrayList();

public ArsalanMenuHandler()

{

IItem biriyani = new IItem(){

public IItem name()

{

System.out.println("Mutton Biriyani");

return this;

}

public Integer cost()

{

return 180;

}

};

IItem muttonChap = new IItem(){

public IItem name()

{

System.out.println("Mutton Chap");

return this;

}

public Integer cost()

{

return 160;

}

};

IItem firni = new IItem(){

public IItem name()

{

System.out.println("Firni");

return this;

}

public Integer cost()

{

return 100;

}

};

menuList.add(biriyani);

menuList.add(muttonChap);

menuList.add(firni);

}

public IMenu order(int index) {// TODO Auto-generated method stubIItem item (index);

selectedList.add(item);

System.out.println("Order given ::");

item.name();

return this;

}

public IMenu eat() {

for(IItem item : selectedList)

{

System.out.println("eating ");

item.name();

}

return this;

}

public IMenu pay() {

int cost=0;

for(IItem item : selectedList)

{

cost = cost + item.cost();

}

System.out.println("Paying Rupees"+ cost);

return this;

}

@Override

public IItem get(int index) {// TODO Auto-generated method stubif(index <3)

{

return menuList.get(index);

}

return null;

}

public void showMenu(){

System.out.println("MENU IN ARSALAN");

for(IItem item : menuList)

{

item.name();

}

}

}

测试:

package com.example.fluentapi.impl;

public class FluentApiTest {

publicstaticvoid main(String[] args) {

new Arsalan().name("ARSALAN").show().order(0).order(1).eat().pay();

}

}

输出:

Enter to hotel :: ARSALAN

MENU IN ARSALAN

Mutton Biriyani

Mutton Chap

Firni

Order given ::

Mutton Biriyani

Order given ::

Mutton Chap

eating

Mutton Biriyani

eating

Mutton Chap

Paying Ruppes340

我们是通过下面方法链实现流畅调用的:

new Arsalan().name("ARSALAN").show().order(0).order(1).eat().pay();


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空