2013-11-13 4 views
4

Мне нужен шаблон программирования, но я не мог понять, каким он будет. Я даже не уверен, возможно ли то, что я хочу, или нет. Допустим, у меня есть Class A и 10 класс, унаследованный от A. Я хочу, чтобы тот же метод Method Print() реализовал по-разному в каждом унаследованном классе, но все они должны повторить один и тот же метод Class A.Необходимое предложение дизайна шаблона

Class A 
{ 
    public virtual void Print() 
    { 
    } 
    protected void StartingProcedure() 
    { 
     /// something 
    } 
    protected void EndingProcedure() 
    { 
     /// something 
    } 
} 

Class A_1 : A 
{ 
    public override void Print() 
    { 
     StartingProcedure(); 
     /// class specific print operation 
     EndingProcedure(); 
    } 
} 

Class A_2 : A 
{ 
    public override void Print() 
    { 
     StartingProcedure(); 
     /// class specific print operation 
     EndingProcedure(); 
    } 
} 

Как вы видите, я не хочу, чтобы писать StartingProcedure(); на каждом переопределен Print методом. Я хочу автоматизировать эту процедуру, когда я наследую новый класс от A. Я не хочу возражать против процедур «Запуск и завершение», я хочу просто написать операцию печати по конкретному классу. Есть ли какой-либо шаблон, который обеспечит мне такое поведение класса?

КСТАТИ Я работаю с C#

+0

Вызов 'base.Print()' ' –

+0

base.Print()' не имеет реализации в нем. Это виртуальный метод. Даже если бы это было так, как я мог бы назвать унаследованные классы конкретными операциями? –

+1

Кроме того, ваши «производные» классы не наследуются от 'A'. –

ответ

9
Class A 
{ 
    public void Print() 
    { 
     StartingProcedure(); 
     SpecificPrint(); 
     EndingProcedure(); 
    } 
    protected void StartingProcedure() 
    { 
     /// something 
    } 
    protected void EndingProcedure() 
    { 
     /// something 
    } 
    protected virtual SpecificPrint() // could possibly be abstract 
    { 
    } 
} 

Class A_1 : A 
{ 
    public override void SpecificPrint() 
    { 
     /// class specific print operation 
    } 
} 

Class A_2 : A 
{ 
    public override void SpecificPrint() 
    { 
     /// class specific print operation 
    } 
} 
+0

Я лично сделал бы 'SpecificPrint' виртуальным, чтобы его не нужно было использовать. – gunr2171

+0

'override' какой? классы не наследуют ничего. –

+0

@ gunr2171 Я согласен. – Rik

3

Узор вы ищете в этом случае является Шаблон Шаблон по Банды четырех (GoF).

Class A 
{ 
    public virtual void Print() 
    { 
    } 
    protected void StartingProcedure() 
    { 
     /// something 
     Print(); 
    } 
    protected void EndingProcedure() 
    { 
     /// something 
    } 
} 

обычно вы добавите еще один метод, называемый Template Method:

/// Template Method 
protected void Run() 
{ 
    StartingProcedure(); 
    Print(); 
    EndingProcedure(); 
} 

class A_1 : A 
{ 
    public override void Print() 
    { 
     /// class specific print operation 
    } 
    public A_1() 
    { 
     base.Run(); 
    } 
} 
+0

да Я ищу что-то подобное, но не знаю, как вызвать виртуальный метод. могли бы вы объяснить? –

+0

@TolgaEvcimen - отредактировал мой ответ. –

+0

Я знал это :) Я знал, что проблема имеет какое-то отношение к шаблону шаблона, но поскольку я не был уверен, что я этого не заметил. Спасибо хоть. –

1

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

class PrintDecorator : A 
{ 
    private A wrappedA; 
    public PrintDecorator(A a) 
    { 
     wrappedA = a; 
    } 
    public virtual void Print() 
    { 
     //wrap the derived logic with the pre- and post- processing 
     StartingProcedure(); 
     wrappedA.Print(); 
     EndingProcedure(); 
    } 
} 
class A 
{ 
    public virtual void Print() 
    { 
    } 
    protected void StartingProcedure() 
    { 
     /// something 
    } 
    protected void EndingProcedure() 
    { 
     /// something 
    } 
} 

class A_1 : A 
{ 
    public override void Print() 
    { 
     /// class specific print operation 
    } 
} 

class A_2 : A 
{ 
    public override void Print() 
    { 
     /// class specific print operation 
    } 
} 

Пример использования:

A dec = new PrintDecorator(new A_1()); 
dec.Print(); 
+0

Понравился этот подход, но не мог понять, где я буду использовать класс «PrintDecorator». –

+1

@TolgaEvcimen: Вы создали бы это вместо своих классов A_1, A_2 и т. Д. Когда вы его создаете, вы вводите экземпляр A_1/A_2 в конструктор. Если вы используете инфраструктуру инъекций зависимостей, вы можете настроить это автоматически, когда используете эти объекты. – mao47

+0

Я получаю это сейчас;) Большое спасибо. Я буду помнить об этом. На самом деле мне понравилось это решение лучше, чем другое, поскольку он более общий. Но на данный момент я использовал другое решение, поскольку его проще реализовать;) Спасибо за пример использования. –

Смежные вопросы