2

I'm a computer science student and on one of my recent projects I have been dealing with constructing a simple application that is maybe an example of large/medium-scale programming. It's first implementation will be in C language and we will then reconstruct it in Java.

This has made me question the OOP principles about encapsulation and how to achieve it and also how to design a system through the MVC architecture.

Without further ado, here's my problem in a very simplified way:

Let's say I have the following two classes:

a.h
typedef struct a *A;

void insert_into_a(A a, something_to_insert s);
void do1(A a);
stuff do2(A a);
b.h
typedef struct b *B;

void insert_into_b(B b, something_to_insert s);
void do3(B b);
some_value do4(B b);

Note: I am aware that hiding pointers might be criticizable but it was requested to be done so, please, ignore that fact.

Those two classes are pieces of the same final goal but don't directly have a relation. So my interest is on how to build a third, C class, that will interact with those two, without breaking encapsulation. This C class must be able to load the subclasses (A and B) and perform queries on them (it kinda acts like a database) and this was my approach:

c.c
struct c{
    A a;
    B b;
};

void insert_into_a_through_c(C c, something_to_insert s){
    insert_into_a(c->a, s);
}

void insert_into_b_through_c(C c, something_to_insert s){
    insert_into_b(c->b, s);
}

something query1(C c){
    /* Get some info from subclass */  stuff s = do2(c->a);
    /* Get some info from subclass */  some_value sv = do4(c->b);
    /* do some other things with s and sv */ something some = something_with_s_and_sv(s, sv);
    return some;
}

So, I'm never breaking encapsulation because I do not allow the user to ever have anything on their hands. If you want to put something in A you do it through C. And this was all decently fine until I tried to move to MVC architecture and then I realized the following...

It's not C who should be making queries on himself, that's the job of the controller who should parse, retrieve data, act on it and pass it to the view. So, I thought about fixing this but then it hitted me. This would need me to have yet another function in C to use each of the subclasses functions. It does means all implementation is private and allows completely to change the implementation of A and B but it requires for every action to be "duplicated" in C.

( This is what I want to get an answer for! )

But, as is, it can't fit MVC. I won't be able to rollback to the typical OOP way (get-set-clone) so I just wanted to ask if it's alright to make a controller that receives data already processed (how you see above) or if it would make more sense to move query1 (for example) out of c.c and pass the inner logic to the controller, adding do2_through_C(C c) and do do4_through_C(C c) to the C API.

pCosta99
  • 51
  • 5
  • `typedef struct a *A;` --> Never define a `typedef` to signify a pointer to a structure -> [typedef is evil](https://discuss.fogcreek.com/joelonsoftware1/10506.html) – David Ranieri Apr 06 '20 at 10:09
  • 1
    @DavidRanieri I did left a note that explicitly said that it's out of my control, I am aware of that and that's not the point of this question. Will read up on ur link tho. – pCosta99 Apr 06 '20 at 10:11
  • Yes, I have read this: _but it was requested to be done so_ , is there any reason to follow the `typedef` in your API? you can make your own rules isn't it? – David Ranieri Apr 06 '20 at 10:15
  • Ok, then I will focus on this: _how to build a third, C class, that will interact with those two_. As you know, in C the address of the first member is shared with the address of the `struct` itself, to achieve access to 2 base `struct`s the solution is: encapsulate those two structs in a single `struct` and use it as the first member of your derived pseudo-class. It sucks, but I don't see any other way to do that. – David Ranieri Apr 06 '20 at 10:24
  • @4386427 yes it is, i left it out as I thought it would be implicit, my bad. – pCosta99 Apr 06 '20 at 10:26
  • @DavidRanieri Hmm, I do understand what you mean but that's not really what im going for here. The last paragraph is my main question, I'll add some emphasis on it. – pCosta99 Apr 06 '20 at 10:29
  • 1
    What a strange approach, @PedroCosta. Writing something in a non-OOP language such as C and then translating the result into an OOP one is irrational. Even if you reinvent OOP wheel in C and even manage to make a digestible API for it, then that solution will have almost nothing useful for your Java implementation. That's only my opinion, and, I'm sure, you'll not find a definite answer to your question. By the way, it'd be more appropriate, if you asked the question on https://codereview.stackexchange.com/ – Ruslan Osmanov Apr 06 '20 at 10:49
  • @RuslanOsmanov The objective proposed was to do it the get-set-clone way, even in C, but that didn't sounded very interesting so I wanted to try something else. Thanks for the useful comment, I was not aware that there was a proper place for code review matters! Do you think I should close this thread and ask there for a more detailed discussion then? – pCosta99 Apr 06 '20 at 10:57
  • I'm voting to close this question as off-topic because it would be a better fit on https://codereview.stackexchange.com/. @PedroCosta, I've flagged the question for moderator attention. Moderator can move it to any site in the Stack Exchange network. – Ruslan Osmanov Apr 06 '20 at 11:51
  • @RuslanOsmanov alright, thank you – pCosta99 Apr 06 '20 at 13:44
  • @RuslanOsmanov Using OO design is language agnostic and those who don't realize that haven't worked much with program design on a system level... also, this question is definitely off-topic on Code Review so don't recommend the OP to post there. Code Review requires complete working examples, not snippets or pseudo code. – Lundin Apr 06 '20 at 14:18
  • That being said, I don't understand the question here. Specifically, what is this supposed to mean? "It's not C who should be making queries on himself, that's the job of the controller who should parse, retrieve data, act on it and pass it to the view." And what is a "controller"? Also, the nomenclature with "subclass" is very confusing, there's no concept in OO called "subclass", but there is a term called subclassing in Windows programming, meaning something else entirely. – Lundin Apr 06 '20 at 14:22
  • @PedroCosta, so the moderator has only questions for you. As I was ordered to not recommend you to post on Code Review, I won't. But I would do this myself, with the only exception that I would make the code more "real" (the moderator, probably, would call it "complete"). See https://codereview.stackexchange.com/help/on-topic . – Ruslan Osmanov Apr 06 '20 at 14:50
  • @Lundin As I mentioned, although maybe not clearly enough, my interest incides in applying MVC architechture to something like the example above. So, in that scene, a controller is the module who "parse, retrieve data from C module, do something with it and pass it to the view.". My main goal is just understanding if I can achieve decent encapsulation with something in the terms of those examples and if that is a some-what alright approach to achieving encapsulation in the C programming language. Sorry about the informality, not used to technical conversations. I'll fix some stuff mentioned. – pCosta99 Apr 06 '20 at 15:15
  • @Lundin I'm not trying to find something about OO here, I'm trying to achieve what OO achieves in a completely different way! And I just wanted to hear some thoughts about incorporating MVC in that way. The OO is just a comparison to what I'm doing, as I intend to achieve something near that, without going the get-set-clone way. – pCosta99 Apr 06 '20 at 15:17
  • Proper private encapsulation in C is achieved through so-called "opaque types", example: https://stackoverflow.com/questions/3824329/partitioning-struct-into-private-and-public-sections. You can also get "poor man's private" by simply declaring variables at file scope `static`. This also encapsulates the variable properly, but it isn't thread-safe and you only get one instance of that variable. – Lundin Apr 07 '20 at 06:31
  • @Lundin as shown above I'm using opaque types, thanks for the suggestion nevertheless. Very hard trying to explain what I actually wanted to discuss but thanks for all your effort :) – pCosta99 Apr 07 '20 at 10:27

0 Answers0