Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > A design problem I met again and again.

Reply
Thread Tools

A design problem I met again and again.

 
 
一首诗
Guest
Posts: n/a
 
      04-01-2009
Hi all,

I am a programmer who works with some different kinds of programming
languages, like python, C++(in COM), action script, C#, etc.

Today, I realized that, what ever language I use, I always meet a same
problem and I think I never solve it very well.

The problem is : how to break my app into functional pieces?

I know it's important to break an application to lots of pieces to
make it flexible. But it's easier said than done. I can split an
application to 4 or 5 pieces based on "programming functions", for
example, logging, socket, string, math, ...

When it comes to the business logic, I found I always provide a big
class with many methods, and it grow bigger when new functions are
added.

Recently I use twisted to write a server. It has several protocol
classes which decode and encode different kinds of network protocols ,
and a protocol independent service class which handle request from
clients according to business logic.

Protocol classes receive message from client, decode it, call method
of service, encode result and send it back to client.

There are also some utility packages such as logging as I mentioned
before.

So far so fine, every thing is clear.

Until one day I find service has nearly 100 methods and 6000 lines of
code. I don't need to read any programming book to know that it's
too big.

But I can not find an easier way to split it. Here are some
solutions I found:

1. add several business classes, and move code in service into them.
But this means although service will contains much less code, it still
has to keep lots of methods, and the only functions of these methods
is call corresponding methods in business classes. The number of
methods in service will keep growing for ever.

2. completely move codes in service to business classes containing
only classmethods. These protocol classes calls these classmethods
directly instead of call service. But this pattern doesn't look that
OO.

3. completely move codes in service to business classes. Initialize
these classes and pass them to protocol classes.
These protocol classes calls these instances of business classes
instead of call service. These means whenever I add a new business
class. I have to add a parameter to __init__ methods of every
protocol class. Not very clear either.

==========================================

I got the same problem when writing C#/C++ when I have to provide a
lot of method to my code's user. So I create a big class as the entry
point of my code. Although these big classes doesn't contains much
logic, they do grow bigger and bigger.
 
Reply With Quote
 
 
 
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      04-01-2009
In message <48506803-a6b9-432b-acef-
http://www.velocityreviews.com/forums/(E-Mail Removed)>, 涓棣栬瘲 wrote:

> Until one day I find service has nearly 100 methods and 6000 lines of
> code. I don't need to read any programming book to know that it's
> too big.


The question is not how many lines or how many methods, but whether it makes
sense to remain as one piece or not. In one previous project, I had one
source file with nearly 15,000 lines in it. Did it make sense to split that
up? Not really.

 
Reply With Quote
 
 
 
 
涓棣栬瘲
Guest
Posts: n/a
 
      04-01-2009
I also think that's my best choice. Before I wrote my mail, I
already knew that this is not a good question. It lacks details, and
it is too big.

But I think the first step to resolve a problem is to describe it. In
that way, I might find the answer myself

On Apr 1, 6:40*pm, "andrew cooke" <(E-Mail Removed)> wrote:
> 一首诗 wrote:
> > 3. completely move codes in service to business classes. *Initialize
> > these classes and pass them to protocol classes.
> > These protocol classes calls these instances of business classes
> > instead of call service. *These means whenever I add a new business
> > class. *I have to add a parameter to __init__ methods of every
> > protocol class. *Not very clear either.

>
> i don't fully understand your problem, but i would guess (3) is the
> correct solution. *you can probably avoid adding a new parameter by
> writing code in a generic way (using lists of arguments, perhaps using
> introspection to find method names, etc)
>
> andrew


 
Reply With Quote
 
涓棣栬瘲
Guest
Posts: n/a
 
      04-01-2009
On Apr 1, 4:55*pm, Lawrence D'Oliveiro <l...@geek-
central.gen.new_zealand> wrote:
> In message <48506803-a6b9-432b-acef-
>
> (E-Mail Removed)>, 涓棣栬瘲 wrote:
> > Until one day I find service has nearly 100 methods and 6000 lines of
> > code. * I don't need to read any programming book to know that it's
> > too big.

