I am trying to abstract the methods and field from two concrete classes. I am not sure about the field in the abstract class..
Will SearchFactory and WorkFactory be accessing the same products field if I try to make them Singleton objects? But if I create new instances of the concrete factories, the products is a new isolated field for different instances right?
SlashCommand
interface SlashCommand {
}
SlashCommandFactory
abstract class SlashCommandFactory {
protected HashMap<String, SlashCommand> products
SlashCommand getProduct( String key ) {
products.key
}
void registerProduct( String key, String value ) {
products << [ key: value ]
}
}
SearchFactory
class SearchFactory extends SlashCommandFactory {
}
WorkFactory
class WorkFactory extends SlashCommandFactory {
}
Your products Map is static, which means that it will be the same objects across all instances of the class. It belongs to the class, not to the object.
You won't be able to access the field if you set its access modifier to private. Change it to protected to directly access it from subclasses.
Related
I have two questions:
I have a Singleton class with a property Layout that I use in creating child objects of an abstract class (example below). The abstract class has an abstract method where the layout file is given as a variable. Do I connect that Singleton class to the abstract class or each child? The following example is written using pseudo-code:
public class SingletonClass
{
public static Instance;
public var[,] Layout;
}
public abstract class AbstractClass
{
public abstract void DoSomething(var[,] Layout);
}
public class ClassA : AbstractClass
{
public override void DoSomething(var[,] Layout) { some code }
}
public class ClassB : AbstractClass
{
public override void DoSomething(var[,] Layout) { some other code }
}
Is it even needed, or "cleaner", to give the Layout as variable in the method, or is it ok to just call Layout from the singleton class?
The following UML is an equivalent of your code
under the following assumptions: Instance and Layout are assumed to be attributes of analogous classes.
SingletonClass has two owned attributes (denoted by the big dots): public layout of type Layout and instance of type AbstractClass (it's abstract, hence the italics). The latter will later hold either an instance of the concrete ClassA or ClassB.
Whether or not the design is ok depends. Basically there's nothing wrong with this.
I know that it is possible to base class variable holding derived class object. Like below....
class Animal
{
public void printName()
{
System.out.println("Print your name");
}
}
public class Tiger extend Animal
{
public void Print()
{
System.out.println("My Name");
}
public void static main(String args[])
{
Animal type1 = new Tiger();
//with this new created type1 varibale. I can only access members of Animal class.
type1.PrintName() // valid
type1.Print() //In-valid
}
}
So what is the usefulness of this? Still I don't see any benefit. Can someone explain me, may be I am missing something. Thanks.
In this case, where the variable is initialized from a child class variable, it isn't terribly useful. The usefulness comes in two cases:
When you have a function parameter with a base class type and you pass in a child class object as the actual argument.
void CareForAnimal(Animal anm) {
anm.Feed();
anm.Sleep();
}
While it's technically possible to allow you to do things with formal parameters you can't do with regular variables, as a language designer it's a lot of complication to make them different for not a lot of benefit.
When you have a base class variable initialized from the result of a method which is itself virtual:
Animal Breed(Animal father, Animal mother) {
Animal child = mother.mater(father);
child.Bathe();
child.Nurse(mother);
return child;
}
Now, you don't know right away which child class child is being initialized with.
I have a problem with Jackson mixin and inheritance. I have two target classes, a parent and a child. For those two target classes I have defined two MixIn classes (interfaces) with no inheritance relationship with each other. I also tested with one MixIn interface extending the other but there was no difference in the outcome. When Jackson serializes the parent class it uses the correctly defined mixin for the serialization config and everything works well. However when Jackson serializes the child class it will use the parent class mixin definitions for serializing properties that exist in both the parent and the child class. Then it uses the child class mixin definitions for serializing the properties defined in the child class but not in the parent class. Now this probably has something to do with comparing the base classes or implementing interfaces in Jackson.
Now the question is that is there any way that I could instruct Jackson to use only the mixin definitions for the child class when serializing objects of the child class? And yes I would like to keep both the the mixin definitions in place for two separate use cases so just removing the parent class mixin mapping is not gonna solve my issue.
Example code and expected and actual output JSONs below.
Environment:
Jackson version 2.1.4
Tomcat version 7.0.34.0
Target classes and interfaces they implement:
public interface TestI {
public String getName();
}
public interface TestExtendI extends TestI {
public Integer getAge();
}
public class Test implements TestI {
String name;
public Test(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
public class TestExtend extends Test implements TestExtendI {
private Integer age;
public TestExtend(String name) {
super(name);
}
public TestExtend(String name, Integer age) {
super(name);
this.age = age;
}
#Override
public Integer getAge() {
return age;
}
}
Mixins definitions
public interface TestMixIn {
#JsonProperty("base-name")
public String getName();
}
public interface TestExtendMixIn {
#JsonProperty("ext-name")
public String getName();
#JsonProperty("ext-age")
public Integer getAge();
}
If both mixins are added to the mapper the output JSON is:
{
"base-name": "5", // from parent class mixin definition
"ext-age": 50 // from child class mixin defition
}
With mixin for TestI.class commented everything works as expected and the output JSON is (this is what I would like to achieve):
{
"ext-name": "5", // from child class mixin defition
"ext-age": 50 // from child class mixin defition
}
Object mapper configuration
#Provider
#Produces(MediaType.APPLICATION_JSON)
public class JacksonObjectMapper implements ContextResolver<ObjectMapper> {
private ObjectMapper mapper;
public JacksonObjectMapper() {
mapper = new ObjectMapper();
mapper.addMixInAnnotations(TestI.class, TestMixIn.class);
mapper.addMixInAnnotations(TestExtendI.class, TestExtendMixIn.class);
}
public ObjectMapper getContext(Class<?> type) {
return this.mapper;
}
}
REST api for handling the request/response
#Path("api/test/{id}")
public class TestRestApi {
#GET
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public TestI getTest(#PathParam("id") String id) {
TestI ret = new TestExtend(id, 50);
return ret;
}
}
Solution
As described by pgelinas in the first response the solution to this problem is to define the methods that should be handled by the 'child' mixin again in the child interface. For the example code above that would mean changes to the TestExtendI interface:
public interface TestExtendI extends TestI {
public Integer getAge();
// override the method from the parent interface here
#Override
public String getName();
}
This will solve the issue and doesn't add too much boilerplate code to the solution. Moreover it will not change the interface contracts since the child interface already extends the parent interface.
This is a tricky one; the answer to your specific question is no, you cannot tell a child class to not use the Mixin applied to a parent class.
However, a simple solution to your problem here is to re-declare the getName() method in the TestExtendI interface. I believe MixIn annotation resolution doesn't follow the usual parent-child override (as is the case with normal annotations), but will instead prefer the MixIn that is applied to the class that declares the method. This might be a bug in Jackson or a design choice, you can always fill an issue on github.
I have two classes
public class ClassOne {
public Guid Id { get; set; }
}
public class ClassTwo : ClassOne {
}
When I send an instance of ClassTwo to Redis (using ServiceStack via its TypeSerializer) the superclass properties (e.g. Id) does not Serialize because it's on the parent class.
Is there a way to get this working?
Only abstract classes, interfaces or late-bound objects emit the necessary __type info required for inheritance to work. So if you must use inheritance (which is a bad idea in DTOs) change ClassOne to abstract.
Suppose the following (slightly pseudo-code for brevity):
class Basic
{
String foo;
}
class SomeExtension extends Basic
{
String bar;
}
class OtherExtension extends Basic
{
String baz;
}
class BasicService
{
Basic getBasic()
{
}
}
class SomeExtensionService extends BasicService
{
SomeExtension getSomeExtension()
{
}
}
class OtherExtensionService extends BasicService
{
OtherExtension getOtherExtension()
{
}
}
What would be the most idiomatic, elegant way to implement the get-() service methods with the most possible code reuse?
Obviously you could do it like this:
class BasicService
{
Basic getBasic()
{
Basic basic = new Basic();
basic.setFoo("some kind of foo");
return basic;
}
}
class SomeExtensionService
{
SomeExtension getSomeExtension()
{
SomeExtension someExtension = new SomeExtension;
Basic basic = getBasic();
someExtension.setFoo(basic.getFoo());
someExtension.setBar("some kind of bar");
return someExtension;
}
}
But this would be ugly if Basic has a lot of properties, and also you only need one object, as SomeExtension already inherits Basic. However, BasicService can obviously not return a SomeExtension object.
You could also have the get methods not create the object themselves, but create it at the outermost level and pass it to the method for filling in the properties, but I find that too imperative.
(Please let me know if the question is confusingly formulated.)
EDIT: Okay, so it was. I'll try to explain it better. Say you have two model classes, A and B. You also have two classes for returning objects of class A and B (from a database for instance, with information scattered all over so any ORM doesn't apply). Now, say A and B contains a lot of overlapping information, so it makes sense to refactor into a superclass C and let A and B extend from it. However, the service classes are still particular to A and B and need to duplicate the code for reading the overlapping information. How could you refactor these into a service class C?
I would add constructor to A and B which accepts C and sets the fields accordingly. The advantage over your suggested solution is that your ExtensionServices don't have to know about basic fields.
It looks like you're setting default values to your Basic (and children) objects. It's probably best to do that in their constructors.
public class Basic
{
protected String foo;
// and other properties
public Basic()
{
foo = "some kind of foo";
// assign defaults to all other properties
}
}
public class SomeExtension extends Basic
{
protected string bar;
public SomeExtension()
{
super(); // set the default properties of the base class
bar = "some kind of bar";
}
}
Remember to call super() in the child constructors so that the inherited properties will also be assigned default values.
public class BasicService
{
public Basic getBasic()
{
return new Basic();
}
}
public class ExtensionService extends BasicService
{
#Override
public Basic getBasic()
{
return new SomeExtension();
}
}
At least with this structure, you eliminate having to instantiate two objects in ExtensionService, and you actually don't set default values in the service classes. Since SomeExtension is a child of Basic, you can return a SomeExtension at the end of a function whose declared return type is Basic.