Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Текучий интерфейс ( fluent interface) в разработке программного обеспечения кратко

Лекция



Привет, Вы узнаете о том , что такое текучий интерфейс, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое текучий интерфейс, fluent interface , настоятельно рекомендую прочитать все из категории Проектирование веб сайта или программного обеспечения.

текучий интерфейс (англ. fluent interface — в значении «плавный» или «гладкий» «интерфейс») в разработке программного обеспечения — способ реализации объектно-ориентированного API, нацеленный на повышение читабельности исходного кода программы. Название придумано Эриком Эвансом и Мартином Фаулером.

цепочка вызовов

Текучий интерфейс хорош тем, что упрощается множественный вызов методов одного объекта. Обычно это реализуется использованием цепочки методов, передающих контекст вызова следующему звену (но текучий интерфейс влечет за собой нечто большее, чем просто цепочку методов ). Обычно, этот контекст:

  • определен с помощью значения, возвращаемого методом;
  • наследуется (в качестве нового контекста используется предыдущий);
  • прекращается возвращением ничего не значащего значения (void).

Такой стиль косвенно полезен повышением наглядности и интуитивности кода . Однако может весьма пагубно сказаться на отладке, если цепочка действует как одно выражение, куда отладчик не всегда может установить промежуточную точку останова.

Реализация

Плавный интерфейс обычно реализуется с использованием цепочки методов для реализации каскадирования методов (на языках, которые изначально не поддерживают каскадирование), в частности, за счет того, что каждый метод возвращает объект, к которому он прикреплен, часто называемый this или self. Говоря более абстрактно, свободный интерфейс передает контекст инструкции последующего вызова в цепочке методов, где обычно контекст

  • Определяется через возвращаемое значение вызываемого метода
  • Самореференциальный , когда новый контекст эквивалентен последнему контексту
  • Прекращено возвратом пустого контекста

Обратите внимание, что «свободный интерфейс» означает больше, чем просто каскадирование методов через цепочку; это влечет за собой разработку интерфейса, который читается как DSL, с использованием других методов, таких как «вложенные функции и область видимости объекта».

Примеры

C#

Начиная с C# 3.5 и выше введены продвинутые способы реализации текучего интерфейса:

namespace Example.FluentInterfaces
{
    #region Standard Example

    public interface IConfiguration
    {
        string Color { set; }
        int Height { set; }
        int Length { set; }
        int Depth { set; }
    }

    public class Configuration : IConfiguration
    {
        string color;
        int height;
        int length;
        int depth;

        public string Color
        {
            set { color = value; }
        }

        public int Height
        {
            set { height = value; }
        }

        public int Length
        {
            set { length = value; }
        }

        public int Depth
        {
            set { depth = value; }
        }
    }

    #endregion

    #region Fluent Example

    public interface IConfigurationFluent
    {
        IConfigurationFluent SetColor(string color);
        IConfigurationFluent SetHeight(int height);
        IConfigurationFluent SetLength(int length);
        IConfigurationFluent SetDepth(int depth);
    }

    public class ConfigurationFluent : IConfigurationFluent
    {
        string color;
        int height;
        int length;
        int depth;

        public IConfigurationFluent SetColor(string color)
        {
            this.color = color;
            return this;
        }

        public IConfigurationFluent SetHeight(int height)
        {
            this.height = height;
            return this;
        }

        public IConfigurationFluent SetLength(int length)
        {
            this.length = length;
            return this;
        }

        public IConfigurationFluent SetDepth(int depth)
        {
            this.depth = depth;
            return this;
        }
    }

    #endregion

    public class ExampleProgram
    {
        public static void Main(string[] args)
        {
            // Обычный пример
            IConfiguration config = new Configuration
            {
                Color = "blue",
                Height = 1,
                Length = 2,
                Depth = 3
            };

            // Пример текучего интерфейса
            IConfigurationFluent fluentConfig =
                  new ConfigurationFluent().SetColor("blue")
                                           .SetHeight(1)
                                           .SetLength(2)
                                           .SetDepth(3);
        }
    }
}

C++

Банальный пример в C++ — стандартный iostream, где текучесть обеспечивается перегрузкой операторов.

