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