Combining two identical sub classes - apache-flex

So I have two sub classes that extend different base classes in Flex how can I combine these so that I am not repeating myself.
Basically I have something like
public class A extends B {
// methods
}
public class C extends D {
// same methods as class A
}
any way to combine this so that I am not repeating the same code twice.

Favor composition over inheritance
So, the question is, how should you compose the solution?
One possibility is to use Decorator pattern. This is essentially a wrapper around your existing Classes. To make this work, your Classes will probably need to implement an Interface that exposes whatever you'll need to do the job.
So something like:
public interface IFoo {
function get name():String;
function set name(value:String):void;
}
public class A extends B implements IFoo {
protected var _name:String;
public function get name():String {
return _name;
}
public function set name(value:String):void {
_name = value;
}
}
public class C extends D implements IFoo {
protected var _name:String;
public function get name():String {
return _name;
}
public function set name(value:String):void {
if (_value != _name) {
_name = value;
dispatchEvent(new Event('nameChanged'));
}
}
}
public class FooDecorator {
protected var _foo:IFoo;
public function FooDecorator(foo:IFoo) {
_foo = foo;
}
public function sayName():void {
trace('foo name is', _foo.name);
}
}
Another solution is to give both A and C member variables of a fifth type that encapsulate the behavior (like what Jeffry said, but I prefer to obey the law of Demeter where possible):
class NameSayer {
function sayName(name:String):void {
trace('foo name is', _foo.name);
}
}
then
public class A extends B {
public var name:String;
public var sayer:NameSayer;
//note that this method would be identical in both Classes
//but this is OK because the underlying logic is encapsulated
//and can be easily changed
public function sayName():void {
if (sayer) {
sayer.sayName();
}
}
}
I think many developers get too hung up on zealously following DRY and, as Jeffry says, this can cause other, worse, problems in your architecture. Which, if any, of these solutions is appropriate will depend on exactly what you're trying to accomplish.

You have two child classes (extending different parents) that implement the exact same methods.
public class B {}
public class D {}
public class A extends B {
// methods
m1();
m2();
...
}
public class C extends D {
// same methods as class A
m1();
m2();
...
}
Now lets make some points about it.
In assigning a method to a class, the basic idea is that, that method or behaviour really belongs to that class - it is really a property of that class or type. For example, breathing for Animal. When this is the case, the behaviour is tied to class state (or data, or attributes, or variables). If a method does not access the class variables in any ways, then, that method may not belong there. At least it is the general rule.
Now, in your case, you have m1(), m2(), ... methods that appear in two different classes. This raises the possibility that they may not be really tied to the state of those classes. If so, then the better solution is to completely remove them into a new class.
If you do so,
You will also get rid of two classes, A and C, which now exist only for this purpose.
You get rid of two inheritance relationships. This makes you code much simpler.
And, you will achieve your objective of not repeating your self.
--
//Parent classes (child classes are now gone)
public class B {}
public class D {}
--
// Your new class
public class X {
// methods that previously were in A and C
m1();
m2();
...
}

Although, I have mixed feelings about its use; you can use the include directive.
Create a file, like this, named sharedMethods.as (or whatever you want). This is not a real class; it just includes code snippets:
public var mySharedMethod(mySharedMethodArguments:ArgumentType):void{
// do something
}
Then you can include it in your your other classes:
public class A extends B {
include "sharedMethods.as";
}
public class C extends D {
include "sharedMethods.as";
}
The code from your include file will be compiled as part of Class A and Class C.
You could also put your shared code in another class and have an instance of that class in both A and C. Then you either have to write wrapper methods or drill down the calls sort of like this:aInstance.sharedCodeObject.sharedMethod();
My intuition is that if you run into this a lot; you may have a problem with the object model that needs some refactoring.

Related

any work around to allow for an action result to accept a Abstract class as parameter

I have different configurations all inheriting from a base configuration that are customized in forms. I want all of these to be handled by a single action result.
[HttpPost]
public IActionResult Register(AbstractBaseConfig config)
{
...do some logic...
return View("../Home/Index");
}
However, this is not possible because you cannot base in abstract classes as a parameter to an action result. Is there any work around for this so I don't need a seperate action result for each configuration? (I still want each configuration to be it's own class, I only need access to the base class methods in the action result logic).
Basically you can't, and the reason is that MVC will try to do new AbstractBaseConfig() as part of the Data Binding process (which parses the URL or the Form Post and puts the results in a concrete object). And by definition, doing new AbstractBaseConfig() is impossible for an abstract class.
It also makes sense for other reasons, I will explain why.
You seem to expect that MVC can determine the class from the parameters that are being passed in. That is not how it works, in fact the opposite is true: the Action Method has to specify the exact class, and then the Binder will instantiate that exact class and try to bind its properties.
Suppose you had this:
public abstract class Thing { public int ID { get;set; } }
public class NamedThing : Thing { public string Name { get;set; } }
public class OtherThing : Thing { public string Name { get;set; } }
and suppose it would be allowed to use:
public IActionResult Register(Thing thing)
then what would you expect to be in thing after Data Binding: a Thing object with only the ID set? Or one of the other object types, with Name set, but how would MVC ever be able to know which class you meant?
So for all these reasons, this is not possible.
You could have a base class inherit the abstract class and all your classes inherit from that base class whilst having that base class as your parameter
Take for example
public abstract class ABase
{
public void stuff()
{
var stuff = string.Empty;
stuff = "hello";
}
public virtual void otherstuff()
{
var stuff = string.Empty;
stuff = "hello";
}
}
public class Base : ABase
{
//empty
}
public class Derived : Base
{
public void mystuff()
{
this.stuff();
}
public override void otherstuff()
{
// Custom code
}
}
public ActionResult Register(Base config)
{
}

