2015-03-18 4 views
0

Я сталкиваюсь с моей наименее любимой проблемой, и это переписывает код. Вот структура, которую я сейчас разработал.Архитектура для интерфейса/абстракции

public interface ICanMove 
{ 
    int speed { get; set; } 

    void Walk(); 
    void Run(); 
} 

public class Worker : ICanMove 
{ 
    speed = 5; 

    public void Walk() 
    { 
    //Example code Move(speed); 
    } 
} 

public class Warrior : ICanMove 
{ 
    speed = 3; 

    public void Walk() 
    { 
    //Example code Move(speed); 
    } 
} 

Проблема здесь в нескольких классах использует интерфейс таким же образом. Но они не всегда будут делать то же самое. Есть ли способ реализовать это ... более правильно. Другой вариант у меня есть абстрактный класс, который будет работать для этого примера, но не тогда, когда у меня есть еще несколько интерфейсов (ICanAttack, ICanBuild)

с абстрактным классом

public abstract class LivingCreature : ICanMove 
{ 
    public abstract int speed {get;set;} 

    public void Walk() 
    { 
     //Example code Move(speed); 
    } 

    public void Run() 
    { 

    } 
} 

Но тогда моя проблема становится у меня есть реализовать несколько интерфейсов на базовый класс, который не каждый объект, который наследует от базового класса будет нуждаться в 100%

+0

Если вы не хотите, чтобы они реализовали его по-другому, тогда вы должны использовать абстрактный класс, как вы упомянули. –

+0

Для дальнейшего расширения моего комментария - интерфейс - это гарантия, что вы можете сделать что-то *, но не гарантию того, как вы это делаете. Абстрактный класс обеспечивает общедоступную функциональность. Вы можете создать абстрактный класс, который реализует интерфейс, а затем наследует от абстрактного класса. –

+0

Если вы создаете абстрактный класс, например «BaseMover», вы можете реализовать абстрактный класс ICanMove, а затем просто получить Worker и Warrior от IBaseMover. Проблема в том, что вы не можете выполнять множественное наследование, поэтому, имея BaseMover, вы также можете наследовать BaseBuilder, который стандартизирует реализацию интерфейса IcanBuild. –

ответ

1

Я предлагаю следовать шаблону стратегии для этого подхода.

Вы идете/работаете должны быть интерфейсами для движения.

Например, у вас может быть робот, который может только «рулить» и не бегать/ходить. Таким образом, движение этого робота должно быть Roll.

Первая глава в следующей книге поможет вам понять этот шаблон в отношении вашего текущего образца кода.

http://www.amazon.ca/Head-First-Design-Patterns-Freeman/dp/0596007124 (это на Java, но легко переводимый на C#) Эта книга также доступна бесплатно на многих сайтах.

Интернет-версия (бесплатно): http://www.dcc.ufrj.br/~comp2/TextosJava/Head%20First%20-%20Design%20Patterns.pdf

Этот SO вопрос также говорит о шаблоне стратегии с утками и летающими. Эта страница также является частью книги. Duck example strategy pattern - Head first design pattern

Например:

public interface IMovement 
{ 
    int speed { get; set; } 
} 

public class Worker 
{ 
    speed = 5; 
    IMovement Movement; 
    public Warrior(IMovement m) 
    { 
     this.Movement = m; 
    } 
    public void Move() 
    { 
     this.Movement.Move(); 
    } 
} 

public class Warrior 
{ 
    speed = 3; 
    IMovement movement; 

    public Warrior(IMovement m) 
    { 
     this.Movement = m; 
    } 

    public void Move() 
    { 
     this.Movement.Move(); 
    } 
} 

void foo() 
{ 
    IMovement m = new FlyingMovement(); 
    Worker w = new Worker(m); 

    IMovement swimmingMovement = new SwimmingMovement(); 
    SwimmingWorker sw = new SwimmingWorker (swimmingMovement); 
} 

К сожалению, я на мой телефон атм. Однако это даст вам больше универсальности в вашем коде.

+0

Мне нравится этот ответ. – DidIReallyWriteThat

+0

Итак, переверните его и ответьте на него, если он решает вашу дилемму. –

+0

:) Я обычно жду 24 часа, прежде чем я это сделаю. просто для тебя я буду :) – DidIReallyWriteThat

1

(на планшете в пабе атм, так что извиняйте опечатки и отсутствие примеров коды)

Ну, аналогия могла бы работать так метали по линиям супергероев: все они обладают рядом специальных способностей, но все они произвольны и различны. Способности «даются» на них внешним событием (Питер Паркер может подняться на стены, потому что его укусил паук).

Итак, ваша структура класса может быть такой, чтобы у вас был интерфейс iHasAbility, который реализует список iAbility. Вы можете наделить эти способности методом «Предоставить (ответственность)», а затем каким-то образом внедрить эти способности ... «Вступить (« climbwall »)».

Итак ... Композиция, а не абстракция. Способности становятся абстрактными, а не субъектом.

Надеюсь, что это поможет или даже просто искрится мысль.

0

Другой подход может заключаться в использовании вспомогательных классов (я прочитал отличный пример, используя Майкла Рыцаря и Китта на днях.

Итак, у вас есть класс (Iperson), которому могут помочь произвольные классы, которые реализуют что-то вроде «влияния (Iperson)».

Помощник «warriorhelper» может влиять на человека «забастовкой» и строителем-строителем «buildhome».

Опять же, надеюсь, это поможет!

Ps. Еще в пабе на планшете. Пожалуйста, извините опечатки и отсутствие примеров кода.

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