SOLID priciples - Single Responsible is just about composition or also dependency inversion? - solid-principles

I have seen examples online about the Single Responsible principle.
They always use IoC/DI as an example.
They move the code from class A to class B and pass class B as reference.
See code below:
class B {}
class A {
b;
// reference used
constructor(b) {
this.b = b;
}
doStuff() {
...
this.b.doSomeOtherStuff();
}
}
But the Single Responsible principle is about to increase the coherence.
Theoretically the code above would also follow the Single Reponsible principle without
passing down a reference to class B, right?
Like this:
class B {}
class A {
// no reference
constructor() {
this.b = new B;
}
doStuff() {
...
this.b.doSomeOtherStuff();
}
}

In the book Clean Code by Robert C. Martin there is an example reagarding the SRP where he uses only composition.
So I would say yes, Singe Responsible Priciple is valid without IoC/DI.
In the example below hes directly creating an instance of the LinkedList.
public class Stack {
private int topOfStack = 0;
// creating a direct instance here
List < Integer > elements = new LinkedList < Integer > ();
public int size() {
return topOfStack;
}
public void push(int element) {
topOfStack++;
elements.add(element);
}
public int pop() throws PoppedWhenEmpty {
if (topOfStack == 0)
throw new PoppedWhenEmpty();
int element = elements.get(--topOfStack);
elements.remove(topOfStack);
return element;
}
}

Related

Reference methods from another class in traceur

I'm testing classes in ES6 using traceur but it's not working as I expected.
I am trying to use a method as a reference in another class but when it's called I get the reference of the caller class when read the value of this.
Here is my code:
class A {
constructor(anotherMethod){
this.anotherMethod = anotherMethod;
this.name = "A";
}
myMethod (){
console.log(this.name);
this.anotherMethod();
}
}
class B {
constructor(){
this.a = new A(this.myMethod);
this.name = "B";
}
myMethod(){
console.log(this.name);
}
}
var c = new B();
c.a.myMethod();
My expected log is:
A
B
But it is showing:
A
A
In class B, when the constructor function runs:
this.a = new A(this.myMethod);
You're actually setting the method myMethod of B to A. When A's constructor runs,
this.myMethod, is set to A's anotherMethod. Now if you try printing this.a in your B's constructor you will get name : A. Which is actually referencing the class A.
Now when you try executing the method, c.a.myMethod(), As A contains the reference to class A, it's invoking the myMethod of A. Inside this method, this will refer to the current execution context object which is A. That's the reason why you're seeing A in both the consoles.
In short, You're only assigning the function to A and not setting the context.
You can force fat arrow using below:
class B {
constructor(){
this.a = new A(this.myMethod);
this.name = "B";
}
myMethod = () => {
console.log(this);
}
}
Now you will get the desired output. But unfortunately traceur doesn't support it. Only babel supports fat arrow inside functions which is part of ES7 stage 0 Class Properties.
As suggested by Felix King: Binding the context using bind is more than enough currently
class B {
constructor(){
this.a = new A(this.myMethod.bind(this));
this.name = "B";
}
myMethod() {
console.log(this);
}
}

CircularList in ActionScript 3

