Fluent Interface и Builder - идеальное сочетание для декларативного создания объектов.
На самом деле примеры такого выгодного симбиоза давно у нас под носом, например: StringBuilder.
Я использовал такой симбиоз для декларативного создания SIP аккаунтов и звонков.
Решение состоит из внутренних Builder-классов, которые предоставляют декларативный интерфейс для создания объектов и скрывают детали типа суффиксов транспорта, схемы и пр., о которых не надо задумываться.
Оба этих класса опираются на вспомогательный Builder – SIPUriBuilder. Этот класс настолько интуитивен, что я удивлен, что я не написал его первым делом.
Результат на лицо:
Было:
string remote = "sip:";
remote += txbURI.Text == "00"
? "127.0.0.1"
: (txbURI.Text + "@" + SIPUserAgent.SIPUserAgent.Instance.AccountManager.DefaultAccount.RegistrarUri.Split(new[]{':'})[1]);
remote += SIPUserAgent.SIPUserAgent.Instance.SIPTransport is TCPTransport
? ":5061;transport=TCP"
: "";
SIPUserAgent.SIPUserAgent.Instance.CallManager.MakeCall(remote);
Стало:
Call c = Call.ConstructCall().SetAccount(acc).SetExtension(txbURI.Text).SetDomain(txbURID.Text).Call();
Было:
var acc = new Account(false);
using (acc.CreateInitializationSession())
{
acc.Credential = new NamePasswordCredential
{
Password = txbPass.Text,
Realm = txbRegistrar.Text,
UserName = txbLogin.Text
};
acc.AccountId = "sip:" + txbLogin.Text + "@" + txbRegistrar.Text;
acc.RegistrarUri = "sip:" + txbRegistrar.Text;
if (ua.SIPTransport is TCPTransport)
{
acc.AccountId += "5061;transport=TCP";
acc.RegistrarUri += "5061;transport=TCP";
}
}
ua.AccountManager.RegisterAccount(acc, true);
Стало:
var acc = Account.ConstructAccount().SetLogin(txbLogin.Text).SetPassword(txbPass.Text)
.SetRegistrarDomain(txbRegistrar.Text).Register();
Комментарии я думаю излишни. Просто сравните число строк.
Удачи!
четверг, 3 сентября 2009 г.
Fluent Builder
вторник, 3 июня 2008 г.
Handy Monitor wrapper.
Вам никогда не требовалось узнать, стоят ли за текущим потоком в очереди другие потоки на блокировке? Если да, то вы наверняка уже полазили по классу Monitor в поисках свойства, которое бы называлось как-нибудь вроде LockCount или Busy. И тогда-то вы уж точно знаете, что это "конфиденциальная информация"! =)
Ниже я привожу простой и удобный класс-обертку над Monitor, который предоставляет такую информацию совершенно бесплатно. И что самое прекрасное, блокировка также осуществляется с поддержкой языка (я имею ввиду синтаксические конструкции, которые позволяют писать элегантный код). Но есть небольшая разница, если блокировка Monitor осуществляется конструкцией lock(object) {}, то в данной реализации она осуществляется конструкцией using(object){}. Ниже код класса и пример.
Вот пример использования:
Удачи!
P.S. Реализацию я подглядел в недрах какой-то из системных сборок.
пятница, 11 апреля 2008 г.
ConfigurationElement serializing unrecognized attributes


четверг, 27 марта 2008 г.
Safe event pattern
Рылся в кодах Prism и натолкнулся на вот такой код:
public event EventHandler
я так никогда раньше не писал, но данный паттерн позволяет совершенно не заботится о безопасности вызова и можно смело писать так:
Updated(null, new AccountPositionEventArgs());
вместо:
EventHandler
if (handler != null)
handler(null, new AccountPositionEventArgs());
так что на заметку.
Удачи!