Пример обертки текучего интерфейса в C++:

 // обычное задание
 class GlutApp {
 private:
     int w_, h_, x_, y_, argc_, display_mode_;
     char **argv_;
     char *title_;
 public:
     GlutApp(int argc, char** argv) {
         argc_ = argc;
         argv_ = argv;
     }
     void setDisplayMode(int mode) {
         display_mode_ = mode;
     }
     int getDisplayMode() {
         return display_mode_;
     }
     void setWindowSize(int w, int h) {
         w_ = w;
         h_ = h;
     }
     void setWindowPosition(int x, int y) {
         x_ = x;
         y_ = y;
     }
     void setTitle(const char *title) {
         title_ = title;
     }
     void create();
 };
 // обычное использование
 int main(int argc, char **argv) {
     GlutApp app(argc, argv);
     app.setDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_ALPHA|GLUT_DEPTH); // Set framebuffer params
     app.setWindowSize(500, 500); // Set window params
     app.setWindowPosition(200, 200);
     app.setTitle("My OpenGL/GLUT App");
     app.create();
 }

 // Обертка текучего интерфейса
 class FluentGlutApp : private GlutApp {
 public:
     FluentGlutApp(int argc, char **argv) : GlutApp(argc, argv) {} // наследуем родительский конструктор
     FluentGlutApp &withDoubleBuffer() {
         setDisplayMode(getDisplayMode() | GLUT_DOUBLE);
         return *this;
     }
     FluentGlutApp &withRGBA() {
         setDisplayMode(getDisplayMode() | GLUT_RGBA);
         return *this;
     }
     FluentGlutApp &withAlpha() {
         setDisplayMode(getDisplayMode() | GLUT_ALPHA);
         return *this;
     }
     FluentGlutApp &withDepth() {
         setDisplayMode(getDisplayMode() | GLUT_DEPTH);
         return *this;
     }
     FluentGlutApp &across(int w, int h) {
         setWindowSize(w, h);
         return *this;
     }
     FluentGlutApp &at(int x, int y) {
         setWindowPosition(x, y);
         return *this;
     }
     FluentGlutApp &named(const char *title) {
         setTitle(title);
         return *this;
     }
     // без разницы, вести ли цепь после вызова create(), поэтому не возвращаем *this
     void create() {
         GlutApp::create();
     }
 };
 // используем текучий интерфейс
 int main(int argc, char **argv) {
     FluentGlutApp app(argc, argv)
         .withDoubleBuffer().withRGBA().withAlpha().withDepth()
         .at(200, 200).across(500, 500)
         .named("My OpenGL/GLUT App");
     app.create();
 }

Java

Некоторые API в Java реализуют такой интерфейс, например Java Persistence API:

public Collection<Student> findByNameAgeGender(String name, int age, Gender gender) {
    return em.createNamedQuery("Student.findByNameAgeGender")
             .setParameter("name", name)
             .setParameter("age", age)
             .setParameter("gender", gender)
             .setFirstResult(1)
             .setMaxResults(30)
             .setHint("hintName", "hintValue")
             .getResultList();
}

Библиотека op4j позволяет использовать текучий интерфейс для выполнения вспомогательных задач, вроде итерирования структур, конвертирования информации, фильтрации, и т. Об этом говорит сайт https://intellect.icu . д.

String[] datesStr = new String[] {"12-10-1492", "06-12-1978" };
...
List<Calendar> dates = 
    Op.on(datesStr).toList().map(FnString.toCalendar("dd-MM-yyyy")).get();

Также, библиотека Mock-объект тестирования EasyMock активно использует этот стиль для предоставления удобного интерфейса.

Collection mockCollection = EasyMock.createMock(Collection.class);
EasyMock.expect(mockCollection.remove(null)).andThrow(new NullPointerException()).atLeastOnce();

PHP

Пример реализации класса с текучим интерфейсом в PHP:

class Car {
	private $speed, $color, $doors;
		 
	public function setSpeed($speed){
		$this->speed = $speed;
		return $this;
	}
	 
	public function setColor($color)  {
		$this->color = $color;
		return $this;
	}
	 
	public function setDoors($doors) {
		$this->doors = $doors;
		return $this;
	}
}
	 	
// Обычная реализация
$myCar2 = new Car();
$myCar2->setSpeed(100);
$myCar2->setColor('blue');
$myCar2->setDoors(5);

// Текучий интерфейс
$myCar = new Car();
$myCar->setSpeed(100)->setColor('blue')->setDoors(5);

JavaScript

Пример реализации класса с текучим интерфейсом в JavaScript:

var Car = (function(){

	var speed, color, doors, pub;
		 
	function setSpeed(new_speed) {
		speed = new_speed;
		return pub;
	}
	 
	function setColor(new_color) {
		color = new_color;
		return pub;
	}
	 
	function setDoors(new_doors) {
		doors = new_doors;
		return pub;
	}

	pub = {
		'setSpeed': setSpeed,
		'setColor': setColor,
		'setDoors': setDoors,
	};

	return pub;

})
	
// Обычная реализация
myCar2 = Car();
myCar2.setSpeed(100);
myCar2.setColor('blue');
myCar2.setDoors(5);
	 
// Текучий интерфейс
myCar = Car();
myCar.setSpeed(100).setColor('blue').setDoors(5);

Также можно использовать иной подход:

var $ = function(selector) {
    if(this.$) {
        return new $(selector);
    }
    if(typeof selector == "string") {
        this.init = document.getElementById(selector);
    }
};
 
$.prototype = {
    text: function(text) {
        if(!text){
           this.init.innerHTML;
        }
        this.init.innerHTML = text;
        return this;
    },
    css: function(style) {
        for(var i in style){
           this.init.style[i] = style[i];
        }
        return this;
    }
};
//пример использования:
$('div').text('div').css({color: "red"});

Пример независящей от типа возвращаемого объекта реализации:

({
    foo: function (a) {
        return a;
    }
}).foo('foo').toUpperCase();

Вау!! 😲 Ты еще не читал? Это зря!

Исследование, описанное в статье про текучий интерфейс, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое текучий интерфейс, fluent interface и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Проектирование веб сайта или программного обеспечения

создано: 2021-11-18
обновлено: 2021-11-18
5



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Проектирование веб сайта или программного обеспечения

Термины: Проектирование веб сайта или программного обеспечения