Suppose, we have the following Boy class that tries to arrange a date with a Girl by analyzing her schedule (example in Java):
public class Boy {
public boolean tryArrangeDate(Girl girl, Date time) {
boolean success = true;
for (GirlRoutine routine : girl.getSchedule()) {
if (routine.happensAt(time)) {
success = false;
break;
}
}
return success;
}
}
Boy.tryArrangeDate() method clearly violates Law of Demeter because of routine.happensAt() call. One of the ways to resolve this is to move schedule analysis directly to Girl and avoid having a dependency on GirlRoutine. That would probably be one the best decisions in this case. RFC for Boy class will be reduced.
But suppose we choose a different direction for resolving violations of Law of Demeter and change the code in this way:
public class Boy {
public boolean tryArrangeDate(Girl girl, Date time) {
return isFree(girl.getSchedule(), time);
}
private boolean isFree(List<GirlRoutine> schedule, Date time) {
boolean free = true;
for (GirlRoutine routine : schedule) {
if (happensAt(routine, time)) {
free = false;
break;
}
}
return free;
}
private boolean happensAt(GirlRoutine routine, Date time) {
return routine.happensAt(time);
}
}
There are two private methods added that just delegate calls down to the Girl and her schedule / routines.
Each method taken individually does not seem to violate Law of Demeter (for simplicity reasons let us treat retrieval of item from collection as a primitive no-method-call operation). But overall we have not reduced RFC for this class, did not improve the cohesion, and actually increased WMC. Tell, don't ask principle is not preserved. So, Law of Demeter is satisfied but design is still flaky.
Question:
Is it true that (formally) second code snippet does not violate Law of Demeter?
NOTE: Purpose of the question is NOT to find alternative solutions, but to confirm / refute that the solution adheres to the Law of Demeter
Update
Since you're just asking if the second still violates the Law of Demeter, then yes, I'd argue it does. No matter how you refactor tryArrangeDate, it doesn't change the fact that it's calling a method from GirlRoutine. When the Law of Demeter mentions "any method of an object", I take it that it refers to methods accessible to other objects, methods that are exposed to the "outside world". The private methods in your second code snippet are merely helper methods to tryArrangeDate.
Originally
The Girl class is the "expert" when it comes to its own GirlRoutines. As much as possible, you must hide it from anyone else. Remember the principle of tell, don't ask.
Perhaps you can do:
Response response = girl.askOut(boy, date);
Don't read it like the Girl instance is asking out the Boy instance; the rule of thumb I follow (most of the time) is that the object from which you call the method is the direct object of the action that the method represents. In this case, the direct object of askOut is the Girl instance.
The Response class can have information about how it went, or it can be something simple like:
enum Response { ACCEPTED, REJECTED }
This way, a Girl instance has everything it needs to know to accept or reject the Boy instance's request.
Related
I have some confusion about use of Controller with Repository Pattern while maintaining SOLID Principle. Consider, I have two types of Quotations
Commercial Quotation
Private Quotation
And there is a high chance of new types of quotations in future. Each Quotations has different fields, business logics yet they share many common functions. So I created a QuotationInterface
Quotation Inteface
interface QuotationInterface
{
public function save(array $data);
}
Quotation class that implement the interface
class CommercialQuotation implements QuotationInterface
{
public function(array $data)
{
// save commercial quotation
}
}
class PrivateQuotation implements QuotationInterface
{
public function(array $data)
{
// save Private quotation
}
}
Quotation Repository
class QuotationRepository
{
public function save(array $data, QuotationInterface $quotation)
{
$quotation->save($data);
}
}
QotationController
public function store(Resource $resource)
{
$inputs = $resource->all();
/**
* Clearly here Open/Close Principle is broken
*/
if ($inputs['type'] == 'private'){
$quotation = new PrivateQuotation;;
}
else if($inputs['type'] == 'commercial'){
$quotation = new CommercialQuotation;
}
$this->repo->save($inputs, $quotation);
}
Here in my QuotationController, it is clearly violating Open/Close Principle..
Is it a good idea to Create a Controller for each type of quotation (might be 10+ some day, who know?) to avoid the OCP violation or my design is just wrong? Any suggestion, design change tips, resource are welcome.
NOTE: My Quotation Controller will have many other functions except the save only.
If you're going ahead the way you've shown, i suggest you to use a single controller for your quotations and use a Factory design pattern to create your $quotation objects
For example, with a simple factory like this:
//FACTORY CLASS
abstract class QuotationFactory
{
/** return QuotationInterface */
public static function createQuotation($type)
{
switch($type)
{
CASE "private":
return new PrivateQuotation();
break;
CASE "commercial":
return new CommercialQuotation();
break;
}
}
}
you could use the factory from you controllers' methods:
//YOUR CONTROLLER'S METHOD
public function store(Resource $resource)
{
$inputs = $resource->all();
//delegate objects creation to factory class
$quotation = QuotationFactory::createQuotation( $inputs['type'] );
$this->repo->save($inputs, $quotation);
}
This way you are not going to violate the open/closed principle in your controllers, because as you add quotations, you'll only need to modify the method of the factory (adding cases to the switch statement ), and it will return a QuotationFactory object wherever needed.
This will also keep your code DRY and SOLID because you don't have to repeat the if/else statements to create your objects in your controller's methods as you delegate the responsability of the objects' creation to a specific factory class
As correctly pointed ount in the comments below, the Simple factory is going to help you avoiding the Open/Closed Principle in your controllers but be ware that, from a more general point of view, the Simple Factory itself is inherently violating the OCP as it uses a switch case.
Anyway, from what i see of your application, the Simple factory could be a good solution, as your primary concern is to build in many places instances from a variable type. Thus, using the Simple factory you can 'hide' this process of creating objects into the factory and get the instances you need in your controllers. So you are violating the OCP only inside the factory in the switch case, but i think this could be a beareble trade-off
I think this mostly depends on the scope of your application. In the PHP world these days, people are so angry with if/else statements :). However, if that works for your application and seems reasonable in the scope of YOUR context, I think that's fine.
Businesses change and Business changes aren't always easy to plan for. You can only try to make those changes easier when they arise.
That being said, classes are cheap and I think that having separate classes at this point (and in the future) is very reasonable. If the requirements for each type of quotation expand, you'll be in good footing and I don't think you're abstracting so far that you're code will be difficult to understand.
I know it's late, but i hope my comment helps more people searching your issue.
You should follow the following principle:
"If you have a conditional like that you should do it in the low level abstraction not in the high level"
so the design should be:
class QuotationFactory
{
public static function make($type)
{
switch($type)
{
CASE "private":
return new PrivateQuotation();
CASE "commercial":
return new CommercialQuotation();
default:
throw new InvalidTypeException("Invalid type code.");
}
}
}
The above refactoring called "Replace conditional/type code with polymorphism".
If there're no new types in the future you should follow "Replace Parameter with explicit methods" refactoring, it would improve the readability.
For more you should read a book called "Refactoring: Improving the Design of Existing Code" by Martin Fowler.
There are a few questions already on Stackoverflow with similar scenarios, but they don't really address my case.
I am currently doing some refactoring and would like to make the code more robust, flexible and readable by applying patterns. Here is the task:
I have a class, let's say class A, which applies some logic when setting one of its members. This logic is prone to change, so I would like to externalise it. This is where the strategy pattern would be useful.
Also, at some stage I need to filter a list of objects of class A. The filter logic should also be configurable, so the stragey pattern would be handy in this task also.
The question is: How do I combine these requirements into the object-oriented design?
My thoughts so far:
- Use a factory for objects of type A, that has two strategy objects: SettingMemberStrategy and FilterStrategy. If the concrete factory is implemented as singleton, the two strategy objects need to be specified before objects can be created.
- Have two methods on the interface of class A: setMember(value); boolean filtered(). The exact implementation of these methods is determined by the strategies. However, should the object then also carry instances of the strategies?
This approach might work, but it seems a bit overengineered for the task and aesthetically not too pleasing.
Could someone hint at a better solution?
Thanks a million.
Cheers,
Martin
public interface IA {
setMember();
filter();
}
public class A implements IA {
private String theMember = "";
getMember() { return this.theMember; }
setMember(String input, otherParameters[]) {
// set value for member based on strategy and parameters
}
boolean filter();
// returns yes/no based on whether this class should be filtered
// as per filter strategy
}
public class myFactory {
private FilterStrategy myFilterStrategy;
private MemberStrategy mySetMemberStrategy;
IA createObjectOfClassA() {
a = new A(mySetMemberStrategy, myFilterStrategy);
}
setFilterStrategy(FilterStrategy s) { this.myFilterStrategy = s }
setMemberStrategy(MemberStrategy s) { this.mySetMemberStrategy = s }
}
This question depends entirely on how you use these objects. My instinct tells me that in most cases you don't need both a factory and a strategy pattern - you would want to choose one or the other, thus simplifying your code.
If for example, you are creating subclasses of object A in your factory, then eliminate the configurable strategy and bake it into your subclasses.
If, however, you don't create subclasses, just have objects with configurable strategies, then eliminate the factory, and just create the objects with the appropriate strategy in their constructor when you need them.
You could also have a combination of the two if you for example create objects based on an input, and use a factory method to give you a proper instance, i.e.
public A MyFactoryMethod(string typeToCreate){
switch(typeToCreate) {
case "AbeforeB":
return new A(new FilterStrategyA(), new MemberStragegyB());
case "allA":
return new A(new FilterA(), new MemberStrategyA());
// etc. etc.
}
}
In my understanding the strategy pattern is used to make behaviour interchangable. This involves that the responsibility of the strategy is defined in an interface, to which the client may then delegate calls. E.g. suppose a value can be obtained in different ways, the interface would have a method "getValue()".
My question concerns the case where the flow of control is opposite. For example if the concrete strategy initiates the request "onValueChanged()" on the client (suppose it has a reference to the client or a callback interface).
Is this still considered a strategy pattern?
Update - added the following source code example:
interface DataSupplierCb
{
void onValueChanged(int a);
}
interface DataSupplier
{
void check();
}
// NOTE 1: Data supplier knows how the get the value
class ConcreteDataSupplier : public DataSupplier
{
void check()
{
myDataSupplierCb.onValueChanged(47);
}
}
class Client : public DataSupplierCb
{
void onValueChanged(int a)
{
// NOTE 2: Client knows what to do with the value
}
void changeDataSupplier(int i)
{
if (i == 1)
{
myCurrentDataSupplier = new ConcreteDataSupplier(this);
}
}
}
No. That would not be the strategy pattern. In the strategy pattern, the strategy interface, and the concrete strategy implementations do not know about the client.
The client knows about the strategy interface, and knows nothing about the actual implementations.
The goal of this pattern is the ability of replacing one strategy with another without modifying the client. A strategy is usually some sort of algorithm.
What you are describing seems to be closer to the Observer design pattern in which there is a subject and one or several observers implementing a common interface (or inheriting from a common base class). The subject is the object that is being observerved, and the observers are objects that need to be notified whenever the subject changes. e.g: the subject can be some kind of data source, and one observer can be an histogram view, and another a pie chart view.
http://en.wikipedia.org/wiki/Observer_pattern
http://en.wikipedia.org/wiki/Strategy_pattern
If the intent of the DataSupplier interface to allow your Client to swap in, and delegate to, different concrete data-fetching implementations then yes it can be considered a strategy. Your Client is shielded from the details (aka strategy) used to fetch the value as expected in the use of the Strategy pattern. And the fact that the Client reference is passed to the Strategy is fine and common:
(From the GoF)
"Strategy and Context interact to implement the chosen algorithm. A
context may pass all data required by the algorithm to the strategy
when the algorithm is called. Alternatively, the context can pass
itself as an argument to Strategy operations. That lets the strategy
call back on the context as required."
The Context for you is Client.
Now that all being said, rare is a solution that uses only one pattern. Your notification does seem to use the Observer pattern as another poster commented, and that is fine.
What I don't like about what you have implemented though is that your Strategy is a pure interface. Not always a bad thing, but in this case, with that notification callback, an interface does not provide a guarantee that the notifictaion callback is going to happen. Interfaces only guarantee the method signatures. I would recommend using the Template pattern in a base class to derrive the strategies from.
abstract class DataSupplier
{
protected ClientInterface _client;
// ctor takes in context
public DataSupplier(ClientInterface client)
{
_client - client;
}
public void check()
{
int priorValue = 46;
int newValue = OnGetValue();
if (priorValue != newValue)
_client.onValueChanged(newValue)
}
protected abstract int OnCheck();
}
And then:
class ConcreteDataSupplier : DataSupplier
{
// Check, and notification, are handled by the base. We only need
// to implement the actually data fetching
int OnGetValue()
{
return someValue;
}
}
With this approach, I know the notification will be handled. I don't need to worry about an implementor forgetting it in a new strategy later.
I have this code
class Duck {
protected $strVocabulary;
public function Learn() {
$this->strVocabulary = 'quack';
}
public function Quack() {
echo $this->strVocabulary;
}
}
The code is in PHP but the question is not PHP dependent.
Before it knows to Quack a duck has to Learn.
My question is: How do I make Quack() invokable only after Learn() has been called?
No, that does not violate any OOP principle.
A prominent example is an object who's behavior depends on whether a connection is established or not (e.g. function doNetworkStuff() depends on openConnection()).
In Java, there is even a typestate checker, which performs such checks (whether Duck can already Quack()) at compile time. I often have such dependencies as preconditions for interfaces, and use a forwarding class whose sole purpose is protocolling and checking the state of the object it forwards to, i.e. protocol which functions have been called on the object, and throw exceptions (e.g. InvalidStateException) when the preconditions are not met.
A design pattern that handles this is state: It allows an object to alter its behavior when its internal state changes. The object will appear to change its class. The design pattern book from the Gang of Four also uses the example above of a network connection either being established or not.
If you want to fix the order then you can use an abstract base class where in the function quack() you call learn() first and then abstract method doquack() (some other good name, and this will have to be implemented by each derived class).
My question is: How do I make Quack() invokable only after Learn() has
been called?
you can separate concerns:
class EnrolleeDuck {
public function Learn() {
return new AlumnusDuck('quack');
}
}
class AlumnusDuck
{
protected $strVocabulary;
public function __construct(&strVocabulary) {
&this->strVocabulary = &strVocabulary;
}
public function Quack() {
echo $this->strVocabulary;
}
}
It's my first lines in PHP, feel free to correct
What's the name of the antipattern where methods take a generic god-object that has every property you might ever need for a method, rather than explicitly declaring what the method needs?
Eg:
public class BaseRequest
{
User user;
Car car;
CustomerRecords customerRecords;
Folder folder;
// ... etc for 10 - 20 other unrelated parameters
}
public void doSomething(BaseRequest request)
{
User user = request.getUser();
// do stuff with user, ignore all other attributes of request
}
Instead of
public void doSomething(User user)
{
// do stuff with user, since it's nice and clear what we want
}
Note - I'm not referring to the Single Responsibility Princple which BaseRequest violates. Instead, I'm looking for the name of the antipattern where the method signature is "lying" about its dependencies.
Also, are there any good blog posts that succinctly explain the evilness of this pattern, which I can point someone to?
Law of Demeter violation
I would say it's just an effect of having the god object. The problem shouldn't exist when the god object doesn't exist.