2016-07-27 2 views
2

Недавно я узнал о composite pattern. Я хочу использовать его в своем задании, которое я должен реализовать для классов File и Folder. Я понимаю, что подклассы, такие как CFile и Cfolder, имеют одинаковые атрибуты (name и size). Так хорошо для меня, чтобы положить атрибуты в interface? Насколько я знаю, это не очень хорошая практика. Однако я не понимаю, почему я не должен. Или есть другие решения? Class DiagramМожно ли положить данные в интерфейс?

+0

C++ не имеет отчетливый "интерфейс", просто абстрактные классы. В интерфейсе, например. Java, просто невозможно иметь переменные. – deviantfan

+0

Если вы храните их в абстрактном базовом классе (без интерфейсов на C++) в качестве общедоступных полей, то вы несете бремя для разработчика производного класса, чтобы обновлять поля. Если вы поместите их в базовый класс как виртуальные (чистые) геттеры, то вы заставите исполнителя задуматься о них. –

ответ

2

Я бы сказал, что это не проблема. Разница в том, что вместо чистого класса интерфейса у вас есть базовый класс . Однако, если вы хотите сохранить гибкость в использовании интерфейса для реализаций, которые не привязаны к этим конкретным переменным-членам, вы всегда можете создать класс интерфейса , а также базовый класс для полной гибкости. Хотя это может быть слишком сложным, слишком рано, вы всегда можете разделить интерфейс от аннотация базы позже, если вам нужно.

using CItemUPtr = std::unique_ptr<class CItem>; 

/** 
* Interface class 
*/ 
class CItem 
{ 
public: 
    virtual ~CItem() {} 

    virtual CItemUPtr findByName(std::string const& name) = 0; 
    virtual void setHidden(bool a, bool b) = 0; 
}; 

/** 
* Abstract base class 
*/ 
class AbstractCItem 
: public CItem 
{ 
protected: 
    std::string name; 
    std::size_t size; 
}; 

class CFile 
: public AbstractCItem 
{ 
public: 

    CItemUPtr findByName(std::string const& name) override 
    { 
     // stuff 
     return {}; 
    } 

    void setHidden(bool a, bool b) override {} 
}; 
3

На самом деле это не вопрос «это хорошая практика». Создавая интерфейс, вы определяете стандарт. Вопрос в том, вам НЕОБХОДИМО реализовать интерфейс, чтобы содержать эти элементы данных? Вы находитесь в лучшем положении, чтобы понять вашу реализацию, так что вы действительно единственный, кто может ответить на это.

Как правило, класс, реализующий интерфейс, должен быть черным ящиком, а внешний мир не должен иметь доступа к каким-либо внутренним элементам (включая данные членов). Интерфейсы определяют общую функциональность, которая требуется для поддержки интерфейса, и я ожидал бы, что эти детали реализации будут похоронены в базовой реализации класса только в качестве общего правила. YMMV.

0

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

Однако, если класс не имеет инварианта к классу, то
Публичные члены получают то же самое.

// in C++, this is a perfectly fine, first order class 
struct Pos 
{ 
    int x,y; 
    Pos& operator+=(const Pos&); 
}; 

также см https://en.wikipedia.org/wiki/Class_invariant

+1

Что это связано с интерфейсами? –

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