如何围绕面向对象设计进行思考
How to wrap my head around Object Oriented Design
面向对象设计是一个非常简洁的概念,但我正在努力思考如何围绕它的大部分方面进行思考。我认为良好的面向对象设计的关键是掌握如何看待它。我通常是这样看待面向对象的:
类 是真实世界的实体或对象
实例字段是实体的属性,('has A')
方法就像动作、动词、实体的能力
接口就像可以赋予对象的能力。它也可以是 'is A or can do' 关系,其实现不是一成不变的。超人是氪星,作为氪星人具有一系列特殊能力,如飞行、冻结呼吸等。超人的飞行不同于绿灯侠和悟空,尤其是蝙蝠侠,这就是为什么如果你将飞行作为界面可能是个好主意正在创造一个虚构的宇宙。
public class SuperMan extends Man implements Kryptonian{}
public interface Kryptonian extends Flight, FreezeBreath{
public void fly();
public void coolBreath();
}
将泛型添加到组合中时会出现问题吗?因为给定的类型参数以某种方式在 class/interface 和类型之间创建了契约。
public interface Flight<T>{
public void fly(T t);
}
在这个例子中,Flight 加上了一个 T,T 可以是一个超级英雄,一只鸟或者任何可以 fly.But 的东西,真的是我想象中的样子吗?因为这看起来与普通接口所做的一样?虽然,参数化接口仍然是接口,但与类型 T 的耦合才是真正困扰我的地方。此外,当您对参数类型添加有界限制时,事情也会变得复杂。
public class Pidgey<T extends Bird> implements Flight<T>{}
你能将 T 与现实世界中的哪个具体对象联系起来?上面的例子是错误的,虽然使用 class 参数来限制 Flight 的类型可能是一个很好的设计,因为 Flight 仍然足够独立,其他 classes 仍然可以不受任何限制地使用它.但是这个例子本身是错误的。 Pidgey 是一只会飞的鸟,但 T 会是什么呢?好吧,T 可以是任何东西,它可以是另一个对象或能力。问题是它的含义是什么,为什么要把 T 放在那里?这样做的真实例子有哪些?
当你谈论集合时很容易理解,因为集合就像容器。您可以创建各种各样的容器来容纳不同种类的对象。
public class WaterBottle<T extends Liquid> implements UniqueCap{}
但我看到泛型不仅用于类似容器的对象?怎么设计这样的东西,他们是怎么考虑的?
您对 OOP 中各种功能的类比绝对是正确的。在谈论 collections/containers/Hashmaps 时,泛型绝对最有意义。不过,它们确实在其他地方也有用途。例如,如果银行要处理多种货币的票据,他们可以写
public class 货币处理器
但是,泛型不是必需的。在 Flight
接口的上下文中,没有太多理由使用泛型。这让我想到了另一点:
仅仅因为其他人以一种方式做某事并不意味着你必须那样做。 OOP 非常灵活是有原因的。永远有不止一种正确的方法。如果一个方法将 Object
作为参数,那还不是世界末日。只要确保您以后可以阅读它即可。 :)
编辑:其他人也可以阅读。
处理泛型时使用 T 的惯例。它使代码可读,因为其他人阅读您的代码会立即知道您指的是通用的,没有什么具体的
面向对象设计是一个非常简洁的概念,但我正在努力思考如何围绕它的大部分方面进行思考。我认为良好的面向对象设计的关键是掌握如何看待它。我通常是这样看待面向对象的:
类 是真实世界的实体或对象
实例字段是实体的属性,('has A')
方法就像动作、动词、实体的能力
接口就像可以赋予对象的能力。它也可以是 'is A or can do' 关系,其实现不是一成不变的。超人是氪星,作为氪星人具有一系列特殊能力,如飞行、冻结呼吸等。超人的飞行不同于绿灯侠和悟空,尤其是蝙蝠侠,这就是为什么如果你将飞行作为界面可能是个好主意正在创造一个虚构的宇宙。
public class SuperMan extends Man implements Kryptonian{}
public interface Kryptonian extends Flight, FreezeBreath{
public void fly();
public void coolBreath();
}
将泛型添加到组合中时会出现问题吗?因为给定的类型参数以某种方式在 class/interface 和类型之间创建了契约。
public interface Flight<T>{
public void fly(T t);
}
在这个例子中,Flight 加上了一个 T,T 可以是一个超级英雄,一只鸟或者任何可以 fly.But 的东西,真的是我想象中的样子吗?因为这看起来与普通接口所做的一样?虽然,参数化接口仍然是接口,但与类型 T 的耦合才是真正困扰我的地方。此外,当您对参数类型添加有界限制时,事情也会变得复杂。
public class Pidgey<T extends Bird> implements Flight<T>{}
你能将 T 与现实世界中的哪个具体对象联系起来?上面的例子是错误的,虽然使用 class 参数来限制 Flight 的类型可能是一个很好的设计,因为 Flight 仍然足够独立,其他 classes 仍然可以不受任何限制地使用它.但是这个例子本身是错误的。 Pidgey 是一只会飞的鸟,但 T 会是什么呢?好吧,T 可以是任何东西,它可以是另一个对象或能力。问题是它的含义是什么,为什么要把 T 放在那里?这样做的真实例子有哪些?
当你谈论集合时很容易理解,因为集合就像容器。您可以创建各种各样的容器来容纳不同种类的对象。
public class WaterBottle<T extends Liquid> implements UniqueCap{}
但我看到泛型不仅用于类似容器的对象?怎么设计这样的东西,他们是怎么考虑的?
您对 OOP 中各种功能的类比绝对是正确的。在谈论 collections/containers/Hashmaps 时,泛型绝对最有意义。不过,它们确实在其他地方也有用途。例如,如果银行要处理多种货币的票据,他们可以写 public class 货币处理器
但是,泛型不是必需的。在 Flight
接口的上下文中,没有太多理由使用泛型。这让我想到了另一点:
仅仅因为其他人以一种方式做某事并不意味着你必须那样做。 OOP 非常灵活是有原因的。永远有不止一种正确的方法。如果一个方法将 Object
作为参数,那还不是世界末日。只要确保您以后可以阅读它即可。 :)
编辑:其他人也可以阅读。
处理泛型时使用 T 的惯例。它使代码可读,因为其他人阅读您的代码会立即知道您指的是通用的,没有什么具体的