Вчера копался в чужом коде и наткнулся на очень интересную конструкцию.
А увидел я что-то подобное этому:
"Текучий интерфейс (англ. fluent interface, название придумано Эриком Эвансом и Мартином Фаулером) — способ реализации, в разработке программного обеспечения, объектно-ориентированного API, нацеленный на повышение читабельности исходного кода программы.
Текучий интерфейс хорош тем, что упрощается множественный вызов методов одного объекта. Обычно это реализуется использованием цепочки методов, передающих контекст вызова следующему звену (но текучий интерфейс влечет за собой нечто большее, чем просто цепочку методов). Обычно, этот контекст:
определен с помощью значения, возвращаемого методом;
наследуется (в качестве нового контекста используется предыдущий);
прекращается возвращением ничего не значащего значения (void).
Такой стиль косвенно полезен повышением наглядности и интуитивности кода. Однако может весьма пагубно сказаться на отладке, если цепочка действует как одно выражение, куда отладчик не всегда может установить промежуточную точку останова."
А теперь простой пример на С#:
Создаем наш "текучий интерфейс" для какого-нибудь гипотетического класса Player:
А увидел я что-то подобное этому:
/*
PHP код. Обычно я вижу создание
и иницилизацию объектов примерно такой
*/
$myPlayer = new Player();
$myPlayer->setSpeed(50);
$myPlayer->setName('Steve');
$myPlayer->setHealth(10);
/*
Но мною была встречена,
неизвестная мне конструкция
*/
$myPlayer = new Player();
$myPlayer->setSpeed(50)->setName('Steve')->setHealth(10);
Сначала я просто подумал, что это особенность языка, но после я решил покопать эту тему. Оказывается я так отстал от жизни. Поразительно, но данная методика существует уже довольно давно и именуется она как "Текучий интерфейс" (Fluent Interface). Наверняка, он описан во всех современных книгах, ведь конструкция выглядит действительно изящно. Поэтому я сразу полез в википедию:"Текучий интерфейс (англ. fluent interface, название придумано Эриком Эвансом и Мартином Фаулером) — способ реализации, в разработке программного обеспечения, объектно-ориентированного API, нацеленный на повышение читабельности исходного кода программы.
Текучий интерфейс хорош тем, что упрощается множественный вызов методов одного объекта. Обычно это реализуется использованием цепочки методов, передающих контекст вызова следующему звену (но текучий интерфейс влечет за собой нечто большее, чем просто цепочку методов). Обычно, этот контекст:
определен с помощью значения, возвращаемого методом;
наследуется (в качестве нового контекста используется предыдущий);
прекращается возвращением ничего не значащего значения (void).
Такой стиль косвенно полезен повышением наглядности и интуитивности кода. Однако может весьма пагубно сказаться на отладке, если цепочка действует как одно выражение, куда отладчик не всегда может установить промежуточную точку останова."
А теперь простой пример на С#:
Создаем наш "текучий интерфейс" для какого-нибудь гипотетического класса Player:
/*
IPlyaer.cs
*/
using System;
public interface IPlayer
{
IPlayer SetHealth(int health);
IPlayer SetPosition(Vector2 position);
IPlayer SetRunSpeed(float speed_run);
}
А вот и реализация нашего гипотетического класса Player:
/*
Player.cs
*/
using System;
public class Player : IPlayer
{
private int health;
private Vector2 position;
private float speed_run;
public IPlayer SetHealth(int health)
{
this.health = health;
return this;
}
public IPlayer SetPosition(Vector2 position)
{
this.position = position;
return this;
}
public IPlayer SetRunSpeed(float speed_run)
{
this.speed_run = speed_run;
return this;
}
}
Черт, как же изящно теперь выглядит инициализация нашего Player'a:
/*
GameScene.cs
*/
using UnityEngine;
using System.Collections;
public class GameScene : MonoBehaviour
{
private IPlayer player;
private void Start ()
{
player = new Player()
.SetHealth(100)
.SetPosition(new Vector2(0,0))
.SetRunSpeed(300.0f);
}
}
На самом деле практической пользы от этого паттерна конечно мало, да и к тому же возникают сложности в отладке. Но красота кода и удобочитаемость стоят того чтобы хотя бы прочитать о нем.
Комментариев нет:
Отправить комментарий