I have been working on an AS3 project for some while and I think that I've hit a wall. My project requires a series of elements to be arranged in a Circular List, so I copied myself in a Circular List I had done before in C#.
Problem is, that one was heavily dependant on the usage of Generics. Now I don't have those.
Here are the codes. The T variable type represents the generics that I wish existed.
Node.as:
package
{
public class Node
{
var nodeContent:T;
var nextNode:Node;
function Node(nodeElement:T)
{
this.nodeContent = nodeElement;
}
}
}
CircularList.as:
package
{
public class CircularList
{
var head:Node;
var tail:Node;
var listLength:int;
function CircularList()
{
this.head = null;
this.tail = null;
this.listLength = 0;
}
function Add(addition:T)
{
adding:Node = new Node(addition);
if(this.head == null)
{
this.head = adding;
this.tail = adding;
head.nextNode = tail;
tail.nextNode = head;
}
else
{
tail.nextNode = adding;
tail = adding;
tail.nextNode = head;
}
listLength++;
}
function Find(requested:T):Node
{
var finder:Node = null;
var searching = head;
var i:int;
while(i <= listLength)
{
if(searching.nodeContent == requested)
{
finder = searching;
}
searching = searchig.nextNode;
i++;
}
return finder;
}
}
}
Is there a way to make this thing work without the generics?
EDIT: The real problem with this is that I want the NodeContent in the Node class to be an object. I want to make a list of people sitting on a circular table, basically, but I would like to have a code that I can reuse, rather than something specifically made for this problem
From the comments it seems like your best option here would be to use an interface.
Instead of using a type have all classes T implement an interface like INode. In this interface you can define all the functionality that your type T requires and implement it as needed in each of your implementing classes. This way you can change your function signatures to take type INode instead of Class or * and have a common set of methods that these functions can act upon.
function Add(addition:INode){
//add logic on INode
}
function Find(requested:INode):Node{
//find logic on INode
}
edit: a bit of info about interfaces,
http://active.tutsplus.com/tutorials/actionscript/as3-101-oop-introduction-to-interfaces/
say we have two Classes, A, B and each of these classes have a similar method, doTrace, that needs to be implemented differently. We can define an interface, implement it in both of these classes and pass that type into any method looking to call doTrace
Start with the interface called ITraceable,
public interface ITraceable{
function doTrace():void //all methods defined in interfaces are seen as public
}
Now our two Classes, A and B
public class A implements ITraceable { //implementing our interface, when we do this we need to define all methods in ITraceable
public function doTrace():void{
trace("I am A");
}
}
Do a similar thing for B
public class B implements ITraceable {
public function doTrace():void{
trace("I am B");
}
}
Now in some outside class we want to use this
public function letsTrace():void{
doTheTrace(new A()) //I am A
doTheTrace(new B()) //I am B
}
public function doTheTrace(object:ITraceable):void { //now we can pass both A and B into this function
object.doTrace(); //since ITraceable requires all objects that implement it have this method we can guarantee it will be here
}
Hope this helps you through your application

How to Override Constants in ActionScript 3

I have the two following classes:
public class Parent{
static internal const _name:String = "Parent";
public function get name():String{
return _name;
}
}
public class Child{
static internal const _name:String = "Child";
}
If I create an instance of class Child and call its name() getter, since it will call the name() method it inherits from Parent, it returns "Parent". I could, of course, override the name() method:
public class Child{
static internal const _name:String = "Child";
override public function get name():String{
return _name;
}
}
That returns "Child". However, it seems silly to have to copy the exact same code of the method from the parent. Is there any simpler way to do this?
I would take a different approach by making the "name" property a requirement for the parent's constructor:
public class Parent
{
static internal var _name : String;
public function Parent(name : String = "Parent") {
_name = name;
}
public function get name() : String {
return _name;
}
}
Child Class:
public class Child extends Parent
{
public function Child() {
super("Child");
}
}
Firstly, you cannot override static methods or properties - they are not inherited, so no override for them.
Secondly, if you declared a constant to be of a complex type, it is not really a constant. I.e. if it is an object, then you can change its keys / values, if it is an array, you can add / remove members and so on.
But the desire to make this functionality more generic is understandable. So, what I'd do:
Have some property outside both parent and child, let say in class X, or package Y. Let it be package Y. So, you'd create a dictionary in package Y, let it be Y.names and in your name getter you'd do:
import Y.names;
. . .
public function get name() {
return names[(this as Object).constructor];
}
your names variable would be:
package Y {
public var names:Dictionary = generateNames();
internal function generateNames():Dictionary {
var result:Dictionary = new Dictionary();
result[ChildClass] = "child";
result[ParentClass] = "parent";
. . .
return result;
}
}
This way it would be sufficient to only implement name getter in super-class, and all inheriting classes will be able to use super-class code as is, no need to change anything. However, this means that some (maybe important) information pertaining to this class will be stored elsewhere (may be difficult to find, this is not the common way people program in AS3).
your implementation of get name should look like this, then the getter is one and each of the new classes needs to have it's own public static var _name defined:
//in the base class
public function get name():String
{
var _sName:String;
if ((this as Object).constructor._name)
{
_sName = (this as Object).constructor._name;
}
else
{
try
{
var o:Object = getSuperClass(this);
while (o)
{
if (o._name)
{
_sName = o._name;
break;
}
o = getSuperClass(o);
}
}
catch (e:*)
{}
}
return _sName;
}
//as found here: http://www.actionscriptdeveloper.co.uk/getting-the-class-of-an-object-in-as3/
public static function getSuperClass(o: Object): Object
{
var n: String = getQualifiedSuperclassName(o);
if (n == null)
return(null);
return getDefinitionByName(n);
}
the static members can be accessed only via class reference which we can get from constructor object, "this" will point to the current class in the inheritance chain so you can call this in parent class and it will point to a Child in a Child class.
[EDIT]
I've modified it so it tests for existance of the public static property _name if not found on "this" instance then in a loop the parent class is checked until one is found - like inheritance:)
I'm using this feature to create clone method: constructor as helper in clone method implementation
best regards
Why don't you store such a constant within a corresponding function instead of declaring an inaccessible constant?
class Parent {
...
public function get name():String { return 'Parent'; }
}
class Child extends Parent {
...
override public function get name():String { return 'Child'; }
}
By the way, if your Parent class is a descendant of DisplayObject, you should be careful with name property, as it's needed sometimes by operating code, e.g. getChildByName().
I have found something that seems to work. Any feedback is greatly appreciated:
public class Parent{
prototype._name = "Parent";
public function get name():String{
return this["_name"];
}
}
public class Child{
prototype._name = "Child";
}

