How to composite using-by objects (real world example) - oop

Hey i have question with a real word example.
Its related to my two other, but not really answered questions here:
https://softwareengineering.stackexchange.com/questions/423392/no-trivial-god-class-refactoring
and
https://softwareengineering.stackexchange.com/questions/425113/different-composition-techniques-from-the-perspective-of-the-client
Let's say we have a switch with the methods switchOn(), switchOff().
The switch(es) are included in some other structure, for example a switch-bag, from where i can pull out the switches.
This can be seen as a ready system.
Now i want to introduce the possibility of switching these switches on after a certain time automatically: A time switch
The time switch ueses now the "normal" switch.
The normal switch doesn't have to know something about the time switch.
So but now the client can pull out the normal switch from the switch-bag and now he want also to get to the time-switch related to these normal switch, maybe to configure a new time.
And this is my question, how can the client get to the time-switch?
There are a few possibilites:
I refactor the normal switch class to a third-class where the
normal-switch and the time switch lives bundled in it. But for this,
i break some other client code which still uses the normal switch, but
get now from the switch bag a "Combinator"-Class/Object out of it.
I don't change anything of the normal switch class. The client if he
wants to get access to the time switch have to ask a Map which time switch is related to it. (I think this approach is classical a
relation-programming style like a sql relationship database and its
not anymore real object-oriented style)
I extend the normal switch: Here i also have different options:
I change it to a big facade, which delegates the calls to the
normal-switch and time switch (its similar to my first solution with
the combinator, but here with an facade don't breaking some existing
client code)
i extend the normal switch letting the existing normal switch code
untouched and introduce a component holder. Into this component
holder i inject the time switch. So i have these methods there:
switchOn(); switchOff(); getComponent("timeSwitch"). But these
approach feels like a entity-component system
(https://medium.com/ingeniouslysimple/entities-components-and-systems-89c31464240d)
but is that still object oriented programming?
i think the last solution is the best one, because its the most flexible.
But what do you think which approach is the best, maybe some approach i didnt mentionend here?
Edit:
One more thing you must to know here: The time switch is one extension of the normal switch. One of many. So i want to add of course different more things XYZ switches/behavior extensions to the normal switch

Update: answer totally re-written (so the first comment won't make sense any more).
To summarize:
SwitchBag provides access to a list/collection of switches.
Switches have methods like on() and off().
You want to extend the behavior of at least some switches can do stuff themselves based on the passing of time, etc.
Clients (e.g. the UI) need access to the switches classes.
You make comments like
and now he want also to get to the time-switch related to these normal
switch
which suggests you have one of each, etc - which is way more complex than it needs to be. Here's some options to consider - some of your ones were heading in the right direction.
Option A: One type of switch
This assumes that the solutions design & functional drivers don't push you to create huge and overly complex switches. For example, let's say some of your switches need to do something after a period of time, others don't. Such a difference is not necessarily reason enough to make a separate class.
E.g. you can implement a time related property like Duration, if Duration > 0 then time logic applies and gets executed; < 0 means no time logic is applied (normal switch behavior).
I'm assuming here that any client can get access to any switch via the SwitchBag.
This is the option I would start with because it's simple and still allows plenty of functional scope.
Option B: Smart SwitchBag, Dumb Swithes
I'm not sure if I like the smell of this option because it tightly-couples the SwitchBag and Switch classes, but it could be useful.
Keep the switch class as dumb as possible.
SwitchBag knows about switches, it controls access to them (and their properties/methods). Use class structure and access modifiers to control this.
SwitchBag can decide to do stuff to switches based on time if it wants to.
In this approach, switches will be mostly properties, and be a little bit like the SwitchBags personal database, only it's fluid based on objects at runtime.
Note - you can still have events on the switches.
Option C: Interfaces
Create a basic switch. Create interfaces that are designed to be applied to switch class(es), that extend them as necessary. E.g.:
interface ITimeBehaviour{
double InitialDuration
double TimeUntilChange
}
At runtime you can see if a given switch instance implements the interface and respond accordingly. But whilst you can do this I'm not sure why you would, based on what I understand of your problem.
Other Thoughts
Your comments suggest you've thought a lot about OO concepts like inheritance and methods, but I saw no evidence you've considered asynchronous programming techniques - such as using events. If you know nothing about this then do some research and get up to speed, then see if that offers an elegant solution to your problem.
Design Patterns - are you familiar with the idea of design patterns? If you aren't, be sure to research that too. There's heaps of good content online, which describe patterns that might already solve the fundamentals of your problem.

Related

Is it common tradeoff to consider, that interaction between Bounded Contexts may "cripple Open Closed Principle"?

I am implementing interaction between bounded contexts and I found out that it "somehow" cripples open closed principle and I am not sure, whether it is natural consequence of designing BCs and common tradeoff to consider or my design failure.
Consider Shop BC where you can create Order out of Cart with some items. Created order consists of OrderItems, each of them containing one of various types of ItemSpecification Value Object Interface like ProductSpecification or FooServiceSpecification, protecting invariants and containing some data. When Order is created, asynchronous event that can be listened to by any other BC is emitted.
That asynchronous event is created out of Order and is represented as (serialized) OrderCreatedEvent object, containing OrderDTO object, all placed in Core namespace which is shared with every BC so that any BC can depend on Core, but not the other way. All good so far, almost:
That OrderItemDTO must contain interface ItemSpecificationDTO, which need be implemented for every type of specification. My ItemSpecification VO (like any other VO/Entity in Order) has toCoreDTO() method to pragmatically achieve easy translation and it also makes relatively hard to implement new ItemSpecification and forget to implement according DTO. That's probably okay.
But what about other BC's which listen to that Event? In every BC this Event needs to be translated in it's AntiCorruption Layer and that BC may be interested only in some types of ItemSpecificationDTO and translate them to various Value Objects, important for that specific BC.
As Uncle Bob says about OCP in a wit:
You should be able to extend the behavior of a system without having
to modify that system.
But when I implement new type of ItemSpecification, for every BC which may be interested in this new type I need to specifically translate that new type from CoreDTO (okay I could write some abstraction for translating in each BC so I would still be just adding code without modyfying anything like adding if($x instanceof X)). But still, by adding new type of ItemSpecification I need to make appropriate extensions (and maybe even modify something because we don't live in ideal world) in other BCs.
And I do not know how to think about that. Is that downside of whole DDD approach? Or maybe feature indeed, because that hunting for what, where and how needs to be further extended in other BCs, is driven by domain needs instead of technical concerns? It seems right. In the end, I'm trying to do domain driven design :-) But it seems to me somehow dangerous too. I am afraid that one day we can forget to update some other BC and something bad happens. But that is probably because I play big part of domain expert role too, under which that "fear" should probably belong. Is my problem just sitting on two chairs or did I got something wrong? :-)
There are a lot of interesting details about this topic, but I would concentrate here on one specific aspect of bounded contexts.
That is that they are bounded for a reason. As in, there should be a boundary between the models/understanding of these contexts. Two contexts, even if they are related should have a different view on the system, even on the data that might be partly shared.
It seems to me that your "bounded contexts" want to work on the same model. You even created a "core" model which everyone can see and apparently must be able to understand. If this is the case, I'd argue that you lost the benefits of having different contexts, and you are just creating one big application, with one model.
To correct this problem, I think you would need to get rid of any central/core models, and work with "local" (bounded) models in the different contexts/services. When you need to communicate with other components, you need to define a protocol for those two, dictated by either or both parties.
For example a Shopping Cart might need to know the product-id for the backend system to create the order there. But the backend system doesn't need to know the model the shopping cart uses to know what the order is about (in its own model).

How to understand the big picture in a loose coupled application?

We have been developing code using loose coupling and dependency injection.
A lot of "service" style classes have a constructor and one method that implements an interface. Each individual class is very easy to understand in isolation.
However, because of the looseness of the coupling, looking at a class tells you nothing about the classes around it or where it fits in the larger picture.
It's not easy to jump to collaborators using Eclipse because you have to go via the interfaces. If the interface is Runnable, that is no help in finding which class is actually plugged in. Really it's necessary to go back to the DI container definition and try to figure things out from there.
Here's a line of code from a dependency injected service class:-
// myExpiryCutoffDateService was injected,
Date cutoff = myExpiryCutoffDateService.get();
Coupling here is as loose as can be. The expiry date be implemented literally in any manner.
Here's what it might look like in a more coupled application.
ExpiryDateService = new ExpiryDateService();
Date cutoff = getCutoffDate( databaseConnection, paymentInstrument );
From the tightly coupled version, I can infer that the cutoff date is somehow determined from the payment instrument using a database connection.
I'm finding code of the first style harder to understand than code of the second style.
You might argue that when reading this class, I don't need to know how the cutoff date is figured out. That's true, but if I'm narrowing in on a bug or working out where an enhancement needs to slot in, that is useful information to know.
Is anyone else experiencing this problem? What solutions have you? Is this just something to adjust to? Are there any tools to allow visualisation of the way classes are wired together? Should I make the classes bigger or more coupled?
(Have deliberately left this question container-agnostic as I'm interested in answers for any).
While I don't know how to answer this question in a single paragraph, I attempted to answer it in a blog post instead: http://blog.ploeh.dk/2012/02/02/LooseCouplingAndTheBigPicture.aspx
To summarize, I find that the most important points are:
Understanding a loosely coupled code base requires a different mindset. While it's harder to 'jump to collaborators' it should also be more or less irrelevant.
Loose coupling is all about understanding a part without understanding the whole. You should rarely need to understand it all at the same time.
When zeroing in on a bug, you should rely on stack traces rather than the static structure of the code in order to learn about collaborators.
It's the responsibility of the developers writing the code to make sure that it's easy to understand - it's not the responsibility of the developer reading the code.
Some tools are aware of DI frameworks and know how to resolve dependencies, allowing you to navigate your code in a natural way. But when that isn't available, you just have to use whatever features your IDE provides as best you can.
I use Visual Studio and a custom-made framework, so the problem you describe is my life. In Visual Studio, SHIFT+F12 is my friend. It shows all references to the symbol under the cursor. After a while you get used to the necessarily non-linear navigation through your code, and it becomes second-nature to think in terms of "which class implements this interface" and "where is the injection/configuration site so I can see which class is being used to satisfy this interface dependency".
There are also extensions available for VS which provide UI enhancements to help with this, such as Productivity Power Tools. For instance, you can hover over an interface, a info box will pop up, and you can click "Implemented By" to see all the classes in your solution implementing that interface. You can double-click to jump to the definition of any of those classes. (I still usually just use SHIFT+F12 anyway).
I just had an internal discussion about this, and ended up writing this piece, which I think is too good not to share. I'm copying it here (almost) unedited, but even though it's part of a bigger internal discussion, I think most of it can stand alone.
The discussion is about introduction of a custom interface called IPurchaseReceiptService, and whether or not it should be replaced with use of IObserver<T>.
Well, I can't say that I have strong data points about any of this - it's just some theories that I'm pursuing... However, my theory about cognitive overhead at the moment goes something like this: consider your special IPurchaseReceiptService:
public interface IPurchaseReceiptService
{
void SendReceipt(string transactionId, string userGuid);
}
If we keep it as the Header Interface it currently is, it only has that single SendReceipt method. That's cool.
What's not so cool is that you had to come up with a name for the interface, and another name for the method. There's a bit of overlap between the two: the word Receipt appears twice. IME, sometimes that overlap can be even more pronounced.
Furthermore, the name of the interface is IPurchaseReceiptService, which isn't particularly helpful either. The Service suffix is essentially the new Manager, and is, IMO, a design smell.
Additionally, not only did you have to name the interface and the method, but you also have to name the variable when you use it:
public EvoNotifyController(
ICreditCardService creditCardService,
IPurchaseReceiptService purchaseReceiptService,
EvoCipher cipher
)
At this point, you've essentially said the same thing thrice. This is, according to my theory, cognitive overhead, and a smell that the design could and should be simpler.
Now, contrast this to use of a well-known interface like IObserver<T>:
public EvoNotifyController(
ICreditCardService creditCardService,
IObserver<TransactionInfo> purchaseReceiptService,
EvoCipher cipher
)
This enables you to get rid of the bureaucracy and reduce the design the the heart of the matter. You still have intention-revealing naming - you only shift the design from a Type Name Role Hint to an Argument Name Role Hint.
When it comes to the discussion about 'disconnectedness', I'm under no illusion that use of IObserver<T> will magically make this problem go away, but I have another theory about this.
My theory is that the reason many programmers find programming to interfaces so difficult is exactly because they are used to Visual Studio's Go to definition feature (incidentally, this is yet another example of how tooling rots the mind). These programmers are perpetually in a state of mind where they need to know what's 'on the other side of an interface'. Why is this? Could it be because the abstraction is poor?
This ties back to the RAP, because if you confirm programmers' belief that there's a single, particular implementation behind every interface, it's no wonder they think that interfaces are only in the way.
However, if you apply the RAP, I hope that slowly, programmers will learn that behind a particular interface, there may be any implementation of that interface, and their client code must be able to handle any implementation of that interface without changing the correctness of the system. If this theory holds, we've just introduced the Liskov Substitution Principle into a code base without scaring anyone with high-brow concepts they don't understand :)
However, because of the looseness of the coupling, looking at a class
tells you nothing about the classes around it or where it fits in the
larger picture.
This is not accurate.For each class you know exactly what kind of objects the class depends on, to be able to provide its functionality at runtime.
You know them since you know that what objects are expected to be injected.
What you don't know is the actual concrete class that will be injected at runtime which will implement the interface or base class that you know your class(es) depend on.
So if you want to see what is the actual class injected, you just have to look at the configuration file for that class to see the concrete classes that are injected.
You could also use facilities provided by your IDE.
Since you refer to Eclipse then Spring has a plugin for it, and has also a visual tab displaying the beans you configure. Did you check that? Isn't it what you are looking for?
Also check out the same discussion in Spring Forum
UPDATE:
Reading your question again, I don't think that this is a real question.
I mean this in the following manner.
Like all things loose coupling is not a panacea and has its own disadvantages per se.
Most tend to focus on the benefits but as any solution it has its disadvantages.
What you do in your question is describe one of its main disadvantages which is that it indeed is not easy to see the big picture since you have everything configurable and plugged in by anything.
There are other drawbacks as well that one could complaint e.g. that it is slower than tight coupled applications and still be true.
In any case, re-iterating, what you describe in your question is not a problem you stepped upon and can find a standard solution (or any for that manner).
It is one of the drawbacks of loose coupling and you have to decide if this cost is higher than what you actually gain by it, like in any design-decision trade off.
It is like asking:
Hey I am using this pattern named Singleton. It works great but I can't create new objects!How can I get arround this problem guys????
Well you can't; but if you need to, perhaps singleton is not for you....
One thing that helped me is placing multiple closely related classes in the same file. I know this goes against the general advice (of having 1 class per file) and I generally agree with this, but in my application architecture it works very well. Below I will try to explain in which case this is.
The architecture of my business layer is designed around the concept of business commands. Command classes (simple DTO with only data and no behavior) are defined and for each command there is a 'command handler' that contains the business logic to execute this command. Each command handler implements the generic ICommandHandler<TCommand> interface, where TCommand is the actual business command.
Consumers take a dependency on the ICommandHandler<TCommand> and create new command instances and use the injected handler to execute those commands. This looks like this:
public class Consumer
{
private ICommandHandler<CustomerMovedCommand> handler;
public Consumer(ICommandHandler<CustomerMovedCommand> h)
{
this.handler = h;
}
public void MoveCustomer(int customerId, Address address)
{
var command = new CustomerMovedCommand();
command.CustomerId = customerId;
command.NewAddress = address;
this.handler.Handle(command);
}
}
Now consumers only depend on a specific ICommandHandler<TCommand> and have no notion of the actual implementation (as it should be). However, although the Consumer should know nothing about the implementation, during development I (as a developer) am very much interested in the actual business logic that is executed, simply because development is done in vertical slices; meaning that I'm often working on both the UI and business logic of a simple feature. This means I'm often switching between business logic and UI logic.
So what I did was putting the command (in this example the CustomerMovedCommand and the implementation of ICommandHandler<CustomerMovedCommand>) in the same file, with the command first. Because the command itself is concrete (since its a DTO there is no reason to abstract it) jumping to the class is easy (F12 in Visual Studio). By placing the handler next to the command, jumping to the command means also jumping to the business logic.
Of course this only works when it is okay for the command and handler to be living in the same assembly. When your commands need to be deployed separately (for instance when reusing them in a client/server scenario), this will not work.
Of course this is just 45% of my business layer. Another big peace however (say 45%) are the queries and they are designed similarly, using a query class and a query handler. These two classes are also placed in the same file which -again- allows me to navigate quickly to the business logic.
Because the commands and queries are about 90% of my business layer, I can in most cases move very quickly from presentation layer to business layer and even navigate easily within the business layer.
I must say these are the only two cases that I place multiple classes in the same file, but makes navigation a lot easier.
If you want to learn more about how I designed this, I've written two articles about this:
Meanwhile... on the command side of my architecture
Meanwhile... on the query side of my architecture
In my opinion, loosely coupled code can help you much but I agree with you about the readability of it.
The real problem is that name of methods also should convey valuable information.
That is the Intention-Revealing Interface principle as stated by
Domain Driven Design ( http://domaindrivendesign.org/node/113 ).
You could rename get method:
// intention revealing name
Date cutoff = myExpiryCutoffDateService.calculateFromPayment();
I suggest you to read thoroughly about DDD principles and your code could turn much more readable and thus manageable.
I have found The Brain to be useful in development as a node mapping tool. If you write some scripts to parse your source into XML The Brain accepts, you could browse your system easily.
The secret sauce is to put guids in your code comments on each element you want to track, then the nodes in The Brain can be clicked to take you to that guid in your IDE.
Depending on how many developers are working on projects and whether you want to reuse some parts of it in different projects loose coupling can help you a lot. If your team is big and project needs to span several years, having loose coupling can help as work can be assigned to different groups of developers more easily. I use Spring/Java with lots of DI and Eclipse offers some graphs to display dependencies. Using F3 to open class under cursor helps a lot. As stated in previous posts, knowing shortcuts for your tool will help you.
One other thing to consider is creating custom classes or wrappers as they are more easily tracked than common classes that you already have (like Date).
If you use several modules or layer of application it can be a challenge to understand what a project flow is exactly, so you might need to create/use some custom tool to see how everything is related to each other. I have created this for myself, and it helped me to understand project structure more easily.
Documentation !
Yes, you named the major drawback of loose coupled code. And if you probably already realized that at the end, it will pay off, it's true that it will always be longer to find "where" to do your modifications, and you might have to open few files before finding "the right spot"...
But that's when something really important: the documentation. It's weird that no answer explicitly mentioned that, it's a MAJOR requirement in all big sized development.
API Documentation
An APIDoc with a good search feature. That each file and --almost-- each methods have a clear description.
"Big picture" documentation
I think it's good to have a wiki that explain the big picture. Bob have made a proxy system ? How doest it works ? Does it handle authentication ? What kind of component will use it ? Not a whole tutorial, but just a place when you can read 5 minutes, figure out what components are involved and how they are linked together.
I do agree with all the points of Mark Seemann answer, but when you get in a project for the first time(s), even if you understand well the principles behing decoupling, you'll either need a lot of guessing, or some sort of help to figure out where to implement a specific feature you want to develop.
... Again: APIDoc and a little developper Wiki.
I am astounded that nobody has written about the testability (in terms of unit testing of course) of the loose coupled code and the non-testability (in the same terms) of the tightly coupled design! It is no brainer which design you should choose. Today with all the Mock and Coverage frameworks it is obvious, well, at least for me.
Unless you do not do unit tests of your code or you think you do them but in fact you don't...
Testing in isolation can be barely achieved with tight coupling.
You think you have to navigate through all the dependencies from your IDE? Forget about it! It is the same situation as in case of compilation and runtime. Hardly any bug can be found during the compilation, you cannot be sure whether it works unless you test it, which means execute it. Want to know what is behind the interface? Put a breakpoint and run the goddamn application.
Amen.
...updated after the comment...
Not sure if it is going to serve you but in Eclipse there is something called hierarchy view. It shows you all the implementations of an interface within your project (not sure if the workspace as well). You can just navigate to the interface and press F4. Then it will show you all the concrete and abstract classes implementing the interface.

How do i design classes when doing UI?

I notice a pattern, when i did C++ and backend programming (in C# or any language) all my classes are neat and tidy. Recently i notice all my code are in a class and i literally have >50functions in it. I now realize its because i am doing UI. If i were to separate them by pages or forms/dialogs i would have a LOT MORE files, more lines of code and longer line of code. If i separate them i get the same problem (more files, lines, longer lines). Obviously the less lines the better (less code = less to debug, change or break during maintenance).
This specific project is 5k lines with 2k being from the web or libraries. All my .cs files are <1k lines. Is this acceptable even though i have 50+functions in a single class?
Bonus: I notice most of these functions are called only once. and putting certain code blocks (such as one function make two calls to the db) as their own function makes it harder for me to edit since they are divide between files and this balloon function count. So, i kind of dont know what to do. Do i create more classes to reduce function count (per class, it will increase function calls overall and already most are only called once)? How do i design classes doing frontend/UI?
I often find that my UI stuff grows considerably more complex than pure classes. Think about it - your "pure" classes are (for the most part) essentially machine instructions, and can (or should be able to) assume pure, pre-validated inputs and outputs, and do not have to accomodate the vagaries of human behavior.
A UI, on the other hand, is subject to all of human fallacy - and needs to respond in human-predictable ways, in a manner which humans can understand. THIS is where the complexity comes in.
Consider - in your nice, crisply defined classes, in which each function performs a fixed action against a known type of input, there is not alot of random BS to anticipate or handle.
A UI must be receptive to all manner of improper, inconsistent, or unanticipated input and actions by the user. While we, as designers, can pre-think some of this (and even minimize it with things like Combo-boxes and Command Buttons, a). all of that requires additional back-side code, and b) all of these things can then interact in different ways as well.
In our classes, WE decide how certain methods/functions and the like interact and affect one another. on the UI, we can do our best to point the user in the right direction, but there is still the random element. What if the user pushes the button before selecting an item from the list? There are several different ways to handle that scenario, all of which require another line (or ten, or 100) of code to handle gracefully.
Lastly, the more complex the project, the more complex the UI is likely to be, and the more of this must go on.
Managing the actions of the machine, given inputs and outpus we as programmers explicitly define, is EASY compared to predicting, managing, and handling the random quirks imposed on our stuff by a user. If only they would pay attention, right?
Anyway, I believe all of THAT is why code for a UI becomes greater, and more complex. As for how to break it out in a maintanable manner, the guys above covered it. Abstract the two. I design a form. I define the menas for the user to input data, and/or indicate what they want to happen next. Then I define the manner in which that form can communicate those things with my crisp, clean back end classes. Then I provide validation mechanisms, and the means to help control the user in navigating it all (e.g. the button is not enabled until the user selects an item from the list . . .).
Complex.

What kind of OOP structures work well in an application that has many different modes?

What can I do to structure my application so the code stays manageable as it gets bigger? I am building an application that will be in a certain state which will change depending on how the user interacts with it, and there will be many different states the application can be in. I've tried looking for tutorials/resources, but what I find only covers an application with a couple of modes, whereas mine will have lots of different behaviors.
For instance, you can click on object type A or B, so there can be a different behavior for each. If you hold the mouse down and try to drag one, they will behave differently too. But if you weren't holding your mouse down, that means it's not a drag. It's knowing what mode to move into when X event happens while you're in Y state that has me confused because I don't want to have a massive switch statement that handles everything.
It's not clear what exactly you mean by 'different modes.'
Lots of people spend a ton of time dreaming up abstract structures, behavioral, and organizational patterns for code. Another term for these concepts is design patterns. Aside from cleanly formatting and documenting your code, these concepts help you keep your code logically and functionally clean and operational.
They are well-known and mainstream because they have been proven to work in many implementations; you won't use all of them on every project, but you will probably start using combinations/variations of them if you want to scale. My advice would be to familiarize yourself with these and then reflect on where a particular pattern would work well in your application/state machine.
EDIT: Response to your edits.
For GUI development, in principle, you want to achieve separation of presentation code, behavior code, and state code. Some patterns lend themselves naturally to this end, for example the Model-View-Controller (MVC) pattern.

How could you improve this code design?

Lately, I've been making use a lot of the Strategy Pattern along with the Factory Pattern. And I really mean a lot. I have a lot of "algorithms" for everything and factories that retrieve algorithms based on parameters.
Even though the code seems very extensible, and it is, having N factories seems a bit of an abuse.
I know this is pretty subjective, and we're talking without seeing code, but is this acceptable in real world code? Would you change something ?
OK- ask yourself a question. does/will this algorithm implementation ever change? If no then remove the strategy.
I am maintence.
I once was forced (by my pattern lovin' boss) to write a set of 16 "buffer interpreter tuxedo services" using an AbstractFactory and a double DAO pattern in C++ (no reflections, no code gen). All up it something like 20,000 lines of the nastiest code I've even seen (not the least because I didn't really know C++ when I started) and it took about three months.
Since my old boss has moved on I've rewritten them using good 'ole "straight up and down" procedural style C++, with couple of funky-macros... each service is like 60 lines of code, times 16... all up less than a 1000 lines of really SIMPLE code; so simple that even I can follow it.
Cheers. Keith.
Whenever I'm implementing code in this fashion, some questions I ask are:
what components do I need to substitute to test ?
what components will I expect users/admins to disable or substitute (e.g. via Spring configs or similar) ?
what components do I expect or suspect will not be required in the future due to (possibly) changing requirements ?
This all drives how I construct object or components (via factories) and how I implement algorithms. The above is vague, but (of course) the requirements can be similarly difficult to pin down. Without seeing your implementation and your requirements, I can't comment further, but the above should act as some guideline to help you determine whether what you've done is overkill.
If you're using the same design pattern all over the place, perhaps you should either switch to a language that has better support for what you're trying to do or rethink your code to be more idiomatic in your language of choice. After all, that's why we have more than one programming language.
Would depends on the kind of software I'm working on.
Maintenance asks for simple code and factories is NOT simple code.
But extensibility asks sometimes for factories...
So you have to take both in consideration.
Just have in mind that most of the time, you will have to maintain a source file MANY times a year and you will NOT have to extend it.
IMO, patterns should only be used when absolutely needed. If you think it can be handy in two years, you are better to use them... in two years.
How complex is the work the factory is handling? Does object creation really need to be abstracted to a different class? A variation of the factory method is having a simple, in-class factory. This really works best if any dependencies have already been injected.
For instance,
public class Customer
{
public Customer CreateNewCustomer()
{
// handle minimally complex create logic here
}
}
As far as Strategy overuse... Again, as #RichardOD explained, will the algorithm ever really change?
Always keep in mind the YAGNI principle. You Aren't Gonna Need It.
Can't you make an AbstractFactory instead off different standalone factories?
AlgorithmFactory creates the algorithms you need based on the concrete factory.