>
> The question is not how many lines or how many methods, but whether it makes
> sense to remain as one piece or not. In one previous project, I had one
> source file with nearly 15,000 lines in it. Did it make sense to split that
> up? Not really.


What are the average size of source files in your project? If it's
far lower than 15,000, don't feel it's a little unbalance?
 
Reply With Quote
 
Carl Banks
Guest
Posts: n/a
 
      04-01-2009
On Apr 1, 12:44 am, 一首诗 <(E-Mail Removed)> wrote:
> I got the same problem when writing C#/C++ when I have to provide a
> lot of method to my code's user. So I create a big class as the entry
> point of my code. Although these big classes doesn't contains much
> logic, they do grow bigger and bigger.



This seems to be a classic result of "code-based organization", that
is, you are organizing your code according to how your functions are
used. That's appropriate sometimes. Procedural libraries are often
organized by grouping functions according to use. The os module is a
good example.

However, it's usually much better to organize code according to what
data it acts upon: "data-based organization". In other words, go
though your big class and figure out what data belongs together
conceptually, make a class for each conceptual set of data, then
assign methods to classes based on what data the methods act upon.

Consider the os module again. It's a big collection of functions, but
there are a group of functions is os that all act on a particular
piece of data, namely a file descriptor. This suggests tha all the
functions that act upon file descriptors (os.open, os.close, os.seek,
etc.) could instead be methods of a single class, with the file
descriptor as a class member.

(Note: the os library doesn't do that because functions like os.open
are supposed to represent low-level operations corresponding to the
underlying system calls, but never mind that. Ordinarily a bunch of
functions operating on common data should be organized as a class.)


Carl Banks
 
Reply With Quote
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      04-02-2009
In message <158986a9-b2d2-413e-9ca0-
(E-Mail Removed)>, 涓棣栬瘲 wrote:

> On Apr 1, 4:55 pm, Lawrence D'Oliveiro <l...@geek-
> central.gen.new_zealand> wrote:
>
>> In message <48506803-a6b9-432b-acef-
>>
>> (E-Mail Removed)>, 涓棣栬瘲 wrote:
>> > Until one day I find service has nearly 100 methods and 6000 lines of
>> > code. I don't need to read any programming book to know that it's
>> > too big.

>>
>> The question is not how many lines or how many methods, but whether it
>> makes sense to remain as one piece or not. In one previous project, I had
>> one source file with nearly 15,000 lines in it. Did it make sense to
>> split that up? Not really.

>
> What are the average size of source files in your project? If it's
> far lower than 15,000, don't feel it's a little unbalance?


Why?

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      04-02-2009
On Thu, 02 Apr 2009 18:47:29 +1300, Lawrence D'Oliveiro wrote:

>>> The question is not how many lines or how many methods, but whether it
>>> makes sense to remain as one piece or not. In one previous project, I
>>> had one source file with nearly 15,000 lines in it. Did it make sense
>>> to split that up? Not really.

>>
>> What are the average size of source files in your project? If it's
>> far lower than 15,000, don't feel it's a little unbalance?

>
> Why?


If you have too much code in one file, it will upset the balance of the
spinning hard drive platter, and it will start to wobble and maybe even
cause a head-crash.



--
Steven
 
Reply With Quote
 
Tim Rowe
Guest
Posts: n/a
 
      04-02-2009
2009/4/1 一首诗 <(E-Mail Removed)>:
> Hi all,
>
> I am a programmer who works with some different kinds of programming
> languages, like python, C++(in COM), action script, C#, etc.
>
> Today, I realized that, what ever language I use, I always meet a same
> problem and I think I never solve it very well.
>
> The problem is : how to break my app into functional pieces?


