5 ms·
OOP is really interesting to someone like myself that comes from a philosophy background. In a python framework, i find object to be very useful in conceptualiz
by scoofy 6y ago
OOP is really interesting to someone like myself that comes from a philosophy background. In a python framework, i find object to be very useful in conceptualizing my programs (i'm more able to hold the code in my head).
I, however, often see objects used in bizarre ways. Often to reduce written lines, or to take a concept, and attach another concept to it in a fairly ad hoc way. This is never helpful.
The most problematic times i have with object is when the concept behind them become too general. E.g. If a have a program with a deck of cards, i can have card objects, with rank and suit, and i can have deck objects, with 52 cards, shuffle and deal methods. That's fine, but if i have an object that's just "poker game" that tries to shove all those concepts into one object, it seems to become very unwieldy, very quickly.
- dheera 6y agoOOP is nice when it is used concisely and when objects correspond 1:1 to real things. This is painful use of OOP (actual code from an Android app): Camera.Parameters params = mCamera.getParameters(); params.setRotation(90); mCamera.setParameters(params); This would be NICE use of OOP: mCamera.setRotation(90); OR mCamera.setParameters({"rotation": 90}); This is painful use of OOP: BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inSampleSize = 4; Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length, opts); mImageView.setImageBitmap(bmp); This would be nice use of OOP: mImageView.setImage(new Bitmap(data = data, sampleSize = 4));
- throwaway894345 6y agoI would argue that it’s very rarely useful to mutate like this at all, and this is one of my grievances with OOP in practice. In particular, I don’t need to mutate via methods—this kind of encapsulation is rarely useful; it’s not like one day I’m going to be able to swizzle the implementation for a network-backed implementation without introducing a breaking change (and a whole host of performance problems when iterating over a collection of objects).
- dheera 6y agoIn addition, there are things that just don't need to be separate classes, they should be static methods or constructor options of an existing class. I very much like the Pythonic paradigm of conciseness, e.g. PIL.Image.open() or cv2.imread() with optional arguments which is light-years more pleasant to code with than the BitmapFactories and BitmapFactory.Options and AbstractSingletonProxyFactoryBeans. It's also really nice that Python and JavaScript classes/objects can have arbitrary attributes stuck onto them, e.g. someObject.__source = "foo" or set and that sticks to someObject wherever it goes. It's a very intuitive way to implement a lot of things; one can liken it to sticking a post-it note on a box.
- Skunkleton 6y ago> OOP is nice when it is used concisely and when objects correspond 1:1 to real things. These sorts of objects provide a nice API, but they don't contribute to good internal designs. I have seen many systems were there is an attempt to map objects to physical things (like on a modem, you might have a "demux" object). Invariably, software ends up having to bend to the design of the hardware, and you end up with very leaky abstractions. Why have a "demux" object, when all you are trying to do is write some registers depending on user configuration? Why not design your software around what it is actually doing, rather than what the system's overall purpose is? Interfaces are a different question. High level interfaces that reflect what the system actually does are very useful. I think this is born out in some modern OOP-ish languages like Go or Rust where interfaces are everywhere, but full scale OOP is mostly absent.
- dheera 6y agoAlthough I have only a very superficial understanding of modems, I'd say demux() should be a function library, not an instantiated object. But even if it is an object for various reasons such as caching, that's quite fine with me; a Demultiplexer can be thought of as an conceptual component that a Modem "has" inside it. What I don't like is when things like options, parameters, and intermediate representations of data that aren't actually intuitive are represented as instantiated objects of their own. In some sense I expect every instantiated object to "do" something useful of its own, and represent a functional block in a flowchart. Objects should, to the greatest extent possible, represent "is" and "has" relationships in a system, IMO. Also, class hierarchy should be well designed. For example, an Exception called ConnectionError (that inherits from Exception) is great. It can be parametrized from there. What sucks is if there is SomeFooConnectionError, SomeBarConnectionError, SomeBlahConnectionError that all inherit directly from Exception and don't inherit from a common ConnectionError, because that makes the try/catch block super verbose and easy to miss a possibility.
- choward 6y agoFor the camera example, I would rather do: Camera camera = createCamera({"rotation": 90}); If you need another camera with different parameters then create a new one. You can build the options before the creating the cameras to avoid duplication. Bitmap bitmap = createBitmap({data: data, samepleSize: 4}); ImageView imageView = createImageView(bitmap); In the case where you are mutating image view, it's an optimization to reuse the same memory that could be handled by your language/framework so you don't have to think about it. For example, like with react it could create an internal representation of what is rendered and then diff it with the new rendering and reuse the internal representation of image view and mutate it for you so you don't have to think about doing the optimization yourself.
- NeutronStar 6y agoOr Camera camera = new Camera({"rotation": 90}); and Bitmap bitmap = new Bitmap({data: data, samepleSize: 4}); ImageView imageView = new ImageView(bitmap);
- teekert 6y agoAs a Python programmer, all I see is heaps of very similar and the same words. It looks like mess, I'm sorry.
- mmm_grayons 6y agoA Python background explains that, as y'all tend to worry less about memory usage and re-use. This can have its upsides, but it probably creates a bit of a blind spot here, because it's referencing the sort of thing one probably wouldn't do in python.
- jschwartzi 6y agoThat's because you're telling the compiler what the type of the variables is ahead of time so the compiler knows whether you're using the type correctly. As opposed to in Python constructing an object and adding functions to it one by one at run-time, and only checking that the type is used correctly when the type is used. There's a trade-off being made between conciseness on one hand and fast feedback on the other. Python leans toward conciseness and Java/C++ lean toward fast feedback. In Python you can express complicated ideas quickly, but you can't necessarily express correct ideas quickly. Whereas in C++ you can express correct ideas quickly but you can't express complicated ideas quickly. If it's costly for you to correct defects in deployed software then you might prefer the fast feedback of C++ or Java rather than the flexibility of Python.
- pantalaimon 6y agoOr just plain procedural camera_set_rotation(camera, 90);
- deleted 6y ago[deleted]
- jasonlhy 6y agoI think OOP as a way of abstraction. It make sense to abstraction something in OOP style, for example, collection such as LinkedList, Stack. But sometime it is too verbose to use OOP, for example lambda vs anonymous listener. The biggest problem is it is easy to do wrong abstraction with OOP style, for example, store state that make no sense and put weird method inside a class