I'm just curious to see what you guys think about this. I heard a bunch of answers passed around the office and I want to see if you guys can have possibly a better one.
Question:
You have two functions outlined below:
function one()
{
A();
B();
C();
}
function two()
{
A();
D();
C();
}
How would you re-write this (anything counts, you could create classes, variables, other methods, anything), to reduce code duplication?
Each of the methods called changes variables that the other functions need to use. Methods A() B() and C() are already defined.
Not all languages will support this approach, and the syntax of passing a function may vary between those that do, but the concept would be:
function one()
{
refactored(B);
}
function two()
{
refactored(D);
}
function refactored(middleMan)
{
A();
middleMan();
C();
}
There is no code duplication here. It looks fine.
Each of the methods called changes variables that the other functions need to use.
I would start by refactoring the entire class to use proper OOP.
There are a number of ways to refactor that code; which I would use depends on the specific application, as it may mean that I need to reconsider things at a higher level, e.g. redefine classes, or at worst review the entire application design because the duplication means I missed some key relationship.
If your functions one() and two() are really three-liners as in the example, I wouldn't rewrite anything. You would loose readability and make the code much harder to understand for the next guy.
If the calls to A() and C() are actually larger blocks of code...
- define a base class with abstract method X() and a concrete
function any()
{
A();
X();
C();
}
define a class One where X() is implemented by B()
define a class Two where X() is implemented by D()
Here's one option.
function (triggerA, triggerB, triggerC, triggerD)
{
A(triggerA);
B(triggerB);
C(triggerC);
D(triggerD);
}
This way you're only calling one function to do it all, and skips whatever you don't need/want to do.
If you have closures, lambdas etc. available, you could write
function one()
{
three(B)
}
function two()
{
three(D);
}
function three(middle)
{
A();
middle();
C();
}
You could (but probably shouldn't) make a class where A() is the constructor and C() is the destructor, and have one() and two() be methods of the class calling B() and D() respectively.
I said you probably shouldn't because OOP should be used to write code that makes sense and not for obscure optimization reasons.
In C++ this is usually accomplished with RAII if the context makes sense... this pattern is usually A() = some init function, C() = some de-init function. There's usually also a context associated that's being initialized or destroyed as well.
class bar
{
bar() {
A();
}
~bar() {
C();
}
};
void one()
{
bar barvar;
B();
}
void two()
{
bar barvar;
D();
}
Related
I have a struct type named as game as follows:
type game struct {
commands map[string]*command
// ...
}
And I want to initialize a map in a struct of this type in the init function. I do it like this
func (game *game) init() {
game.commands = make(map[string]*command)
// ...
}
As I think, there is some code duplication. It would be neat if I could declare the type (map[string]*command) only once. Is there a way to do that? I tried to use reflect but it doesn't seem to work because make builtin takes a type and not a value.
If you are worried that repeating map[string]*command two times is duplication, you can define a new type from it.
type commandsMap map[string]*command
type game struct {
commands commandsMap
// ...
}
func (game *game) init() {
game.commands = make(commandsMap)
// ...
}
There is not a code duplication here. Code duplication is when you have multiple points in your code that does the same thing.
That being said, you can leave your code like it is or you can use a Constructor, which has the benefit of restricting this initialization where you type is and is also a cleaner approach imho.
type game struct {
commands map[string]*command
}
func game() *game {
return &game{commands: make(map[string]*command)}
}
That way, when you need a game object, you can just do
gameObject := game()
and then use the map methods as you normally would (or you can also make a utility method just for that)
I am still learning the Go way of doing things, coming from a C++ background. I am looking for feedback contrasting OOP inheritance to interface composition.
I have a design situation in a Go program where, if I was implementing in C++, I would solve with an abstract base class.
Suppose I need a base class, which has many implementors. The base class has shared methods that do work on abstract data items. Different Worker implementations provide CRUD operations on different item types, but workers all use the shared methods of the base class for general work.
In C++ I might do it this way
class IItem
{
// virtual methods
};
class IWorker
{
public:
// one of many virtual functions that deal with IItem CRUD
virtual IItem* createItem() = 0;
// concrete method that works on interfaces
void doWork()
{
IItem* item = createItem();
// do stuff with an IItem*
}
};
class Toy : public IItem
{
};
// one of many kinds of workers
class ElfWorker : public IWorker
{
public:
ElfWorker()
{
// constructor implicitly calls IWorker()
}
IItem* createItem() override
{
return new Toy;
}
};
In Go you don't have abstract virtual methods such as IWorker::createItem(). Concrete classes need to supply the base with an interface or function that do the right thing.
So I think it is the case that the Go code the ew.ItemCRUD interface has to be explicitly set with a pointer to an ElfWorker.
The elf knows how to createItem(), which in his case happens to be Toy object. Other workers would implement their own ItemCRUD for their data objects.
type Item interface {
// various methods
}
type ItemCRUD interface {
create() Item
// other CRUD
}
type Worker struct {
ItemCRUD // embedded interface
}
func (w *Worker) doWork() {
item := w.create()
// do stuff with item
}
type Toy struct {
}
type ElfWorker struct {
Worker // embedded
// ..
}
func NewElfWorker() *ElfWorker {
ew := &ElfWorker{}
ew.ItemCRUD = ew // <-- #### set Worker ItemCRUD explicitly ####
return ew
}
func (ew *ElfWorker) createItem() Item {
return &Toy{}
}
// more ElfWorker Item CRUD
func bigFunction(w *Worker) {
// ...
w.doWork()
// ..
}
So the part that I am wrestling a bit with is explicit setting. Seems like the "Go way" of composition does require this explicit step if I want the base Worker class to provide shared methods on Items.
Thoughts?
Beeing new to go myself, this answer is not backed by years of go experience :-)
I don't know, if the way you tackle this is the correct approach.
go allows interfaces to be implemented without explicit declaration. If you have elves, and you need them to do ItemCRUD methods, just implement them.
The method set will then match the interface and you can use the elf as a ItemCRUD where required.
To supply any elf object with a default ItemCRUD Implementation, you should implement an adapter for the ItemCRUD and compose the adapter with your abstract elf. The abstract methods could have a default implementation as log.Fatal("not implemented")
The concrete elves shadow the adapter's methods, this answers your question: It is not required to insert the object during creation.
Yet, since go has no generics, it may not be the right approach to have an ItemCRUD.
Im not entirely clear what the plan is with the above code and without understanding that its hard to suggest specific solutions, what is clear is you are very much coming to the party with an established OOP mindset (I did too) which is rarely helpful in finding the best solution in golang.
In Golang I wouldnt usually embed an interface in an implementation, interfaces are satisfied implicitly in Golang which allows for a nice separation of expectation and implementation which should generally be respected.
A reciever method should expect an interface, the implementation passed at runtime should just satisfy the signature of that interface implicitly.
So perhaps my doWork method needs to be able to createItems then it would be the doWork method that would accept any implementation of ItemCRUD which it could call to create an item. But this is me guessing at what you really want to do here, I suspect if you just separate implementation from interface you will probably answer your own question.
Can someone show me an example of where this syntax would show up in code?
thing.Foo().Bar(this)
From the looks of it, I see an object that calls a function that calls another function?
I obviously don't know how it works. If you have the slightest idea, I would appreciate a suggestion. Thanks!
This is one of many possible scenarios:
struct somethingelse
{
void SomeOtherMethod()
{
thing.Foo().Bar(this);
}
};
struct foo
{
void Bar(somethingelse *pSomethingElse);
};
struct thing
{
foo &Foo() {return m_foo;}
foo m_foo;
};
What makes this a bit unusual is that the naming convention for the class and method naming is the opposite of the de-facto one in which classes are capitalised and methods camel-cased.
This code could be found in any non-static member function of a class. The Foo() function of thing returns an object of a class with a member function Bar that takes a pointer to the current object (this) as argument.
I have the following pseudocode for algorithm with multiple IF conditions. How to avoid such nesting with some checking or more efficient way.
If (there does not exist a house) then
if (road ==1) then do something
if (road ==2) then do something
if (road ==3) then do something
end if end if end if end if
If (road ==4) AND (there exist a house) then do something end if
I'd probably be more concerned about readability than efficiency, unless you have profiled your code and found it is a bottleneck.
For readability you could use an array of classes that implement a common interface. In pseudo code, given this interface:
interface Callback
{
void DoJob()
}
and various classes that implement the interface:
class DoThing1 implements Callback { public void DoJob() { .. } }
class DoThing2 implements Callback { public void DoJob() { .. } }
Then in your main code have an array of these callbacks:
Callback m_roadHandlers[MAX_HANDLERS]
And call them like so:
if (house and road == 4)
m_roadHandlers[road].DoJob();
else if (no house and road >= 1 and road <= 3)
m_roadHandlers[road].DoJob();
You tagged Java, so I illustrated it as above because Java doesn't (yet) have a notion of method callbacks so as far as I know you can't pass in a method (it's been a while since I used Java), so you might have to pass in the class to the callback. In C# you could use delegates and pass in methods in the same class.
According to clean code laws, we want to have functions which do only one thing and are on the same "level of abstraction". But how to name function, whose work is just to check some condition and do the work if condition is true. For example, how could this function be named?
public void HowToNameThis(){
if(!ComponentIsInstalled()){
DisableCheckbox();
}
}
I thought about naming it like DisableCheckboxIfComponentIsNotInstalled, but then the name just repeats the code, which effectively means I have created a function but did not create any abstraction.
CleanCode also suggest that you stay as positive as you can in your code. If you reverse the logic within your method, then, naming becomes easier.
public void TryEnableComponent() {
if(ComponentIsInstalled()) {
EnableCheckbox();
}
}
I generally think really hard about if the IF is really deserving it's own function.
And then often end up inlining it:
Like this (pseudo):
void SetupInstallerWindow()
{
LoadLicenseAgreement();
if(!ComponentIsInstalled()){
DisableCheckbox();
}
BringWindowTop();
}
If that really gets to messy, here's an idea for a name might provide more context for the reader:
AllowReinstallationOfComponent()