I have some reports; Report1, Report2, Report3
and I'm using some Builder classes to build these reports programmatically for different scenarios and sections.
One way of naming my Grid Table builder classes is this:
var builder = new Report1.GridTableBuilderForSection1()
where Report1 is a namespace (folder).
The second approach is to use this:
var builder = new GridTableBuilderForReport1ForSection1()
in the section approach name of the classes become very long.
What's the best way to name these classes in your view?
First of all "Section1" is a terrible choice. The above version is nicer, because you get to put things into different folders. Try be more imaginative, or whatever:
var bldr; (not so important)
bldr = new InitialReport.SectionHeaderBuilder()
bldr2= new InitialReport.SectionDescriptionBuilder()
bldr3= new GraphSummary.SectionDataBuilder()
alternatively: (sorted the other way, I like this a lot.. but it's kinda weird depending on what your native language is)
b1 = new ReportInitial.getBuilderSecHeader()
b2 = new ReportSubsequent.getBuilderSecMain()
b3 = new ReportFinal.getBuilderSecGraphics()
.. this is great if you use auto-completion a lot.
I've built and designed a successful high performance reporting engine for a data warehouse company a couple years ago and I used a Strategy pattern or Abstract Factory pattern to solve a similar issue...
Strategy Pattern (wiki)
Abstract Factory Pattern (wiki)
If you use a Strategy approach your code might look like this...
def report1 = new Report1()
report1.buildHeader(new FancyHeader(data);
report1.buildSection(new GridTable(data));
report1.buildFooter(new SimpleFooter(data));
Or if you simply looking to organize concrete classes with long names that very similar names you could use a type of static class hierarchy to make the code a little more readable...
def thing = Reports.GridBuilders.EmployeeGrids.DailyEmployeeAttendance
def another = Reports.GridBuilders.EmployeeGrids.WeeklyPayroll
def oneMore = Reports.GridBuilders.EmployeeGrids.Managers
Related
It's been a very long time since I touched object oriented programming, so I'm a bit rusty and would appreciate your insight.
Given a class, for example CDPlayer, that includes the field numberOfTracks and currentTrack and the methods getCurrentTrack and setCurrentTrack, where should I put the functionality to set the current track to a random track? In a method such as setRandomTrack inside this class, or in the application code outside this class (e.g. player1.setCurrentTrack(randomnumbergeneratingcode))?
What are the pros and cons of each of these approaches? Which is easier to use, change and maintain? The above example is quite simple, but how do things change when I want e.g. the random number generation to be flexible - one CDPlayer instance to use a normal distribution for randomising, another to use a flat distribution, another to use a distribution defined by some set of numbers, and so forth.
EDIT
Thanks for the three replies so far.
Consider an extension to the op... After a decent amount of coding it becomes clear that on numerous occasions we've had to, in the application code, change current the track to the track three before it but only on Thursdays (which potentially has non-trivial conditional logic to work properly). It's clear that we're going to have to do so many times more throughout the dev process. This functionality isn't going to be user facing (it's useless as far as users would be concerned), it's just something that we need to set on many occasions in the code for some reason.
Do we created a setThreeTracksBeforeOnThursdays method in the class and break the tight representative model of a CD player that this class has, or do we absolutely stick to the tight representative model and keep this functionality in the application code, despite the pain it adds to the application code? Should the design wag the developers or should the developers wag the design?
Well there is no real benefit to where the code is besides that its more readable.
But in some cases it could be less redundant to put the code in the class, it all depends on the language. For example:
C# code in the class:
private Random random = new Random();
public void setRandomTrack()
{
setCurrentTrack(random.NextInt());
}
C# code outside the class:
Random random = new Random();
CDPlayer player = new CDPlayer()
player.setCurrentTrack(random.NextInt());
The code outside has to create a Random Generator outside the class to generate a random integer, you might have to create the Random Generator more than once if its not visible to the class where you calling it from.
If it is a function that all CD players have, then it should be inside the CDPlayer class.
If it is a function that just a few CD players have, then you should inherit the CDPlayer class and put the function in the child class.
If it is a function that no CD player has, then there is no reason to include it in the class. Does it make sense for the CDPlayer class to know about picking random tracks? If not, it should be implemented outside the class.
The pro of putting it inside CDPlayer is that it will be a single method call, and that the function is pretty typical of CD players so it "feels right".
A con of putting it in your application is that it requires two calls, one to get the number of tracks so you can generate the random number, and one to set it.
A con of putting it in CDPlayer is that the class needs to know about random numbers. In this particular case, it's simple enough to use a standard library, but if this were some top security CIA CD player that could be an issue. (Just noticed youvedited your post to hint at something similar)
I'd put the code in CDPlayer, (and add a method to change the random number generator, the fancy term for this is Dependency Injection) but this post hopefully gives you a few of the pros and cons.
Let's try to implement this feature. What are requirements for playing random track?
it should be random (of course),
it should be not current track (nobody wants to hear current track five times in a row if there other tracks to play)
you should pick track from those which exist in player (track number should not exceed count of tracks).
I will use C#:
Random random = new Random();
CDPlayer player = new CDPlayer();
// creates list of track indexes, e.g. { 1, 2, 3, 4, 5, 6, 7 }
var tracksNotPlayed = Enumerable.Range(0, player.NumberOfTracks - 1).ToList();
if(tracksNotPlayed.Count == 0)
// initialize list again, or stop
int index = random.Next(tracksNotPlayed.Count);
int nextTrack = tracksNotPlayed[index];
player.SetCurrentTrack(nextTrack);
tracksNotPlayed.Remove(nextTrack);
That looks like feature envy to me - some other class uses data from player to implement this functionality. Not good. Let's do some refactoring - move all this stuff into player:
public void PlayRandomTrack() // Shuffle
{
if(tracksNotPlayed.Count == 0)
tracksNotPlayed = Enumerable.Range(0, numberOfTracks - 1).ToList();
int index = random.Next(tracksNotPlayed.Count);
int nextTrack = tracksNotPlayed[index];
SetCurrentTrack(nextTrack);
tracksNotPlayed.Remove(nextTrack);
}
It looks better and it's much easier to use outside:
CDPlayer player = new CDPlayer();
player.PlayRandomTrack();
Also if you are implementing something like Winamp (it has two modes - shuffle playing and sequential playing when it automatically plays songs one by one) then consider to move this logic into some Strategy (or it should be Iterator?), which will have two implementations - sequential and shuffle, and will know nothing about player - it's responsibility will be picking number in some range (number of tracks or collection being enumerated should be passed):
public abstract class CollectionIterator<T>
{
public CollectionIterator(IEnumerable<T> source)
{
// save source
}
abstract int GetNextItemIndex();
}
The player will use this iterators/strategies to play next item:
public void PlayTrack()
{
SetCurrentTrack(iterator.GetNextItemIndex());
}
So, we have clear separation of responsibilities here - client uses player to listen music, player knows how to play music, and iterator knows how to pick next item from collection. You can create ThursdaysCollectionIterator if you want some other sequences on Thursdays. That will keep your player and client code untouched.
I have a question about IOC, factories, and the Open/Closed principle.
consider, if you will, the following factory
public function PODocument( _type as string) as IPODocument
dim d as new PODocument
if _type = "service" then
d.header = new ServicePOHeader()
d.details = new ServicePOLineItems()
else if _type = "merchandise" then
d.header = new MerchandisePOHeader()
d.details = new MerchandisePOLineItems()
end if
return d
end function
This is working for me and I can nicely have a webpage show information about heterogeneous collections.
My challenge is that today someone told me sometimes a certain customer will order a service and merchandise together. Come on, who among us could have seen that coming?
So I write a new set of providers that handle the added complexity, changed the factory to include a case for the new type, I'm back off and running.
However, I have violated the open/closed principle by changing the factory, which was released to production.
Is there a way to set this up so that I am not constantly changing the factory?
thanks in advance.
Yes. The simplest example for your case would be to define a factory class for each _type, and name them ServiceFactory, MerchandiseFactory, etc, or put a <PODocumentType("Service")> etc on them.
Then just find all factories (for example, using reflection), put them in a Dictionary(Of String, IPODocumentFactory) and select correct one based on key.
In a more complicated case, IPODocumentFactory interface may include CanCreate() method in addition to Create(). Then you can select a factory on the list based on its opinion about current situation.
Note that the discovery and list resolution support is often provided out of the box by DI frameworks such as Unity or Autofac.
I see why it's a legal declaration, but why would it be useful?
How is this different from just going:
Bear bear = new Bear(); //?
What can I do with the object Animal bear = new Bear(); that I can't do with the latter?
Attempt at clarification:
What's the practical diference between declaring something like this:
A. SuperClass x = new SubClass();
versus,
B. SubClass x = new SubClass();
What can you do with the object in A that you can't do with B? Why would you want to declare an object like this at all?
Thanks!
In general, it's desirable to have loose coupling whenever possible. In part, this means that your code should know as little as possible about the objects it uses. If it is sufficient for your code to know that it's an Animal, then why should you let it know it's a Bear? Next week you might want to run your code with a Chicken.
By restricting yourself to the interface exposed by Animal, you've now made it easy to drop in any other particular animal in its place and you know that you haven't used any Bear-specific methods.
To achieve polymorphism and to write generic code for all the Animals rather than specific to bear.
So, Animal animal = new Bear() and we can use the same reference we can use to point to other different animals.
I'd say that the main difference I see is Bear bear = new Bear(); is defined as an object Bear while the Animal bear = new Bear(); is an object Animal. This method defines a new Bear as a Animal while the other is defining a new bear as a Bear. Both are practically the same thing, however one way might be more useful if you needed the new Bear() in a particular object.
I'm new to OOP and I'm in the following situation: I have something like a report "Engine" that is used for several reports, the only thing needed is the path of a config file.
I'll code in Python, but this is an agnostic question.So, I have the following two approaches
A) class ReportEngine is an abstract class that has everything needed BUT the path for the config file. This way you just have to instantiate the ReportX class
class ReportEngine(object):
...
class Report1(ReportEngine):
_config_path = '...'
class Report2(ReportEngine):
_config_path = '...'
report_1 = Report1()
B) class ReportEngine can be instantiated passing the config file path
class ReportEngine(object):
def __init__(self, config_path):
self._config_path = config_path
...
report_1 = ReportEngine(config_path="/files/...")
Which approach is the right one? In case it matters, the report object would be inserted in another class, using composition.
IMHO the A) approach is better if you need to implement report engines that are different from each other. If your reports are populated using different logic, follow this approach.
But if the only difference among your report engines is the _config_path i think that B) approach is the right one for you. Obviosly, this way you'll have a shared logic to build every report, regardless the report type.
Generally spoken, put everything which every Report has, in the superclass. Put specific things in the subclasses.
So in your case, put the _config_path in the superclass ReportEngine like in B) (since every Report has a _config_path), but instanciate specific Reports like in A), whereas every Report can set its own path.
I don't know Python, but did a quick search for the proper syntax for Python 3.0+, I hope it makes sense:
class ReportEngine(object):
def __init__(self, config_path):
self._config_path = config_path
def printPath(self):
print self._config_path
...
class Report1(ReportEngine):
def __init__(self):
super().__init__('/files/report1/...')
Then a
reportObj = Report1()
reportObj.printPath()
should print
'/files/report1/...'
Basically the main difference is that approach A is more flexible than B(not mutual change in one report does not influence other reports), while B is simpler and clearer (shows exactly where the difference is) but a change affecting one report type would require more work. If you are pretty sure the reports won't change in time - go with B, if you feel like the differences will not be common in the future - go with A.
Is it possible to configure Hiberate/NHibernate not to use the default constructor to create objects when reading from the database?
When Hibernate reads 10 customers from a table, it creates 10 Customer objects. It does this by
Customer c = new Customer();
Can I tell Hibernate to do the following instead:
Customer c = ACertainStaticFactory.CreateNewCustomer();
or even to manage a factory instance:
ACertainFactory factory = .....;
Customer c = factory.CreateNewCustomer();
or even more sophisticated, to pass a parameter which I set before:
// My client code
Query query = session.CreateQuery(...);
// either:
query.SetSomeParameter(someObject);
// or:
session.SetSomeParameter(someObject);
query.List();
// Hibernate should then behave like this:
Customer c = new Customer(someObject);
// or
Customer c = ACertainStaticFactory.CreateNewCustomer(someObject);
// etc.
Is that possible in anyway? If yes: How? If no: Is there an alternative?
When Hibernate reads 10 customers from a table, it creates 10 Customer objects. It does this by (...)
More precisely, Hibernate uses Class<T>#newInstance() to create new instances of an entity, which relies on the no-arg constructor. Hence the need to provide it.
Is that possible in anyway? If yes: How? If no: Is there an alternative?
Your requirement looks close to the Possible to have Hibernate hydrate objects with Factory? thread on Hibernate's forums so I'll quote Steve's answer (updated to match current names):
This is totally doable. In fact you
have two options:
create a custom EntityPersister implementation;
create a custom Interceptor implementation, specifically the
Interceptor.instantiate() method will
be of interest to you...
I think I'd go the interceptor way (not sure about your complex scenario but implementing the factory approach looks pretty easy).
Check this out, may be helpful:
http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html