当前位置: 动力学知识库 > 问答 > 编程问答 >

linked list - How to add LinkedList functionality to a class

问题描述:

We have a base class Element that has numerous super classes such as ElementPicture. We store lists of Elements in a LinkedList class. The LinkedList class stores all elements in a LinkedListNode class which has members next, prev, value, & list. This all works as expected.

However, we're finding that we want the Element class itself to know the prev, next, & parent Element (each Element can have a body that is a list of Element objects). So the natural answer is for the LinkedList to hold a list of Element objects and those objects have the next, prev, & list members. And the value member goes away because the node is the value.

Is there a clean way of writing a library class that somehow is applied to the Element class giving it the LinkedListNode members? Generics can pass in a type for internal declarations but they can't do an extends. And even if they can, we presently have WrObject -> Element -> ElementPicture and without multiple inheritance there's no way to inject LinkedListNode into that.

The other thought was to create an ILinkedListNode interface, Element implements that, and that works. But we're then having to copy the methods & member data declarations across to it and that's not clean.

Any suggestions? We're using Typescript 1.5.

thanks - dave

网友答案:

Relevant reading: https://en.wikipedia.org/wiki/BaseBean

The only thing your classes need is a prev and next. All the LinkedList-specific things can be factored out into a module that provides functionality for LinkedList objects:

interface LinkedList<T> {
    prev: LinkedList<T>;
    next: LinkedList<T>;
}

class MyElement implements LinkedList<MyElement> {
    prev: MyElement;
    next: MyElement;

    name = 'bob';

    findThing() {
        return LinkedList.findNext(this, n => n.name === 'joe').name;
    }
}

module LinkedList {
    export function findNext<T extends LinkedList<{}>>(start: T, predicate: (x: T) => boolean): T {
        let current: T = start;
        while(current && !predicate(current)) {
            current = <T>current.next;
        }
        return current;
    }
}

This has several advantages:

  • It's not even possible for classes to accidently provide some nonstandard implementation of a LinkedList method
  • Smaller memory footprint of any given class instance
  • No danger of naming conflicts between class members and new Linked List functionality you might want to add in the future
  • It's clearer when you're doing a list operation vs a class operation

The real smell test here is that findNext (and other abstract list operations) doesn't ever need to refer to this. If you're not using this, why would you be on a class? FxCop would warn you about a nonstatic method not using this in a C# class for the same reason.

分享给朋友:
您可能感兴趣的文章:
随机阅读: