TL;DR 共享库实现了一些在库本身和使用该库的项目中使用的类。项目继承该类来添加项目特定的代码。 是否也有一些设计模式/最佳实践来在库中使用该项目特定的子类?
详情:
我创建了一个库(Swift 包),其中包含我在多个 iOS 应用程序项目中使用的代码和类。
例如
ThemeManager
类处理不同控件的样式和布局:
// In Shared Package
public class ThemeManager {
public class func styleLabel(_ label: UILabel) {
// Apply default style to label
}
}
public class SharedViewController: UIViewController {
func applyStyle() {
ThemeManager.styleLabel(someLabel)
}
}
使用该包的项目现在可以扩展
ThemeManager
以应用其自己的、项目特定的样式。
// In Project
public class ProjectThemeManager: ThemeManager {
override public class func styleLabel(_ label: UILabel) {
// Apply project style to label
}
}
如果在项目中使用
SharedViewController
,它仍会使用 someLable
中定义的默认样式设置 ThemeManager
的样式,而不是使用 ProjectThemeManager
。
当然有不同的方法来解决这个问题。例如,
SharedViewController
可以简单地使用var themeManager: ThemeManager
来代替,它必须设置为项目中所需的类型。然而,如果 ThemeManager
不是在一个地方使用而是被很多很多不同的类使用,这将非常麻烦。
另一种解决方案是使用一些必须由项目配置的中心实例,并且库代码从那里获取正确的类型/实例。
所以,问题不是是否可以解决这个问题,而是是否有现有的 OOP 设计模式或最佳实践来解决此类问题。
使用该包的项目现在可以扩展 ThemeManager 以应用其自己的、项目特定的样式。 如果在项目中使用 SharedViewController,它仍然会使用 ThemeManager 中定义的默认样式来设置 someLable 的样式,而不是使用 ProjectThemeManager。
看起来你需要根据某些条件应用各种样式。如果我们将不同的样式称为策略,那么我们可以得出结论,有必要应用样式策略,这取决于某些原因。
因此,可以在这里应用策略模式。它还增强了“关注点分离”。我的意思是一个班级只有一个目标。 假设我们有一些应该根据类型调用的各种
LabelStyles
。让我通过 C# 展示一个代码片段。
所以标签样式的代码如下所示:enum LabelStyleType
{
ThemeManager, ProjectThemeManager
}
LabelStyle 的抽象看起来像这样:
public abstract class LabelStyleBase
{
public DateTime StartDateTime { get; set; } = DateTime.Now;
public abstract string Get();
}
具体的实现是这样的:
public class ThemeManagerStyle : LabelStyleBase
{
public override string Get() =>
"I am ThemeManagerStyle. Object created: " + StartDateTime.ToString();
}
public class ProjectThemeManagerStyle : LabelStyleBase
{
public override string Get() =>
"I am ProjectThemeManagerStyle. Object created: "
+ StartDateTime.ToString();
}
然后
LabelStyleFactory
看起来像这样:
public class LabelStyleFactory
{
private Dictionary<LabelStyleType, LabelStyleBase> _labelStyleByType;
public LabelStyleFactory()
{
_labelStyleByType = new Dictionary<LabelStyleType, LabelStyleBase>()
{
{ LabelStyleType.ThemeManager, new ThemeManagerStyle() },
{ LabelStyleType.ProjectThemeManager, new ProjectThemeManagerStyle() }
};
}
public LabelStyleBase GetInstance(LabelStyleType userInput) =>
_labelStyleByType[userInput];
}
然后你可以在需要的地方调用你的LabelStyle,如下所示:
string GetLabelStyleByUserInput(LabelStyleType labelStyleType)
{
LabelStyleFactory labelStyleFactory = new LabelStyleFactory();
LabelStyleBase labelStyle = labelStyleFactory.GetInstance(labelStyleType);
return labelStyle.Get();
}
可以看出,如果添加新的LabelStyle,就会将其添加到
LabelStyleFactory
类中,并且它符合单一职责原则和开放封闭原则