OO编程如何正确设计我的类 [英] OO Programming how to design my classes properly

查看:47
本文介绍了OO编程如何正确设计我的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我正在写一个网络流量分析器。 (使用Pcap.Net和LibPcap。)

在我的设计中,我有一个名为Controller的顶级类,而Controller创建了PacketBuffer的实例(二级类),PacketAnalyzer ,DatabaseWriter。

如下所示。



所有类都需要从Controller获取信息以相互协调,所以在某些类中,我通过这个(作为控制器)到二级课程。这似乎没问题吗?



大多数班级都会完成工作,并从sharedResultQueue存储或获取结果,sharedResultQueue是Controller的私人成员。

我将这个成员传递给二级课程,以便他们可以访问它。

看起来好吗?



谢谢!



Hi,

I am writing an network traffic analyzer. (using Pcap.Net and LibPcap.)
In my design, I have a top-level class called "Controller", and Controller creates instance (2nd-level classes) of "PacketBuffer", "PacketAnalyzer", "DatabaseWriter".
Like below.

All the classes need to get information from the Controller to coordinate with each other, so in some classes, I pass "this" (as a Controller) to the 2nd-level classes. Does this seem all right?

Most of the classes do their jobs, and store or get results from "sharedResultQueue", which is a private member of the Controller.
And I pass this member to the 2nd-level classes so they can access it.
Does this seem all right?

Thanks!

Class Controller
{
    private PacketBuffer _buffer = new ...;
    private PacketAnalyzer _analyzer;
    private DatabaseWriter _writer;
    private Queue<...> _sharedResultQueue = new Queue<...>;

    public Controller()
    {
        _analyzer = new PacketAnalyzer(this, _buffer, _sharedResultQueue);
        _writer = new DatabaseWriter(this, _sharedResultQueue);
    }
    ...
}

Class PacketBuffer
{
    ...
}

Class PacketAnalyzer
{
    private Controller _controller;
    private PacketBuffer _buffer;
    private Queue<...> _sharedResultQueue;

    public PacketAnalyzer(Controller controller, PacketBuffer buffer, Queue<...> sharedResultQueue)
    {
        _controller = controller;
        _buffer = buffer;
        _sharedResultQueue = shareResultQueue;
    }
    ...
}

Class DatabaseWriter
{
    private Controller _controller;
    private Queue<...> _sharedResultQueue;

    public DatabaseWriter(Controller controller, Queue<...> sharedResultQueue)
    {
        _controller = controller;
        _sharedResultQueue = shareResultQueue;
    }
    ...
}

推荐答案

考虑使用委托概念。 了解C#中的代表初学者



最好不要将类硬链接在一起,而是通知控制器作业已完成并且可以获取数据。最好使用本机数据类型或语言类作为接口,以便将来的更改很容易,代码也不会出现在一些粘合的意大利面上。 ;-)



注意死锁和参考周期。如果数据不是太多,最好是在自己的缓冲区中传输数据。
Consider using the delegate concept. Understanding Delegates in C# for Beginners.

It is better not to hard link the classes together, but informing the controller that the job is done and it can get the data. It is better to use native data type or classes of the language as interface so future changes are easy and the code isnt get to some glued spaghetti. ;-)

Watch out for deadlock and reference cycles. Best is transfering data in a own buffer if it is not too much.


这可能会对你有帮助。

最近,我使用.Net Concurrent Collection实现了一个队列它为您处理线程。这使用了生产者 - 消费者模式。





This may help you.
Recently, I implemented a Queue using .Net Concurrent Collection which does the thread handling for you. This uses the producer-consumer pattern.


using System.Collections.Concurrent;
public class DHCP_Queue
    {
        public event EventHandler DataReceived;

        private ConcurrentQueue<DHCP_Packet> packetQueue;

        public DHCP_Queue()
        {
            this.packetQueue = new ConcurrentQueue<DHCP_Packet>();
        }

        protected virtual void OnDataReceived(EventArgs e)
        {
            if(DataReceived!=null)
            {
                DataReceived(this, e);
            }
        }

        public void Produce(DHCP_Packet newPacket)
        {
            this.packetQueue.Enqueue(newPacket);
            OnDataReceived(EventArgs.Empty);
        }

        public List<DHCP_Packet> ConsumeAll()
        {
            List<DHCP_Packet>  latestPackets = new List<DHCP_Packet>();
            DHCP_Packet packet = new DHCP_Packet();
            while(this.packetQueue.TryDequeue(out packet))
            {
                latestPackets.Add(packet);
            }
            return latestPackets;
        }
    }


考虑在方法的签名中使用ref关键字,而不是传递对类的引用修改sharedResultQueue。更多信息 https://msdn.microsoft.com/en-us/library/14akc2c7.aspx [ ^ ]



每个需要修改结果队列的类都应该有一个类似于以下签名的方法:

void addResultsTo(ref Queue< ...> sharedResultQueue )

{



}



最佳做法是创建包含此方法签名的接口,将由需要修改sharedResultQueue的所有类实现。



更新:此​​外,您应该了解SOLID原则,尤其是Liskov替代原则&在决定你的设计之前,依赖性倒置原则。
Instead of passing a reference to the class, consider using the "ref" keyword in the signature of the methods that modify the "sharedResultQueue". More info https://msdn.microsoft.com/en-us/library/14akc2c7.aspx[^]

Each class that needs to modify the results queue should have a method with a signature similar to :
void addResultsTo(ref Queue<...> sharedResultQueue)
{

}

A best practice would be to create a interface that contains this methods signature, which will be implemented by all classes that need to modify the "sharedResultQueue".

Update: Also, you should understand the SOLID principles, particularly the Liskov substitution principle & the Dependency inversion principle, before deciding on your design.


这篇关于OO编程如何正确设计我的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