Override Object.toString Error

Why does this produce an error in Flash Builder?:
package {
public class Foo {
override public function toString():String {
return "Foo";
}
}
}
Tab completion suggests that this is available for override...
Error message:
Multiple markers at this line:
-public
-1020: Method marked override must override another method.
-overridesObject.toString
Remove override on the toString() method.
There is a popular misconception among about the toString() method, namely: if one wants to provide a custom implementation of a super class method, the override keyword is needed. But in case of Object, toString() is dynamic and is attached at runtime, negating the need for overriding. Instead, the implementation is to be provided by the developer so one is not created at runtime. One just needs to write their own toString():String implementation.
Foo is not extending a class; so therefore there are no methods to override. Just remove the override keyword from the function definition and it should compile
package {
public class Foo {
public function toString():String {
return "Foo";
}
}
}
I'll add that toString() is a method of the Object class which many ActionScript classes extend from. But, even if you extend Object, you don't need to override the toString() method. From the docs:
To redefine this method in a subclass of Object, do not use the
override keyword.
Like this:
package {
public class Foo extends Object {
public function toString():String {
return "Foo";
}
}
}

How to mock a Generic Abstract class

Assuming I have an Interface IReportBuilderService and concrete class ReportBuilderService
e.g. public class ReportBuilderService : IReportBuilderService { }
I can start to mock this service with Moq as such
Mock<IReportBuilderService> _reportBuilderServiceMock = new Mock<IReportBuilderService>();
And mock expectations etc on the mock class, ok no problems.
Question: How do I mock the following method signature?
public abstract class ReportBuilder<TReport> where TReport : Report, new()
where a TReport is defined as
public class SomeReport : ReportBuilder<Report>, IMapper{}
And Report class is simply
public class Report { }
In the abstract class ReportBuilder there are a series of Property Get/ Sets, it is the value of these that I’m trying to fake/mock.
But I can’t begin to get the correct mock on this abstract class to start with
Hope this makes sense
Given that your abstract class looks like this:
public abstract class ReportBuilder<TReport> where TReport : Report, new()
{
public abstract Int32 SomeThing { get; set; }
}
there's no problem in mocking it at all:
var m = new Mock<ReportBuilder<Report>>();
m.SetupProperty(r => r.SomeThing, 19);
but note that all your properties have to be virtual or abstract.
So if this is not the case (and you can't or don't want to change this), you could either extract an interface from your base class and use this (if you're willing to change your code accordingly), or simply create a stub/mock by subclassing:
public class StubReportBuilder : ReportBuilder<Report>
{
public override Int32 SomeThing { get { return 42; } set { } }
}

Difference Between Static or NoneStatic Methods in ASP.NET MVC

I need a method that return me some parameters in controllers this is implementation of it:
public List<Parameter> GetParameters(FormCollection collection) {
List<Parameter> parameters = new List<Parameter>();
List<string> parameterNames = new List<string>();
//Get Parameters Names and Values
return parameters;
}
I use this method in all of controllers, So I think about 3 option that I have to define it:
1-For any controller class define it in that controller like this:
public class ProductController : Controller {
public List<Parameter> GetParameters(FormCollection collection) {
//
}
}
2-Define it in static class as static method:
public static class GeneralMethods {
public static List<Parameter> GetParameters(FormCollection collection) {
//
}
}
3-Define it as a None Static :
public class GeneralMethods {
public List<Parameter> GetParameters(FormCollection collection) {
//
}
}
which one is better? which one have better performance? or any other option for define methods that used in many controllers?
what is your suggestion?
There will be no performance impact in any of the three. (Though last approach will create separate object each time,it will be gracefully handled by GC).
approach 1: NO, as a standard practice we should not duplicate the code.
approach 2: YES, if your method depends only on the input parameter.
approach 3: YES, if you need to set up some instance variable and your method depends on them.
suggested approach: (approach 1+ approach 3)
If this method is common to all of your controller (or most), declare a base controller with this method and inherit all other controller from it.
Static methods will not be a problem as any variable declared with in a method are with in scope of the method.

C# - Override <T> method signature with ClassName?

Is there a way to override an abstract class's method signature which uses <T> with a ClassName so I can pass an object by reference without recasting it?
For example, I have a bunch of Object Managers. I want them all to contain a .Save(Object) method which will perform the appropriate save action based on the object state (Insert, Update, Delete, etc).
I was trying to create a base class which contains these methods:
protected virtual bool Update<T>(ref T _object) where T : ObjectBase
{
throw new NotImplementedException();
}
public virtual bool Save<T>(ref T _object) where T : ObjectBase
{
// Figure out which action to take based on _object's state and execute it
}
And I wanted my inherited classes to define the methods using something like this:
public override bool Update<Consumer>(ref Consumer _object)
{
return _service.UpdateConsumer(ref _object);
}
My problem is that I can't specify that <T> will now be <Consumer>, and by keeping it at <T> I can't pass it by ref
Instead of making the methods themselves generic, you should make the entire base class generic.
For example:
public abstract class ObjectManager<T> where T : ObjectBase {
protected abstract bool Update(T obj);
}
Each concrete ObjectManager should inherit ObjectManager of the type that it manages, like this:
public class ConsumerManager : ObjectManager<Consumer> {
protected override bool Update(Consumer obj) {
...
}
}
Note, by the way, that your parameters should almost definitely not be passed ref.
You only need to ref keyword if you want to change the caller's variable to refer to a different instance.
For more information, see here.

Resources