How to pass a reference to class into another class

The question is a bit silly. I am trying to implement a skill updating system. So to explain.
There is a class
class AppInfo
{
public static var power:int = 10;
public static var speed:int = 20;
}
and class SmartButton which should take a reference to one of the static variables e.g. power in a constructor and increment it on the given value.
e.g.
class SmartButton
{
public function onClick(skillReference:int = <AppInfo.power>, incrementVAlue:int = 10)
{
skillReference += incrementVAlue
}
}
I want this code to update the value of the power in AppInfo class. But this doesn't happen... I assume because the skill was passed as value not as reference...
Can you suggest a way of solving the task?
Thanks
Your assumption is correct, ints are passed by value rather than reference. One direct approach would be to encapsulate power into a reference type (a class) rather than a value type:
class Skill {
public var value:int;
public function Skill(val:int) {
this.value = val;
}
}
class AppInfo
{
public static var power:Skill = new Skill(10);
public static var speed:Skill = new Skill(20);
}
Then passing power should pass it as a reference to the instance. Though you would have to change your implemenation a bit to use skillReference.value instead.
Aside from that, I think there are a couple of ways to abstract what you want out. One way would be use an interface and leverage some dependency injection.
interface ISkills
{
function get power():int;
function set power(val:int):void;
}
class AppInfo implements ISkills
{
private static _power:int = 0;
public function get power():int { return _power; }
public function set power(val:int):void { _power = val; }
}
class SmartButton
{
public function onClick(skills:int = ISkills, skill:String = "power", incrementVAlue:int = 10)
{
skills[skill] += incrementVAlue
}
}
The idea here that you want to decouple your usage from your implementation. In this case SmartButton doesn't need to know how Skills work just how to operate on them. It loses its reference to the static class AppInfo in favor of an injectable instance. There are some advantages to this approach, it makes it easier to test and easier to swap implementations later if you decide that a static class isn't the best implementation idea without having to update a bunch of classes/code. Also, rather than injecting ISkills into the method, you could inject it into the constructor of SmartButton, and keep a private reference to the skill container.
Another approach would be to use a functional approach.
class SmartButton
{
public var defaultWorker:Function = function(val:int):void {
AppInfo.power += val;
}
public function onClick(worker:Function = undefined, incrementValue:int = 10):void
{
if(worker == undefined) worker = defaultWorker;
worker.call(this, incrementValue);
}
}
Again, in this case, rather than tightly coupling your implementation to use the AppInfo class directly, you inject a "worker" for it do the work for you (if the worker is undefined then use the default worker. You can then swap out which property gets changed by changing the closure that gets passed in. For instance if you wanted to change speed instead then you would call:
var smartButton:SmartButton;
smartButton.onClick(function(val:int):void { AppInfo.speed += val});
Not quite as succinct as it could be, but it gets the job done.
The obligatory "elegantly sophisticated" approach using the command pattern:
Interface Command {
function execute():void;
}
Class UpdatePower implements Command {
private var appInfo:AppInfo;
private var delta:int;
public function UpdatePower(appInfo:AppInfo, delta:int) {
this.appInfo = appInfo;
this.delta = delta;
}
public function execute():void {
appInfo.delta += delta;
}
}
Class SmartButton {
var command:Command;
public function SmartButton(command:Command) {
this.command = command;
}
public function onClick(event:Event):void {
command.execute();
}
}
I would probably implement this in a slightly different way.
Maybe something like;
class Properties {
private var _properties:Dictionary = new Dictionary();
public function setValue(key:String, value:int) {
_properties[key] = value;
}
public function getValue(key:String):int {
if( !_properties[key] ) return 0;
else return _properties[key];
}
public function modifyValue(key:String, value:int) {
setValue(key, getValue(key) + value);
}
}
class SmartButton
{
public function onClick(target:Properties, key:String, incrementValue:int = 10) {
target.modifyValue(key, incrementValue);
}
}
Or something along those lines.

What is the best way to implement a singleton pattern class in Actionscript 3?

Since AS3 does not allow private constructors, it seems the only way to construct a singleton and guarantee the constructor isn't explicitly created via "new" is to pass a single parameter and check it.
I've heard two recommendations, one is to check the caller and ensure it's the static getInstance(), and the other is to have a private/internal class in the same package namespace.
The private object passed on the constructor seems preferable but it does not look like you can have a private class in the same package. Is this true? And more importantly is it the best way to implement a singleton?
A slight adaptation of enobrev's answer is to have instance as a getter. Some would say this is more elegant. Also, enobrev's answer won't enforce a Singleton if you call the constructor before calling getInstance. This may not be perfect, but I have tested this and it works. (There is definitely another good way to do this in the book "Advanced ActionScrpt3 with Design Patterns" too).
package {
public class Singleton {
private static var _instance:Singleton;
public function Singleton(enforcer:SingletonEnforcer) {
if( !enforcer)
{
throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
}
}
public static function get instance():Singleton
{
if(!Singleton._instance)
{
Singleton._instance = new Singleton(new SingletonEnforcer());
}
return Singleton._instance;
}
}
}
class SingletonEnforcer{}
I've been using this for some time, which I believe I originally got from wikipedia of all places.
package {
public final class Singleton {
private static var instance:Singleton = new Singleton();
public function Singleton() {
if( Singleton.instance ) {
throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
}
}
public static function getInstance():Singleton {
return Singleton.instance;
}
}
}
Here's an interesting summary of the problem, which leads to a similar solution.
You can get a private class like so:
package some.pack
{
public class Foo
{
public Foo(f : CheckFoo)
{
if (f == null) throw new Exception(...);
}
}
static private inst : Foo;
static public getInstance() : Foo
{
if (inst == null)
inst = new Foo(new CheckFoo());
return inst;
}
}
class CheckFoo
{
}
The pattern which is used by Cairngorm (which may not be the best) is to throw a runtime exception in the constructor if the constructor is being called a second time. For Example:
public class Foo {
private static var instance : Foo;
public Foo() {
if( instance != null ) {
throw new Exception ("Singleton constructor called");
}
instance = this;
}
public static getInstance() : Foo {
if( instance == null ) {
instance = new Foo();
}
return instance;
}
}