当我一开始看到连接继承时,它对我来说就像一个组合,但人们一直将其命名为继承。然而,类使用原型来创建将对象连接在一起的原型链。现在的问题是,如果串联继承和类继承都做同样的事情,该使用哪一个?
这是两种场景串联继承的示例
function Person(name, address) {
const _name = name
const _address = address
const toString = () => `name: ${this.name}, address: ${this.address}`
return {
_name,
_address,
toString
}
}
function Employee(name, address, salary) {
const getAnnualSalary = () => 12 * salary
return Object.assign({ getAnnualSalary }, Person(name, address))
}
Run Code Online (Sandbox Code Playgroud)
类继承
class Person {
constructor(name, address) {
this.name = name
this.address = address
}
toString() { return `name: ${this.name}, address: ${this.address}` }
}
class Employee extends Person {
constructor(name, address, …Run Code Online (Sandbox Code Playgroud) 我昨天在一个继承自Bar的Foo类中写了这个:
public override void AddItem(double a, int b)
{
//Code smell?
throw new NotImplementedException("This method not usable for Foo items");
}
Run Code Online (Sandbox Code Playgroud)
随后想知道这是否可能表明我应该使用 Bar,而不是继承它.
还有哪些"代码味道"可以帮助在继承和组合之间做出选择?
编辑我要补充一点,这是一个片段,还有其它方法有相同之处,我只是不想去考虑太多的细节.我必须分析切换到合成的含义,并想知道是否可能有其他"代码味道"可能有助于提高平衡.
我有一个基于"实体"的程序,它包含"组件"(组成FTW).
组件可能包括许多不同的类型,包括脚本,资产等.我想构建一个名为Entity的函数
实体具有字符串映射和实际组件,以便可以按类型名称搜索组件.
我想要一个叫做的函数
<Component T>GetComponent(char* TypeName, <T>);
Run Code Online (Sandbox Code Playgroud)
其中包含字符串和类型名称,并返回所请求的类型化组件.
用C++模板做这样的事情有可能吗?以上显然不起作用,我不知道如何去做.
谢谢
编辑:
我不是在找工厂.
实体保存不同类型组件的实例.目前这已经完成了
std::vector<Component> componentList;
Run Code Online (Sandbox Code Playgroud)
和
std::vector<char*> componentNames;
Run Code Online (Sandbox Code Playgroud)
谁的索引保证是相同的.我可能稍后会写一张合适的地图.
我只是希望GetComponent返回一个正确类型的引用,该引用指向ComponentList中Entity持有的类型名称的已定时组件.
我在教程中得到了这个问题,我真的不知道如何去做.
为了确保
filter p . map f = map g . filter h
始终保持,必须如何用p和f定义g和h ?
任何指向正确方向的人都会非常感激.
我有三个函数xyz和一个名为functionComposer的函数.
我希望functionComposer将函数xyz作为参数,并返回一个函数,该函数使用y和z的结果作为x的参数并应用x.
在数学符号中: x(y(a),z(b))
我不是要求这个: functionComposer x y z = x.y.z
例如:
double x = x + x
summer x y = x + y
functionComposer summer double double = summer (double) (double)
Run Code Online (Sandbox Code Playgroud)
如果x = 2,结果应为8(2 + 2)+(2 + 2)
我正在为API编写客户端.一种方法,posts返回用户帖子的数组.
在具有继承的语言中,我将创建一个抽象基类Post,然后将其子类化为每种类型的帖子创建一个具体类.我会在基础构造函数或工厂方法Post,也许fromJson(),这需要一个JSON对象,并提取所有公共字段.然后我会在每个子类中覆盖它以提取专用字段,确保调用基本实现来干掉公共字段的提取.
Go没有继承,但它有组合.我定义了一个包含Post所有公共字段的结构,然后我为每个具有匿名Post字段的类型创建了一个结构,以便它包含所有Post字段.例如,
type PhotoPost struct {
Post // which contains: ID int; URL string; etc
Caption string
Height int
Width int
/// etc
}
Run Code Online (Sandbox Code Playgroud)
我的目标之一是我想让我的客户的用户轻松访问Post的公共字段.所以我绝对不希望只有Posts()我正在写的方法返回interface{},因为那时任何时候有人想要获取所有帖子的ID,例如,他们将不得不做一个可怕的类型切换,这将是一个使用的模式一遍又一遍让我畏缩:
func GetIDs(posts []interface{}) []int {
var ids []int
for _, p := range posts {
switch p.(type) {
case PhotoPost:
ids = append(ids, p.(PhotoPost).ID)
//... repeat for the 7 other kinds of posts, …Run Code Online (Sandbox Code Playgroud) 我目前正在阅读Graham Hutton撰写的“在haskell中编程”,并且刚刚接触到curring和函数组合。在练习部分中,有一个从头开始实现curry函数的任务,该任务已存在于前奏模块中。
这是我的实现,但是不起作用。有人可以解释一下(我是函数编程的新手)为什么它不起作用
my_curry :: ((a ,b) -> c) -> (a -> b -> c)
my_curry origFunc = origFunc.combine
where
combine e f = (e, f)
Run Code Online (Sandbox Code Playgroud)
这是错误[已添加]
[1 of 1] Compiling Main ( higher_order.hs, interpreted )
higher_order.hs:92:30:
Couldn't match type `t0 -> (a, t0)' with `(a, b)'
Expected type: a -> (a, b)
Actual type: a -> t0 -> (a, t0)
In the second argument of `(.)', namely `combine'
In the expression: origFunc . combine
In an equation for `my_curry': …Run Code Online (Sandbox Code Playgroud) 我正在从继承转向合成,如您从此处看到的/sf/ask/2075720741/
现在,我已经完成了所有工作,但是简单的注入器希望我手动注册传入的每种类型的每个接口。这是简化的代码。
我有IBaseEntityService,它由BaseEntityService实现
public interface IEntityBaseService<T> where T : class, IEntityBase
{
IDataContext Context { get; }
Task<ICollection<T>> GetAllAsync();
Task<T> GetAsync(long id);
}
public class EntityBaseService<T> : IEntityBaseService<T>
where T : class, IEntityBase
{
protected IDataContext _context;
public IDataContext Context
{
get
{
return _context;
}
}
public EntityBaseService(IDataContext context)
{
_context = context;
}
public async Task<ICollection<T>> GetAllAsync()
{
return await _context.Set<T>().ToListAsync();
}
public Task<T> GetAsync(long id)
{
return _context.Set<T>().Where(e => e.Id == id).FirstOrDefaultAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我有一个IValidationService和ValidationService实现了
public …Run Code Online (Sandbox Code Playgroud) 我希望有一些实用程序可以使用和清理资源,安全和不安全,并在使用后清理资源,有点相当于try/finally,即使操作抛出异常也允许清理.
我有
def withResource[R, U](create: => R, cleanup: R => Unit)(op: R => U): U = {
val r = create
val res = op(r)
cleanup(r)
res
}
def tryWithResource[R, U](create: => R, cleanup: R => Unit)(op: R => U): Try[U] = {
val tried: (R => Try[U]) = (r: R) => Try.apply(op(r))
withResource(create, cleanup)(tried)
}
Run Code Online (Sandbox Code Playgroud)
但我不喜欢
val tried: (R => Try[U]) = (r: R) => Try.apply(op(r))
Run Code Online (Sandbox Code Playgroud)
看来我缺少一些明显的构图功能,但我看不到哪里.我试过了
val tried: (R => Try[U]) = (Try.apply _).compose(op)
Run Code Online (Sandbox Code Playgroud)
但是这样做没有成功
type mismatch;
[error] …Run Code Online (Sandbox Code Playgroud) 我有一个管理的一些消息,像阿卡演员Find,Query中,提出了新的消息,其他类型的演员。这些参与者将以新型消息进行响应。
class Actorbase extends Actor {
override def receive = {
/* The two message below are related to each other */
case Find(coll, id) => // Do something
case QueryAck(key, value, u) => // Do something
/* The three message below are related to each other */
case Upsert(collection, id, value) => // Do something
case Response.UpsertNAck(key, msg, u) => // Do something
case Response.UpsertAck(key, u) => // Do something
/* And so on... */ …Run Code Online (Sandbox Code Playgroud) composition ×10
haskell ×3
inheritance ×2
oop ×2
scala ×2
.net ×1
akka ×1
architecture ×1
asp.net ×1
c# ×1
c++ ×1
currying ×1
dry ×1
factory ×1
go ×1
javascript ×1
refactoring ×1
templates ×1