Oop 这是哪种设计模式?

Oop 这是哪种设计模式?,oop,design-patterns,Oop,Design Patterns,我有一个关于设计模式的小问题 我有这两个类,它们是从同一个类(doctrine_record)扩展而来的,所以它们主要有相同的方法和函数,但是,它们现在有不同的属性。我想创建一个包装器,公开两个类和属性,我记得有一个模式,但我一直在看这本书,就是找不到它。我基本上想做的是映射属性,但是由于这些类中的每一个都将数据存储在不同的表中,因此我必须经常为每个类调用相同的方法(save()),因为将有大量的类,我不想为我拥有的每一对类编写完整的代码。你对我如何存档这个有什么建议吗 为了让自己更清楚,我将添

我有一个关于设计模式的小问题

我有这两个类,它们是从同一个类(doctrine_record)扩展而来的,所以它们主要有相同的方法和函数,但是,它们现在有不同的属性。我想创建一个包装器,公开两个类和属性,我记得有一个模式,但我一直在看这本书,就是找不到它。我基本上想做的是映射属性,但是由于这些类中的每一个都将数据存储在不同的表中,因此我必须经常为每个类调用相同的方法(save()),因为将有大量的类,我不想为我拥有的每一对类编写完整的代码。你对我如何存档这个有什么建议吗

为了让自己更清楚,我将添加一个简单的示例

我有这两个

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个内容翻译,因为处理特定内容所需的特定翻译变得非常重复,我希望合并这两个类,避免修改这两个类中的任何一个

我正在尝试创建一个类,我告诉它(如果在运行时更好)我拥有的两个类,它合并了它们,因此如果我引用某个内容(让我们称这个新类为节),它将同时具有两个类属性。如果我调用save()方法,我必须在两个对象上都调用它,我记得有这样一个模式,但我就是记不起它的de name

基本上,我在这里尝试做的是以下几点,假设我引用了一个节(它的类就是我试图创建的类)

因此,如果我这样做,我会得到我的内容和相应的英语翻译,我甚至可以访问这两者的属性

$section = new Section('1','en');
echo $section->number_clicks;
echo $section->title;
如果我修改其中任何一个并调用save()方法

这将在我的两个包含的类(content和content_translations)中的每个类上调用save()方法,因此信息存储在两个不同的表上,如果我这样做的话

$section = new Section('1','es');
$section->title = "titulo en español";
$section->save();
这只会改变对象的内容,因为我实例化了对象的“es”版本


希望你能帮助我:)并且提前谢谢你

这并不是一个真正的设计模式——你只需要在这一点上运用你的分析技巧

如果方法相同但字段不同,我会使用名为
attributes
的哈希表。您可以检查该属性是否存在。其中一个属性可以是
type
,以区分它们


如果只有少数几种类型,您可以潜在地进行多类,但如果您想添加超过(比如)10种的类型,则似乎是过度分类。

为了解决您的问题,我列举了三种设计模式:

我建议这样的解决方案:

///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();
  }
}

你能展示一下你想用上面显示的两个类做什么的代码吗?只是增加了一个例子:)
///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!