One approach is to go through the specification of the program,
underline all of the significant nouns and try to implement each of
the nouns as a class. That won't take you all the way to a good design
-- some of the resulting classes will be too trivial, and it won't
give you the derived classes you need, but it's a good first step to
breaking a problem down, and might help break your one big class
habit.

--
Tim Rowe
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      04-02-2009
On Thu, 02 Apr 2009 07:45:46 -0400, andrew cooke wrote:

> Lawrence D'Oliveiro wrote:
>>> What are the average size of source files in your project? If it's
>>> far lower than 15,000, don't feel it's a little unbalance?

>>
>> Why?

>
> one reason is that it becomes inefficient to find code. if you
> structure code as a set of nested packages, then a module, and finally
> classes and methods, then you have a tree structure. and if you divide
> the structure along semantic lines then you can efficiently descend the
> tree to find what you want. if you choose the division carefully you
> can get a balanced tree, giving O(log(n)) access time. in contrast a
> single file means a linear scan, O(n).


What's n supposed to be? The number of lines in a file? No, I don't think
so -- you said it yourself: "if you divide the structure along semantic
lines then you can efficiently descend the tree to find what you want".
Not "arbitrarily divide the files after n lines". If one semantic
division requires 15,000 lines, and another semantic division requires 15
lines, then the most efficient way to divide the code base is 15,000
lines in one module and 15 lines in another.

Admittedly, I'd expect that any python module with 15,000 lines
(approximately 900KB in size) could do with some serious refactoring into
modules and packages, but hypothetically it could genuinely make up a
single logical, semantic whole. That's "only" four and a half times
larger than decimal.py.

I can't imagine what sort of code would need to be that large without
being divided into modules, but it could be possible.



--
Steven
 
Reply With Quote
 
一首诗
Guest
Posts: n/a
 
      04-02-2009
You get it. Sometimes I feel that my head is trained to work in a
procedural way. I use a big class just as a container of functions.

About the "data-based" approach, what if these functions all shares a
little data, e.g. a socket, but nothing else?

On Apr 2, 5:58 am, Carl Banks <(E-Mail Removed)> wrote:
> On Apr 1, 12:44 am, 一首诗 <(E-Mail Removed)> wrote:
>
> > I got the same problem when writing C#/C++ when I have to provide a
> > lot of method to my code's user. So I create a big class as the entry
> > point of my code. Although these big classes doesn't contains much
> > logic, they do grow bigger and bigger.

>
> This seems to be a classic result of "code-based organization", that
> is, you are organizing your code according to how your functions are
> used. That's appropriate sometimes. Procedural libraries are often
> organized by grouping functions according to use. The os module is a
> good example.
>
> However, it's usually much better to organize code according to what
> data it acts upon: "data-based organization". In other words, go
> though your big class and figure out what data belongs together
> conceptually, make a class for each conceptual set of data, then
> assign methods to classes based on what data the methods act upon.
>
> Consider the os module again. It's a big collection of functions, but
> there are a group of functions is os that all act on a particular
> piece of data, namely a file descriptor. This suggests tha all the
> functions that act upon file descriptors (os.open, os.close, os.seek,
> etc.) could instead be methods of a single class, with the file
> descriptor as a class member.
>
> (Note: the os library doesn't do that because functions like os.open
> are supposed to represent low-level operations corresponding to the
> underlying system calls, but never mind that. Ordinarily a bunch of
> functions operating on common data should be organized as a class.)
>
> Carl Banks


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
I met a problem using vs 2005 Vivienne C++ 4 01-30-2007 01:08 PM
Bit Problem I met with IAR's C++ Compiler Steven Woody C++ 2 11-14-2005 03:32 PM
I used windows 64bit edition and met one problem =?Utf-8?B?R2xvb215b3JTaGlueQ==?= Windows 64bit 1 09-29-2005 03:10 PM
Met Problem with Distutils steven@lczmsoft.com Python 1 03-01-2005 05:48 AM
I met the same problem and i have no idea on this! need help Jay Ge ASP .Net 1 11-10-2004 12:36 AM



Advertisments