Какой шаблон дизайна это делает? - PullRequest
2 голосов
/ 03 февраля 2010

У меня небольшой вопрос по поводу шаблонов проектирования

У меня есть эти 2 класса, которые выходят из одного и того же класса (doctrine_record), поэтому они в основном имеют одни и те же методы и функции, однако теперь они имеют разные атрибуты. Я хотел бы создать оболочку, которая выставляет атрибуты суммирования двух классов, я помню, что для этого был шаблон, но я просматривал книгу и просто не мог ее найти. То, что я в основном пытаюсь сделать, это атрибуты карты, однако, так как каждый из этих классов хранит свои данные в разных таблицах, мне придется часто вызывать один и тот же метод (save ()) для каждой, так как их будет много. классы, за которые я собираюсь жениться, я не хочу писать целый код для каждой пары классов, которые у меня есть. Есть ли у вас какие-либо предложения по архивированию?

Чтобы прояснить ситуацию, я добавлю простой пример

У меня есть эти 2

class Content extends doctrine_record
{
    int content_id;
    date create_date;
    date modified_date;
    int number_clicks;  
    Content_translations translations[];
}

class Content_translations extends doctrine_record
{
    int translation_id;
    int content_id;
    string language;
    string content;
    string title;
}

Как видите, 1 Контент может иметь N Content_translations , поскольку работа с определенным переводом, который мне нужен для определенного контента, становится очень повторяющейся объединить эти 2 класса, избегая изменения любого из 2.

Я пытаюсь создать класс, в котором я скажу (лучше, если во время выполнения) 2 класса, которые у меня есть, и он объединяет их, поэтому, если я создаю экземпляр определенного содержимого (давайте назовем эти новые секции классов), у него будут оба класса атрибутов. и если я вызову метод save (), мне придется вызывать его для обоих объектов, я помню, что есть такой шаблон, но я просто не могу вспомнить его имя.

То, что я в основном пытаюсь сделать здесь, это следующее, скажем, я создаю экземпляр Раздела (класс которого я пытаюсь создать)

поэтому, если я сделаю это, я получу свой контент и соответствующий перевод на английском языке, и я даже смогу получить доступ к атрибутам обоих

$section = new Section('1','en');
echo $section->number_clicks;
echo $section->title;

и если я изменю любой из них и вызову метод save ()

$section = new Section('1','en');
$section->number_clicks = $section->number_clicks+1;
$section->title = "new title";
$section->save();

это вызовет метод save () для каждого из моих двух содержащихся классов (content и content_translations), поэтому информация будет храниться в 2 разных таблицах, теперь, если я сделаю это

$section = new Section('1','es');
$section->title = "titulo en español";
$section->save();

это только изменит объект content_translations, так как я установил версию моего объекта 'es'

Надеюсь, вы мне поможете :) и заранее спасибо

Ответы [ 2 ]

1 голос
/ 03 февраля 2010

Чтобы решить вашу проблему, я считаю три шаблона проектирования: Адаптер , Композит , Заводской метод .

Я предлагаю решение примерно так:

///Adapter. To adopt current classes to specific hierarchy
abstract class AbstractSection
{
   public void Save();
}

class TranslateSection : AbstractSection
{
  public override void Save()
  {
     //saves current translate version
  }
}

class ConcreteSection : AbstractSection
{
  public ConcreteSection(IEnumerable<TranslateSection> translates)
  {
    translates.AddRange(translates);
  }
  //For simplification only!
  public ConcreteSection(TranslateSection translates)
  {
    translates.AddRange(translates);
  }
  public ConcreteSection()
  {
  }
  public override void Save()
  {
     SaveCurrentSection(); //Save current ConcreteSection
     //Save translates
     foreach(var t in translates)
        t.Save();
  }

  //Slitly modified Composite pattern
  private List<TranslateSection> translates = new List<TranslateSection>();
  private Content content;

  //To inner content we can access directly:
  Content GetContent() {return content;}
  Content Content { get {return content;} }
  //Or we can wrap this with some methods (or something else)
  int GetContentId() {return content.content_id;}
  void SetContentId(int contentId) {content.content_id = contentId;}

  //To simplify access to translate sections we can use something like this
  TranslateSection GetTranslateSection() {return translates[0];}
}

//Factory method design pattern to simplify object creation
class SectionFactory
{
  public static AbstractSection Create(string locale)
  {
     //dependend on locale (or locales) we can create 
     //one or more translates
     if ( locale == 'en' )
       return new ConcreteSection(CreateEnglishTranslateSection());
     //in some circumstances we need only simple section
     //without translates
     return new ConcreteSection();
  }
}

Использование:

var section = SectionFactory::Create('en');
section.Save(); //here we save both sections
Console.WriteLine(section.number_clicks);
Console.WriteLine(section.GetTranslation().title);

var section = SectionFactory::Create('es');
section.Save(); //saves only 'es' section
Console.WriteLine(section.number_clicks); //we can access to this field (or property)
Console.WriteLine(section.GetTranslation().title); //here we got runtime failure!
1 голос
/ 03 февраля 2010

Для этого на самом деле нет шаблона проектирования - вам просто нужно использовать свои аналитические навыки на этом.

Если у вас одинаковые методы, но разные поля, я бы использовал Hashtable с именем attributes. Вы можете проверить наличие атрибута. Одним из атрибутов может быть type, чтобы различать их.

Если есть только несколько типов, вы могли бы потенциально мультиклассировать, но это выглядело бы как переклассификация, если вы хотите добавить больше, скажем, 10.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...