Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
22

You can't write good code without getters. The reason why isn't because getters don't break encapsulation, they do. It isn't because getters don't tempt people to not bother following OOP which would have them put methods with the data they act on. They do. No, you need getters because of boundaries. The ideas of encapsulation and keeping methods ...


10

Getters violate the Hollywood Principle ("Don't call us, we'll call you") The Hollywood Principle (aka Inversion of Control) states that you don't call into library code to get things done; rather, the framework calls your code. Because the framework controls things, broadcasting its internal state to its clients is not necessary. You don't need to know. ...


4

If I put above three in this way, why ACCOUNT itself is an abstract data type? How comes ACCOUNT at the same time is parameter as well as abstract data type? Strangely enough, for no better reason than because it happens to be one. STACK[int] makes just as much sense. STACK is an ADT and int is a concrete primitive. You just don't find many languages that ...


4

Inheritance is not bad per se. It depends on how you use it. Avoiding a technique just because someone says it is bad is not a good way to make decisions. While I see where Josh Bloch is coming from, the alternative he proposes is not quite the same thing. The Template pattern aims to enforce a particular design; it takes advantage of the rigidity of ...


4

I'd be inclined to split the responsibilities into two: creating and sending emails, loosely coupled with an Email interface. Then the EmailService takes the simple form you intuitively want and the implementation is only dependent on the transportation infrastructure. public interface EmailService { void send(Email email) throws X; } Whilst an ...


3

In my opinion is the EmailService implementation is way to broad, it will be a great idea to split it into more specific implementations (like you did). the interface-segregation principle states: ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of ...


3

OOP is more than dot-method syntax. How exactly OOP should be defined is up to some debate, but most definitions agree on some design benefits: OOP is polymorphism: by having the object contain its own methods we can have multiple objects that implement the same interface but behave differently. This allows for significant flexibility in the design of a ...


3

The main purpose of encapsulation is to hide complexity from the user of a class to make his life easier. This implies that there is such internal information that is irrelevant to the user. While this is probably not always the case in practice, I do believe that there are such things as good abstractions where the user can be freed from dealing with the ...


3

Interface of the library should be defined by a user not by the creator. And user defines it by pattern of usage. Exactly the opposite is true. The library provider has the job of understanding the domain of the library to the maximum extent possible, with every minute detail possible, and to form it into a coherent, logically structured, easy to use, hard ...


3

Your feeling is correct. This is not a good design. It appears to me that this is an attempt to 'model the real world' with objects: a manager fires an employee, therefore the fireEmployee method must be part of Manager. What your model should really reflect, however, are the invariants of your business domain. For example, an employee can only be fired by ...


3

I'd pick the second approach, but not exactly the way you are proposing it. Here is the issue: You are introducing an object called SpeedCalculator, which is indicating that it is performing a calculation. But in fact, you are storing two values - duration and mileage together. This is the principal remark I'm making. Let's look at that same pair - (...


3

This isn’t a concern for encapsulation, it’s a concern of using proprietary software. Because what you describe is clearly a bug. It’s either a bug in the published API or it’s a bug in the implementation. If the black box is internal to your company or the source code is otherwise available to you, you might be able to dig deeper and uncover the problem ...


3

A design is never inherently "good" or "bad" per se, these attributes cannot be applied sensibly without context. A good design is one which makes a program fit to its non-functional requirements in the most simple manner. And sometimes global variables are exactly this: the most simple solution which fits well into the context. So the question you need to ...


2

Having a method to just execute one method on another object is not wrong per se. It is perfectly fine if the semantics of both methods is different or the methods are on a different abstraction level. For example calling fire() just calls record.delete() to remove from database or something. In your example it is questionable, since both methods should ...


2

Looking at your code, if you have any requirement to have a unit test cover the processRequest method, without dependency injection it will be impossible for you to provide a mock object for MyObjectClass in your first example. If MyObjectClass interacts with anything (such as making an HTTP request, write / read from a file, save / read stuff to or from a ...


2

Getters Leak Implementation Details and Break Abstraction Consider public int millisecondsSince1970() Your clients will think "oh, this is an int" and there will be a gazillion calls assuming that it is an int, doing integer math comparing dates, etc... When you realize that you need a long, there will be a lot of legacy code with problems. In a Java ...


2

Your ResourceCommonProcedures doesn't really seem to be an example of the Template Method pattern (as it doesn't really define a 'template' for an operation, except perhaps in a trivial sense). Your base class acts as a factory that produces a concrete ResourceCommonProcedures-derived instance based on an identifying parameter (resourceType). Arguably, that ...


1

One of the strong selling points of OO is supposed to be encapsulation: the implementation details are hidden away and only API, in the form of method signatures and the like, are exposed to the wider world. Yet there is a well recognised way of breaking that encapsulation: you guarantee that a method will perform certain actions, including calling other - ...


1

Sounds like you're describing the mediator pattern. I'm not sure about your compile-time validation requirement. If you have an ArcadeGame class that takes an ArcadePlayer, I'm not sure access control can be enforced at compile-time without a custom preprocessor step or just encoding the rules in your build process. For example, if you were using Makefiles,...


1

What is one thing, without opinions, that will break if I use getters sensibly and for data that clearly the object's integrity doesn't break if it puts it out? Mutable members. If you have a collection of things in an object that you expose via a getter, you are potentially exposing yourself to bugs associated with the wrong things being added into ...


1

I think the first key is to remember that absolutes are always wrong. Consider an address book program, which simply stores people's contact information. But, let's do it right and break it up into controller/service/repository layers. There's going to be a Person class that holds actual data: name, address, phone number, etc.. Address and Phone are ...


1

You got already some good answers, but I am not sure if the answerers really understand your issue. I guess what you are really after is Joel's Law of Leaky Abstractions. In essence, it says, any non-trivial abstraction always has the risk of showing unexpected or undocumented behaviour. This behaviour can only be understood in full by looking inside the "...


1

In addition to @DocBrown's answer. Q: Do you believe this design is bad or not scalable? How would you improve this or, better, what would you substitute this design with? Locating constants in specific classes is not bad per se. Clustering all the constants in the very same class, at the very same level of abstraction could be problematic. 1 I would ...


1

I think you're missing a multiplicity indicator here: The Schedule that Scheduler.BuildSchedule() returns will sometimes have more than one ScheduleEntry in it wont it?


1

In addition to Frank Puffer's answer. Hiding complexity is not the only reason why we make some details unreachable. We also want as much decoupling as possible. In consequence, we make our public interface thin. The thinner is the public interface of the API, the lesser coupling will be between the consumers of the API and the API itself. But, we don't do ...


1

A smaller public interface is inherently better, as it makes it easier to implement alternative implementations. If you add methods which are specific to an implementation then you are effectively 'breaking' that interface. We should remember that making things private doesnt really stop a determined developer calling them. It's just a flag to help you ...


1

Compared with procedural programming, OOP allows us to build higher level abstractions by bundling code & data together.  Any time we can reduce the number of items that the consuming client has to deal with, that is positive. In procedural programming, a simple structure can combine, say an int x and an int y.  Using a structure, a consuming ...


1

Ouch, that looks messy. Workflows and Rule Books I think what you need is a workflow, and a rule book. In comes a TransferRequest, with some source information, destination information, and a balance. enum AccountKind { BankTransfer, Cashier, Wallet, ... } class Account { AccountKind kind; AccountIdentifier identifier; } enum ...


Only top voted, non community-wiki answers of a minimum length are eligible