25
Шаблоны проектирования Часть вторая

Шаблоны проектирования 2

Embed Size (px)

DESCRIPTION

Лекция Михаила Гуренкова по шаблонам проектирования в рамках курса по ООП. Каф. Вычислительная математика и программирование, МАИ.

Citation preview

Page 1: Шаблоны проектирования 2

Шаблоны проектирования

Часть вторая

Page 2: Шаблоны проектирования 2

Порождающие шаблоны

— Factory (фабрика, фабричный метод)

— Abstract Factory (абстрактная фабрика)

— Singleton (одиночка)

— Lazy Load (загрузка по требованию)

Page 3: Шаблоны проектирования 2

Façade (фасад)

Page 4: Шаблоны проектирования 2

Façade (фасад)class TreeNode{}

class SearchResult{}

static class ACAlgoritm{ public static TreeNode BuildTree(string[] a_Keywords)

{…

}

public static SearchResult[] FindAll(TreeNode a_Root, string a_Text){

…}

}

class SearchAlgoritm{ TreeNode m_Root; public SearchAlgoritm(string[] a_Keywords) { m_Root = ACAlgoritm.BuildTree(a_Keywords); }

public SearchResult[] FindAll(string a_Text) { return ACAlgoritm.FindAll(m_Root, a_Text); }

public static SearchResult[] FindAll(string[] a_Keywords, string a_Text)

{ return ACAlgoritm.FindAll(

ACAlgoritm.BuildTree(a_Keywords), a_Text);

}}

Page 5: Шаблоны проектирования 2

Façade (фасад)

— Предоставить более удобный интерфейс для использования библиотеки, за счет наличия специальных удобных методов

— Повысить читаемость клиентского кода (повышение уровня абстракции)

— Снизить связанность между клиентским кодом и кодом модуля

— Создать собственный хорошо спроектированный API для сторонней библиотеки, у которой свой API плохо спроектирован

Page 6: Шаблоны проектирования 2

Composite (компоновщик)

Page 7: Шаблоны проектирования 2

Composite (компоновщик)

select * from Companies

where (IsClient = 1 or IsFormerClient = 1) and IsDeleted = 0 and id_Object = 103

Page 8: Шаблоны проектирования 2

Composite (компоновщик)

IsClient = 1 or IsFormerClient = 1) and IsDeleted = 0 and id_Object = 103

and

or

IsClient = 1 IsFormerClient = 1

IsDeleted = 0 id_Object = 103

Page 9: Шаблоны проектирования 2

Composite (компоновщик)

interface IFilter{

string GetSql();}

interface ICompositeFilter : IFilter{

void AddFilter(IFilter a_Filter);}

Page 10: Шаблоны проектирования 2

Composite (компоновщик)class ScalarFilter : IFilter{ string m_Sql;

public ScalarFilter(string a_Field, string a_Relation, object a_Value) { m_Sql = string.Format("{0} {1} {2}", a_Field, a_Relation, a_Value); }

public ScalarFilter(string a_Field, object a_Value) : this (a_Field, "=", a_Value) {}

public string GetSql() { return m_Sql; }}

Page 11: Шаблоны проектирования 2

Composite (компоновщик)class AndFilter : ICompositeFilter{ List<IFilter> m_Filters = new List<IFilter>();

public void AddFilter(IFilter a_Filter) { m_Filters.Add(a_Filter); }

public string GetSql() { string result = string.Empty; foreach (IFilter filter in m_Filters) { if (result != "") result += " and "; result += filter.GetSql(); } return result; }}

Page 12: Шаблоны проектирования 2

Composite (компоновщик)protected IFilter GetFilterInternal(){ XAndFilter result = new XAndFilter(); if (ObjectsItemSelection.HasSelectedItems) { XOrFilter objectFilter = new XOrFilter(); foreach (XObject obj in ObjectsItemSelection.SelectedItems) objectFilter.Add(new XScalarFilter("id_Object", obj.Id)); result.Add(objectFilter); } if (OperatorCheckBox.Checked || ClientCheckBox.Checked || FormerClientCheckBox.Checked) { XAndFilter categoryFilter = new XAndFilter(); if (OperatorCheckBox.Checked) categoryFilter.Add(new XScalarFilter("IsOperator", 1)); if (ClientCheckBox.Checked) categoryFilter.Add(new XScalarFilter("IsClient", 1));

… result.Add(categoryFilter); } if (HoldingComboBox.Text.Trim() != "") { result.Add(DB.Companies.HoldingFilter(HoldingComboBox.Text.Trim())); } … return result;}

Page 13: Шаблоны проектирования 2

Composite (компоновщик)

Компоновщик — это круто!

Page 14: Шаблоны проектирования 2

Ахтунг!public class XScalarFilter : IFilter{ string m_Command; IDataParameter m_Parameter;

public XScalarFilter(string a_Field, string a_Relation, object a_Value) { int counter = XFilter.Counter; m_Command = string.Format("{0} {1} @p{2}", a_Field, a_Relation, counter); m_Parameter = new SqlParameter(); m_Parameter.Value = a_Value; m_Parameter.ParameterName = "@p" + counter; } public XScalarFilter(string a_Field, object a_Value) : this(a_Field, "=", a_Value) {}

public string SqlText { get { return m_Command; } }

public IList<IDataParameter> Parameters { get { return new IDataParameter[] { m_Parameter }; } }}

Page 15: Шаблоны проектирования 2

Задача

Page 16: Шаблоны проектирования 2

Command (команда)interface ICommand{ void Run();}

interface ICommand{ void Do(); void UnDo();}

foreach(ICommand command in GetCommands()){ command.Do();}

Page 17: Шаблоны проектирования 2

Command (команда)<?xml version='1.0' encoding='windows-1251'?><template> <parts> <part type="Cell" cell="Contract"> <sql>select ContractNumber from CompanyClients where id_Company = @id_Company</sql> </part> <part type="Cell" cell="CompName"> <sql>select FullName from Companies where id = @id_Company</sql> </part> <part type="Cell" cell="SmallCompName"> <sql>select FullName from Companies where id = @id_Company</sql> </part> <part type="Cell" cell="Month"> <sql>select @DateFrom</sql> </part> <part type="Table" cell="AbonTable" groupBy="BService"> <sql> select ... </sql> </part> </parts></template>

Page 18: Шаблоны проектирования 2

Command (команда)

Page 19: Шаблоны проектирования 2

Плагины[TemplateItem(TemplateKind.ExcelSpreadsheet, "Cell")]public class XCellTemplateItem : XTemplateItem{ public override void Apply() { XExcelWorkDesk wd = (XExcelWorkDesk)WorkDesk;

… }}

[TemplateItem(TemplateKind.ExcelSpreadsheet, "Table")]class XTableTemplateItem : XTemplateItem{}

Page 20: Шаблоны проектирования 2

ПлагиныType FindTypeByName(string a_Name){ foreach (Type type in GetType().Assembly.GetTypes()) { if (!type.IsSubclassOf(typeof(XTemplateItem))) { continue; }

if (!type.IsDefined(typeof(TemplateItemAttribute), false)) { continue; }

TemplateItemAttribute attr = (TemplateItemAttribute)type.GetCustomAttributes(typeof(TemplateItemAttribute), false)[0];

if (attr.TemplateKind == m_Template.TemplateKind && attr.Name == a_Name) { return type; } }

return null;}

Page 21: Шаблоны проектирования 2

Template Method (шаблонный метод)abstract class Game { protected int playersCount; protected abstract void initializeGame(); protected abstract void makePlay(int player); protected abstract bool endOfGame(); protected abstract void printWinner(); /* A template method : */ public void playOneGame(int playersCount) { this.playersCount = playersCount; initializeGame(); int j = 0; while (!endOfGame()) { makePlay(j); j = (j + 1) % playersCount; } printWinner(); }}

Page 22: Шаблоны проектирования 2

Template Method (шаблонный метод)abstract public class XParser{

public XCallInformation ParseAndProcess(XBillingString a_BillingString) {

a_BillingString.SetParser(this);

XCallInformation result = DoParse(a_BillingString);

if (result == null) { XBilling.RegisterError(a_BillingString); }

return result;}

public XCallInformation Parse(XBillingString a_BillingString){

a_BillingString.SetParser(this); return DoParse(a_BillingString);}

}

Page 23: Шаблоны проектирования 2

Strategy (стратегия)class XDocumentConflictManager{ public XDocumentConflict FindConflict(

XDocument a_Document, bool a_ForRegisteration) { XDocumentConflictFindingStrategy strategy =

XDocumentConflictFindingStrategy.Create(a_Document, a_ForRegisteration);

return new XDocumentConflict(a_Document, strategy.FindSameDocuments(), strategy);

}}

Page 24: Шаблоны проектирования 2

Strategy (стратегия)public abstract class XDocumentConflictFindingStrategy{ XDocument m_Document;

protected XDocumentConflictFindingStrategy(XDocument a_Document) { m_Document = a_Document; }

public static XDocumentConflictFindingStrategy Create(XDocument a_Document, bool a_ForRegistration)

{…

}

public IList<XDocument> FindSameDocuments() { return XDocumentRepository.Instance.Find(GetSameDocumentsFilter()); }

protected abstract IFilter GetSameDocumentsFilter();

public abstract string GetConflictDefinition();}

Page 25: Шаблоны проектирования 2

Strategy (стратегия) public class XBillingConflictFindingStrategy : XDocumentConflictFindingStrategy { internal XBillingConflictFindingStrategy(XDocument a_Document) : base(a_Document) {

}

protected override IFilter GetSameDocumentsFilter() { return new XAndFilter( DB.vDocuments.idFilter("!=", Document.Id), DB.vDocuments.id_CompanyFilter(Document.Company.Id), DB.vDocuments.DocumentDateFilter(Document.DocumentDate), DB.vDocuments.id_TemplateFilter(Document.Template.Id) ); }

public override string GetConflictDefinition() { return string.Format("Компания «{0}» уже имеет расшифровку «{1}» за «{2:MMMM yyyy}».", Document.Company.Alias, Document.Template.Name, Document.DocumentDate); } }