我正在为邻居做一个小应用程序,目前对设计很困惑。一开始看起来很简单,但现在我被卡住了。我理解继承因此,
场景:用户通过其身份向商店赠送礼物(例如bday for family,bday for colleague )。所以有一个同事的生日礼物,不同于一个家庭的礼物。用户指定他们喜欢使用哪种包装样式。 (例如Origami,Western )在这种情况下,假设同事的生日礼物必须使用Origami下的生日风格包装。
但是如何将礼物与包装连接起来呢?起初包装看起来像是我的界面。所以礼物实现它。但是,包装每个主要包装样式具有子包装样式的事实使其变得复杂。同事的礼物对象生日怎么知道要实现哪个界面?它似乎是生日,婚礼也应该是抽象类,因为只有第3代礼品类才是具体的类。
如何让这个设计变得有意义而且现在很容易编码,以后可以进行修改/改进?
答案 0 :(得分:1)
为了将每件礼物与包装相关联,您不想要实现包装。那样不行。相反,将包装作为变量包含在Gift中。
你似乎有方法是使用抽象类(基本上是部分实现):
public abstract class Gift
{
public IWrappingStyle wrapping { get; private set; }
public Gift(IWrappingStyle wrapping)
{
this.wrapping = wrapping;
}
public void Unwrap()
{
// code common to all gifts for unwrapping
// ...
}
}
public interface IWrappingStyle
{
}
然后,您可以继续将第二级类型表示为包装样式的接口和礼品的抽象类,将类作为其他所需类型的最低级别。添加一个新的就像添加一个新类一样简单。
然后使用,你可以这样做:
Gift g = new GraduationSchoolGift(new OrigamiBirthdayWrapping());
别忘了使用文件夹!
但是,除非你对不同的包装有一些特定的不同行为,我认为你可以使用更简单的布局:
public class Gift
{
public String GiftType { get; private set; }
public String WrappingStyle { get; private set; }
public Gift(String giftType, String wrappingStyle)
{
this.GiftType = giftType;
this.WrappingStyle = wrappingStyle;
}
}
然后,如果您(再次)将文件整理到如下文件夹中:
以下是各自的文件(命名空间很重要):
礼品类型:
namespace GiftWrapping.GiftTypes
{
public class Birthday
{
public static const String FIFTH_BIRTHDAY = "Birthday Fifth";
public static const String TENTH_BIRTHDAY = "Birthday Tenth";
}
}
namespace GiftWrapping.GiftTypes
{
public class Wedding
{
public static const String FAMILY = "Wedding Family";
public static const String FRIENDS = "Wedding Friends";
}
}
包装样式:
namespace GiftWrapping.WrappingStyles
{
public class Origami
{
public static const String BIRTHDAY = "Origami Birthday";
public static const String WEDDING = "Origami Wedding";
}
}
namespace GiftWrapping.WrappingStyles
{
public class Western
{
public static const String SCHOOL = "Western School";
public static const String WEDDING = "Western Wedding";
public static const String UNIVERSITY = "Western University";
}
}
现在用法变为:
Gift g = new Gift(GiftTypes.Wedding.FAMILY,
WrappingStyles.Origami.BIRTHDAY);
答案 1 :(得分:0)
实际上写一个界面是一个很好的做法。在编写单元测试时,它们可以真正帮助您,并且是SOLID的基础。所以你可以试试像:
public interface IGift
{
public void Wrap(IWrappingStyle wrappingStyle)
{
}
}
public interface IWrappingStyle
{
}
有了这种对象依赖性,您可以使用策略模式之类的东西来根据类的类型来处理包装样式。
答案 2 :(得分:-1)
礼品和包装是单独的实体,使用依赖注入。
Class wrapping{
protected $gift;
public __construct( $gift ){
$this->gift = $gift
}
public getGift(){
return $this->gift;
}
}
Class gift{
}
$g = new gift()
$w = new wrapper($g);
这样您就不需要为每个新礼物更换包装,也不需要为每个新包装更换礼物。无论您是接口礼品,还是将其抽象取决于功能。包装也是如此。不要在“代码”级别混合它们,即使上图显示它们是单独的对象。
就我个人而言,我要么接受礼物,要么为它做一个基础抽象类。然后你可以依赖未来的礼物,包含你需要的代码。
我刚刚意识到这是C,我是怎么做到的。无论如何,即使它不是PHP,这个想法也是一样的。干杯。