本文介绍了一种有趣的OOP方法:
如果对象作为封装存在,并通过消息进行通信怎么办?如果代码重用与继承无关,但使用组合,委托,甚至老式帮助对象或程序员认为合适的任何技术,该怎么办?本体不会消失,但它与实现分离.
没有继承或依赖于类层次结构的重用的想法是我发现最令人震惊的,但这有多可行?
给出了示例,但我不太清楚如何更改当前代码以适应此方法.
那么这种方法有多可行?或者是否真的不需要更改代码,而是基于场景的方法,即"仅在需要或最佳时使用"?
编辑:哎呀,我忘了链接:这里是链接
我正在使用OpenGL进行渲染.我的东西是沙箱,所以我使用CreateDesktop()来防止破碎攻击.但是,新桌面在出于任何原因创建时没有Aero组合(虽然默认情况下是这样)并且尝试使用DwmEnableComposition()启用它失败.我不知道为什么,或者如何解决这个问题.DwmEnableComposition()在默认桌面上运行正常.有没有办法让vs vsync在没有合成的情况下工作?即使从nvidia的驱动程序控制面板强制执行,我也无法做到这一点.这里有什么解决方案?
我正在使用Windows 7.在Windows 8中,他们说无法禁用合成,所以我想知道这个问题是否会再存在.
我有一个C++类来描述3D空间中对象的方向 - 位置,旋转,缩放等.我有其他类需要这样的信息(或其中的一部分) - 模型,地形,相机等.现在我可以创建我的方向类的子类,但谷歌告诉我更喜欢组合而不是继承.这种哲学是有道理的-一个模型是不是一个方向,它有一个(是的,我知道的就是,一个过一件事只是一个启发式).然而,对于所有那些可能的子类重写相同的包装器方法似乎是不必要的,几乎完全不太优雅,只需要获得该功能.事情model.getOrientation().set_x(1)似乎也很愚蠢.
我可以看出为什么这对于小对象来说不会"太糟糕",但是对于这个例子(以及其他类似的例子),如果你不得不通过箍来假装你正在使用继承,那么构成的重点是什么?我现在应该使用它吗?我几乎可以肯定我正在考虑这个问题.
假设我们有两个类,A并且B.当使用组合来建模"has-a"或"is-implemented-in-terms-of"关系(例如B has-a A)时,缺点与继承之一是B不包含A它需要的公共功能.为了获得对A公共函数的访问,有必要提供转发函数(与继承相反,B继承所有A的公共函数).
为了给出一个更具体的例子,假设我们有一个Person它具有-A ContactInfo:
using namespace std;
class ContactInfo
{
public:
ContactInfo();
void updateAddress(string address);
void updatePhone(string phone);
void updateEmail(string email);
private:
string address;
string phone;
string email;
};
class Person
{
public:
Person();
// Forwarding functions:
void updateAddress(string address){contactInfo.updateAddress(address)};
void updatePhone(string phone){contactInfo.updatePhone(phone)};
void updateEmail(string email){contactInfo.updateEmail(email)};
private:
ContactInfo contactInfo;
};
Run Code Online (Sandbox Code Playgroud)
在设计中忽略任何不足之处(这只是一个人为的例子来证明我下面的问题),我不得不不厌其烦地从复制确切函数签名ContactInfo中Person.在一个更复杂的例子中,可能有许多这样的函数,以及许多组合类的层,导致许多代码重复,具有所有常见的维护和容易出错的问题等. …
我理解为什么功能组成很重要.它允许从小而简单的功能构建大型复杂功能.
val f: A => B = ... val g: B => C = ... val h = f andThen g; // compose f and g
该构图符合身份和相关性法则.
关联性很有用,因为它允许f1 andThen f2 andThen f3 andThen f4 ...以任何顺序进行分组.现在我想知道为什么身份是有用的.
def f[T](t:T) = t // identity function val g: A => B = ... // just any function g andThen f[B] == f[A] andThen g
所以,我的问题是这个身份在哪里以及为何有用.
根据各种来源(2ality,esdiscuss),应该能够将mixins添加到类中:
编辑发现类方法不可枚举,因此无法工作.编辑了下面的代码,但仍然没有快乐
class CartoonCharacter {
constructor(author) {
this.author = author;
}
drawnBy() {
console.log("drawn by", this.author);
}
}
// THIS CANNOT WORK
// class methods are not enumerable
// class Human {
// haveFun() {
// console.log("drinking beer");
// }
// }
let Human = Object.create({}, {
haveFun: {
enumerable: true,
value: function () {
console.log("drinking beer");
}
}
});
class Simpson extends Object.assign(CartoonCharacter, Human) {
constructor(author) {
super(author);
}
}
let homer = new …Run Code Online (Sandbox Code Playgroud) 我正在使用Play的ActionBuilder创建各种保护我的控制器的操作.例如,我实现IsAuthenticated了以确保只有在用户登录时才能访问某些操作:
case class AuthRequest[A](user: String, request: Request[A]) extends WrappedRequest[A](request)
private[controllers] object IsAuthenticated extends ActionBuilder[AuthRequest] {
def invokeBlock[A](req: Request[A], block: (AuthRequest[A]) => Future[SimpleResult]) = {
req.session.get("user").map { user =>
block(new AuthRequest(user, req))
} getOrElse {
Future.successful(Results.Unauthorized("401 No user\n"))
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用IsAuthenticated我可以(1)将操作限制为已登录的用户,以及(b)访问登录的用户:
def auth = IsAuthenticated { implicit authRequest =>
val user = authRequest.user
Ok(user)
}
Run Code Online (Sandbox Code Playgroud)
此外,我使用ActionBuilder HasToken来确保在请求的标头中存在令牌时调用了一个动作(并且,我可以访问令牌值):
case class TokenRequest[A](token: String, request: Request[A]) extends WrappedRequest[A](request)
private[controllers] object HasToken extends ActionBuilder[TokenRequest] {
def invokeBlock[A](request: …Run Code Online (Sandbox Code Playgroud) authentication scala composition playframework playframework-2.0
public interface IMovable
{
void Move();
}
public interface IUnloadable
{
void Unload();
}
public class Vehicle : IMovable
{
public void Move()
{
Console.Write("moving");
}
}
public class Truck : IMovable, IUnloadable
{
private Vehicle Veh;
public Truck(Vehicle veh)
{
this.Veh = veh;
}
public void Move()
{
Veh.Move();
Console.Write("reverse with beepy noise as well");
}
public void Unload()
{
Console.Write("Unload");
}
}
Run Code Online (Sandbox Code Playgroud)
如果这是装饰模式.装饰者模式和构图之间有什么区别?我已经看到了使用继承的这种模式的例子.例如维基百科上的Java示例.
我根本没有看到需要使用继承,或者我错过了什么?
我想使用PHP实现图的下一个片段.
请参阅下面的组成示例图:
我们可以使用内部类在Java中实现组合.
但PHP中没有"内部类"的类比.当然,还有一些特点.但是我们可以在多个班级中使用它.
我已经实现了这样的组合:
class Head {
private static $instance = NULL;
private function __construct(){}
public static function getInstance() {
$traces = debug_backtrace();
if (strcmp($traces[1]['class'], 'Human')) {
echo "<br>Only human has head"; // Exception can be thrown here
return NULL;
}
if (!static::$instance) static::$instance = new self();
return static::$instance;
}
public function __toString() {
return 'Head';
}
}
class Human {
private $head;
public function __construct() {
$this->head = Head::getInstance();
}
public function __toString() {
return 'I …Run Code Online (Sandbox Code Playgroud) 好的,所以我最近已经开始加快了类,继承,接口以及它们如何相互作用.在此期间,我发现了一种普遍的声音蔑视继承和在各种论坛/博客/视频上赞成作曲.好的,冷静一些新的东西来学习.使用这个维基页面上的示例,我开始尝试更好地理解它...到目前为止我的成就似乎只是让自己更加困惑.
我的代码,然后我会解释我认为是错的.
MainClass.cs
class MainClass
{
static void Main(string[] args)
{
var player = new Player();
var enemy = new Enemy();
var entity = new Entity();
for(int i = 0; i < GameObject.GameObjects.Count; i++)
{
GameObject.GameObjects[i].Type();
GameObject.GameObjects[i].Draw();
GameObject.GameObjects[i].Move();
GameObject.GameObjects[i].Collision();
GameObject.GameObjects[i].Ai();
Console.WriteLine();
}
Console.ReadKey();
}
}
Run Code Online (Sandbox Code Playgroud)
GameObject.cs
interface IVisible
{
void Draw();
}
class Visible : IVisible
{
public void Draw()
{
this.Print("I am visible!");
}
}
class Invisible : IVisible
{
public void Draw()
{
this.Print("I am invisible!"); …Run Code Online (Sandbox Code Playgroud) composition ×10
inheritance ×4
oop ×4
c# ×2
c++ ×2
scala ×2
traits ×2
aggregation ×1
ecmascript-6 ×1
function ×1
javascript ×1
mixins ×1
opengl ×1
php ×1
sandbox ×1
windows ×1