- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有以下简化的解析库存文件的要求,该文件包含汽车品牌字母和每行相应的规范字符串。例如:
A Sedan
B Blue
下面我提供了一个简化版的代码:
class StockManager
{
List<ICar> cars = new List<ICar>();
public StockManager(List<string> inventoryFileLines)
{
foreach(var inventoryFileLine in inventoryFileLines)
{
string[] parts = inventoryFileLine.Split(' ');
cars.Add(CreateCar(parts[0], parts[1]));
}
}
public decimal CalculateTotal()
{
decimal total = 0;
foreach(var car in cars)
{
total += car.GetPrice();
}
return total;
}
public ICar CreateCar(string brand, string spec)
{
if(brand == "A")
{
return new CarA(spec);
}else if(brand == "B")
{
return new CarB(spec);
}
throw new Exception();
}
}
interface ICar
{
decimal GetPrice();
}
class CarA : ICar
{
string type;
public CarA(string type)
{
this.type = type;
}
public decimal GetPrice()
{
if(type == "Sedan")
{
return 30000;
}
else if (type == "SUV")
{
return 50000;
}
throw new Exception();
}
}
class CarB : ICar
{
string color;
public CarB(string color)
{
this.color = color;
}
public decimal GetPrice()
{
if (color == "Orange")
{
return 20000;
}else if (color == "Red")
{
return 25000;
}
throw new Exception();
}
}
将来可能会添加新的品牌和规范。这是我应该预见并提供灵 active 的变化。现在我想应用正确的设计模式,但要出于正确的原因应用它们,而不仅仅是为了应用设计模式。 (正如 GoF 所说:“只有在实际需要其提供的灵 active 时才应应用设计模式。”)
我首先想到的是工厂方法或抽象工厂模式。所以当以后有新的汽车品牌C加入时:
工厂方法
将 CreateCar 设为虚拟并在我将使用的新 StockManager 类中覆盖它:
class StockManager2 : StockManager
{
public StockManager2(List<string> inventoryFileLines) : base(inventoryFileLines) { }
public override ICar CreateCar(string brand, string spec)
{
if (brand == "C")
{
...
}
return base.CreateCar(brand, spec);
}
}
抽象工厂
将CreateCar方法做成自己的抽象工厂类,提供给StockManager类。
如果我想在运行时使用不同的替代创建选项,例如多个有效的 CreateCar
工厂,这两种重构看起来都很棒。而GoF给出的Maze例子也扩展了这个思路。
但事实上,我预期的变化不是替代工厂,而是改造工厂。所以对我来说,修改 CreateCar
方法而不是创建一个新的工厂类并让旧的工厂类过时(这里指的是抽象工厂方法)似乎更合乎逻辑。在工厂方法的情况下,创建第二个 StockManager2 类也是如此。我知道开放/封闭原则(Robert Martin 的 SOLID 的 O)说不要修改类而是扩展它,而工厂模式正是这样做的但是上面的例子是否证明了它的使用,考虑到我在开头提到的可扩展性要求?似乎要求不是 GoF 中解释的意义上的扩展,而是真正的修改。但如果我错了,我希望得到纠正。
最佳答案
您可以使用运行时对象创建机制。因此,c# 将根据字符串创建类。唯一期望类名和给定的字符串必须相同。
但如果值不相同,您可以使用静态字典。这是代码:
public ICar CreateCar(string brand, string spec)
{
System.Type type = typeof( ICar ).Assembly.GetTypes().Where( t => t.Name == brand ).FirstOrDefault();
object instance = Activator.CreateInstance( type, new object[ 1 ] { specs } );
return (ICar)instance;
}
当然这个函数不处理任何错误,但它是容易的部分。顺便说一下,在您的代码中请使用 NotImplementedException 而不是 Exception 基类,因为这是您想要的:) 实现新品牌。
关于java - 工厂方法/抽象工厂模式的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53269400/
我对 java 中的抽象有点困惑。 我查了很多页面说抽象就是数据隐藏(隐藏实现)。 我对抽象的理解是它是“部分实现”。只需在抽象类/接口(interface)中定义您需要的内容,然后扩展/实现它们并添
我是 Ruby 的新手,主要来自 C# 和 ActionScript 3(以及其他语言)。我对抽象功能很好奇。具体来说,包装和抽象 Ruby 的 FTP 和 SFTP 库。 我四处搜索,发现了一个名为
目录 Java基础知识(抽象) 抽象 抽象定义 abstract的使用 定义抽象类
这个月我花了一些时间与 Emacs Lisp 进行斗争,试图获得更好地满足我需求的自动缩进。令人惊讶的是,大多数缩进代码是多么低级。我只看到了很少的抽象,例如 搜索不在字符串或注释中的第一个正则表达式
我有以下内容: public abstract class Foo{ //contents of Foo // ... public class Bar extends
我有三个类(class)(A 类、B 类和 C 类)。 类 A 调用 B 的实例并运行 start()。 B类扩展了Thread,因此当调用start()时,run()方法中的任何内容都会被执行。 在
这个问题已经有答案了: Calling a subclass method from superclass (5 个回答) 已关闭 7 年前。 Klasse1是一个抽象类,有一个 foo()方法。 K
我有一个这样的函数: def test(): x = "3" # In actual code, this is computed if x is None: retu
我有两个基类之间的关系: public abstract class RecruiterBase { // Properties declare here // Constructors de
这是我第一次发帖,但我遇到了很多问题。我目前有一个带有标题的 AbstractDevice 类: public abstract class AbstractDevice> implements De
我有一个 MotorDefinition 类和一个名为 Motor 的抽象类: class MotorDefinition { public: MotorDefinition(int p1,
是否有任何方法可以在这种代码(sass)中制定 css 的抽象规则: #cottage-image-gallery input:nth-of-type(1):checked ~ label:nth-o
是否可以声明一个已知的基类型并允许传输所有派生类型? [ServiceContract] public interface IService { [OperationContract]
我目前正在为基于 Java 的文本游戏开发角色生成机制,但我遇到了一个问题,看不出哪里出了问题。我有一个“Character”类,它是抽象的,然后是另一个类“NPCharacter”,它是建立在这个之
抱歉,标题令人困惑。不太确定如何表达它,这可能是问题所在! 我正在寻找一个好的抽象来用于涉及并发线程的情况。 我已经接近了,但还不是很清楚。 稍微简化一下,我在 Android 手机上收集了两种传感器
提前感谢您阅读本文。我不完全理解如何/何时使用摘要,所以我试图在我从事的每个项目中考虑它,看看它是否会在某一天全部点击 Smile | :) 此外,可访问性级别(私有(private)、 protec
我正在探索用于生成 Web 内容的 XML -> XSLT -> HTML 模因。我的 XSLT 经验很少。 我很好奇 XSLT 中有哪些机制可用于处理抽象或“重构”。 例如,使用通用 HTML 和服
在这些谈话中 Nicholas Zakas和 Addy Osmani他们讨论了在构建大型 Javascript 应用程序时将外观模式用作沙箱的想法,以便将应用程序与底层基础库分离。 这种解耦理论上允许
我使用C++和CUDA/C,想为特定问题编写代码,但遇到了一个非常棘手的简化问题。 我在并行编程方面的经验不容忽视,但相当有限,我无法完全预见到此问题的特殊性。 我怀疑是否有一种方便甚至“轻松”的方式
假设我有: trait A class B extends A class C extends A 有没有办法配置类型参数: class Foo[AType <: A with canCreateIn
我是一名优秀的程序员,十分优秀!