Интернет магазин китайских планшетных компьютеров |
|
Компьютеры - Fluent interface - Примеры13 мая 2011Оглавление: 1. Fluent interface 2. Примеры DelphiСледующий пример показывает обычный класс и класс, реализующий текучий интерфейс, и различия в использовании. Пример написан на Delphi Object Pascal: unit FluentInterface; interface type IConfiguration = interface procedure SetColor; procedure SetHeight; procedure SetLength; procedure SetDepth; end; IConfigurationFluent = interface function SetColor: IConfigurationFluent; function SetHeight: IConfigurationFluent; function SetLength: IConfigurationFluent; function SetDepth: IConfigurationFluent; end; TConfiguration = class private FColor: string; FHeight: integer; FLength: integer; FDepth: integer; protected procedure SetColor; procedure SetHeight; procedure SetLength; procedure SetDepth; end; TConfigurationFluent = class private FColor: string; FHeight: integer; FLength: integer; FDepth: integer; protected function SetColor: IConfigurationFluent; function SetHeight: IConfigurationFluent; function SetLength: IConfigurationFluent; function SetDepth: IConfigurationFluent; public class function New: IConfigurationFluent; end; implementation procedure TConfiguration.SetColor; begin FColor := Color; end; procedure TConfiguration.SetDepth; begin FDepth := depth; end; procedure TConfiguration.SetHeight; begin FHeight := height; end; procedure TConfiguration.SetLength; begin FLength := length; end; class function TConfigurationFluent.New: IConfigurationFluent; begin Result := Create; end; function TConfigurationFluent.SetColor: IConfigurationFluent; begin FColor := Color; Result := Self; end; function TConfigurationFluent.SetDepth: IConfigurationFluent; begin FDepth := depth; Result := Self; end; function TConfigurationFluent.SetHeight: IConfigurationFluent; begin FHeight := height; Result := Self; end; function TConfigurationFluent.SetLength: IConfigurationFluent; begin FLength := length; Result := Self; end; end. var C, D: IConfiguration; E: IConfigurationFluent; begin { Обычное использование:} C := TConfiguration.Create; C.SetColor; C.SetHeight; C.SetLength; C.SetDepth; { обычная реализация, упрощенная с помощью инструкции with } D := TConfiguration.Create; with D do begin SetColor; SetHeight; SetLength; SetDepth end; { использование реализации с текучим интерфейсом } E := TConfigurationFluent.New .SetColor .SetHeight .SetLength .SetDepth; end; C#Начиная с C#3.5 и выше введены продвинутые способы реализации текучего интерфейса. Этот пример написан на C#: 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; IConfigurationFluent SetHeight; IConfigurationFluent SetLength; IConfigurationFluent SetDepth; } public class ConfigurationFluent : IConfigurationFluent { string color; int height; int length; int depth; public IConfigurationFluent SetColor { this.color = color; return this; } public IConfigurationFluent SetHeight { this.height = height; return this; } public IConfigurationFluent SetLength { this.length = length; return this; } public IConfigurationFluent SetDepth { this.depth = depth; return this; } } #endregion public class ExampleProgram { public static void Main { // Обычный пример IConfiguration config = new Configuration { Color = "blue", Height = 1, Length = 2, Depth = 3 }; // Пример текучего интерфейса IConfigurationFluent fluentConfig = new ConfigurationFluent.SetColor .SetHeight .SetLength .SetDepth; } } } C++Банальный пример в C++ стандартный iostream, где текучесть обеспечивается перегрузкой операторов. Пример обертки текучего интерфейса в C++: // обычное задание class GlutApp { private: int w_, h_, x_, y_, argc_, display_mode_; char **argv_; char *title_; public: GlutApp { argc_ = argc; argv_ = argv; } void setDisplayMode { display_mode_ = mode; } int getDisplayMode { return display_mode_; } void setWindowSize { w_ = w; h_ = h; } void setWindowPosition { x_ = x; y_ = y; } void setTitle { title_ = title; } void create; }; // обычное использование int main { GlutApp app; app.setDisplayMode; // Set framebuffer params app.setWindowSize; // Set window params app.setWindowPosition; app.setTitle; app.create; } // Обертка текучего интерфейса class FluentGlutApp : private GlutApp { public: FluentGlutApp : GlutApp {} // наследуем родительский конструктор FluentGlutApp &withDoubleBuffer { setDisplayMode | GLUT_DOUBLE); return *this; } FluentGlutApp &withRGBA { setDisplayMode | GLUT_RGBA); return *this; } FluentGlutApp &withAlpha { setDisplayMode | GLUT_ALPHA); return *this; } FluentGlutApp &withDepth { setDisplayMode | GLUT_DEPTH); return *this; } FluentGlutApp &across { setWindowSize; return *this; } FluentGlutApp &at { setWindowPosition; return *this; } FluentGlutApp &named { setTitle; return *this; } // без разницы, вести ли цепь после вызова create, поэтому не возвращаем *this void create { GlutApp::create; } }; // используем текучий интерфейс int main { FluentGlutApp app .withDoubleBuffer.withRGBA.withAlpha.withDepth .at.across .named; app.create; } JavaНекоторые API в Java реализуют такой интерфейс, например Java Persistence API: public Collection<Student> findByNameAgeGender { return em.createNamedQuery .setParameter .setParameter .setParameter .setFirstResult .setMaxResults .setHint .getResultList; }
String datesStr = new String {"12-10-1492", "06-12-1978" }; ... List<Calendar> dates = Op.on.toList.map).get;
Collection mockCollection = EasyMock.createMock; EasyMock.expect).andThrow).atLeastOnce; PHPПример реализации класса с текучим интерфейсом в PHP: class Car { private $speed; private $color; private $doors; public function setSpeed{ $this->speed = $speed; return $this; } public function setColor { $this->color = $color; return $this; } public function setDoors { $this->doors = $doors; return $this; } } // Обычная реализация $myCar2 = new Car; $myCar2->setSpeed; $myCar2->setColor; $myCar2->setDoors; // Текучий интерфейс $myCar = new Car; $myCar->setSpeed->setColor->setDoors; JavaScriptПример реализации класса с текучим интерфейсом в JavaScript: var Car = { var speed, color, doors, pub; function setSpeed { speed = new_speed; return pub; } function setColor { color = new_color; return pub; } function setDoors { doors = new_doors; return pub; } pub = { 'setSpeed': setSpeed, 'setColor': setColor, 'setDoors': setDoors, }; return pub; }) // Обычная реализация myCar2 = Car; myCar2.setSpeed; myCar2.setColor; myCar2.setDoors; // Текучий интерфейс myCar = Car; myCar.setSpeed.setColor.setDoors; Также можно использовать иной подход: var $ = function { if { return new $; } if { this.init = document.getElementById; } }; $.prototype = { text: function { if{ this.init.innerHTML; } this.init.innerHTML = text; return this; }, css: function { for{ this.init.style = style; } return this; } }; //пример использования: $.text.css; Пример реализации независящей от возвращаемого типа объекта: ({ foo: function { return a; } }).foo.toUpperCase; Просмотров: 1965
|