I'm trying to apply the decorator pattern to making an object that encrypts a word into a certain encryption, like the L337 method, which replaces letters like 9 with g, or 4 with r. Basically, I want to type a word into an inputfield and show the encrypted word in a text object. But I can't get the L337 decorator to inherit from the main decorator class. It won't accept the keyword 'super', so I tried the base word, but then when I implement Encrypt, it won't take the object newEncryption. Could someone help me figure out how to put this pattern together please?
I basically know what the decorator pattern is. It's making an object, making a basic decorator, and making a specific decorator, and instantiating the object with the decorating for exclusive methods and features.
public class Encryption : MonoBehaviour
{
public static InputField inputBox;
public static Text outputText;
public interface IEncryption { void Encrypt(); }
public class TextEncryption : IEncryption
{
public void Encrypt()
{
string currentText = inputBox.text;
outputText.text = currentText;
}
}
public abstract class encryptionDecorator : IEncryption
{
protected IEncryption tempEncryption;
public encryptionDecorator(IEncryption newEncryption)
{
tempEncryption = newEncryption;
}
public void Encrypt()
{
tempEncryption.Encrypt();
}
}
public class L337EncryptionDecorator : encryptionDecorator
{
public L337EncryptionDecorator(IEncryption newEncryption) : base(newEncryption)
{
print("Encrypting L337 Code");
}
public void Encrypt()
{
}
}
}
I think you actually want to use tempEncryption, but you didnt really tell where you could not use newEncryption so im guessing.
But anyway, I hope this will clear some things up. Its slightly edited from your code so I didnt need to put GUI stuff, but you could just CnP it to unity.
using UnityEngine;
public class Encryption : MonoBehaviour {
public interface IEncryption {
void Encrypt();
}
public class TextEncryption : IEncryption {
public void Encrypt() {
}
}
public abstract class EncryptionDecorator : IEncryption {
protected IEncryption tempEncryption;
public EncryptionDecorator(IEncryption newEncryption) {
//this will be called when you override the constructor
Debug.Log("In EncryptionDecorator constructor: " + newEncryption.GetType());
tempEncryption = newEncryption;
}
//if you are going to override a method in a child class,
//declare it either abstract ("no body; passes implementation to child") or
//virtual ("allows for a base implementation")
public virtual void Encrypt() {
Debug.Log("In EncryptionDecorator.Encrypt(): " + tempEncryption.GetType());
tempEncryption.Encrypt();
}
}
public class L337EncryptionDecorator : EncryptionDecorator {
public L337EncryptionDecorator(IEncryption newEncryption) : base(newEncryption) {
//newEncryption is a parameter, think of it as sort of a local variable.
//but since you pass it down to the parent class, it gets assigned to tempEncryption
//the base-class constructor is called first!
Debug.Log("In L337EncryptionDecorator constructor: " + newEncryption.GetType());
}
//this overrides the base implementation. you can call it with
//base.Encrypt() though.
public override void Encrypt() {
//you have no parameters here, but you could use the inherited variable tempEncryption because you declared it protected
Debug.Log("In L337EncrytionDecorator.Encrypt(): " + tempEncryption.GetType());
//base refers to the base class
base.Encrypt();
}
}
void Start() {
IEncryption encryption = new L337EncryptionDecorator(new TextEncryption());
encryption.Encrypt();
}
}
or maybe i missed what this is all about?!
Related
If I have something like
public class OwnerClass1{
public class OwnedClass{
// definition 1
}
}
public class OwnerClass2{
public class OwnedClass{
// definition 2
}
}
From a function that is implemented as below:
public <OwnedClass> boolean doStuff(OwnedClass example) {
System.out.println(example.<???>);
// example.getClass() returns "OwnerClass1$OwnedClass" etc here, so I guess getting this to string and trimming after $ would be one solution
// example.getSuperClass() returns "java.lang.Object" here, so not what I need
}
How can I get the behavior as below:
doStuff(new OwnerClass1.OwnedClass());
// OwnerClass1
doStuff(new OwnerClass2.OwnedClass());
// OwnerClass2
Note: Code above is meant to give a rough idea of the structure, not to be compiled out of box.
I understand that you want your unique doStuff method to act differently depending of the class on the actual class of the parameter you pass to it.
For this to be possible, OwnedClass1 and OwnedClass2 have to extend a common class or interface (that I guess you call OwnedClass). Otherwise your doStuffwill have to take an Object as param.
Then you can use instanceofto differenciate the classes.
Example with Object :
public boolean doStuff(Object example) {
if (example instanceof OwnedClass1) {
System.out.println("this is a class 1!");
} else if (example instanceof OwnedClass2) {
System.out.println("this is a class 2!");
} else {
throw new RuntimeException("Not supported : " + example.getClass());
}
}
And if you are only interested in the short name of the class, then you could go like that :
public boolean doStuff(Object example) {
System.out.println("this is a " + example.getClass().getName());
}
or even
public boolean doStuff(Object example) {
System.out.println("this is a " + example.getClass().getName().replaceAll(".*\\.", ""));
}
HTH!
The OwnedClass doesn't extend the OwnerClass1, it only extends the Object class. Most likely you are looking for getEnclosingClass() method instead of getSuperClass().
public boolean doStuff(Object example) {
System.out.println(example.getClass().getEnclosingClass());
}
Both OwnedClass sub classes could inherit from another class, that you pass to doStuff.
public class OwnerClass1 {
public class OwnedClass extends SuperOwnedClass {
// definition 1
}
}
public class OwnerClass2 {
public class OwnedClass extends SuperOwnedClass {
// definition 2
}
}
public class SuperOwnedClass {
}
public boolean doStuff(SuperOwnedClass example) {
System.out.println(example.<???>);
}
Or even better, let em implement interfaces.
I have two classes and one interface.
Interface:
public interface MyBirthdayEvent {
void itsMyBirthday();
}
First class:
public class MyBirthdayButton
{
public void addOnClickedListener(MyBirthdayEvent mbe){}
}
Second class:
public class MyBirthday {
private MyBirthdayButton myBirthdayButton = new MyBirthdayButton();
MyBirthday() {
myBirthdayButton.addOnClickedListener(new MyBirthdayEvent() {
public void itsMyBirthday() {
System.out.println("Happy Birthday");
}
});
}
}
Then in main, I have this:
public class TestThisStuff {
public static void main(String[] args) {
MyBirthday myBirthday = new MyBirthday();
}
}
As can be seen from the code, I am using an anonymous class in the MyBirthday constructor. In doing so, I am trying to get the string "Happy Birthday" to print to the console.
My problem is, when I call the MyBirthday constructor in main by making a new myBirthday object, I am not seeing the string "Happy Birthday" print to the console. Shouldn't it print to the console? If not, what I am doing wrong?
What you can do is this:
public interface MyBirthdayEvent {
void itsMyBirthday();
default void invoke() {
itsMyBirthday();
}
}
...
public class MyBirthdayButton
{
public void addOnClickedListener(MyBirthdayEvent mbe){
mbe.invoke();
}
}
...
Also, it will work without it, but use a lambda rather than an anonymous inner class. This looks much better.
MyBirthday() {
myBirthdayButton.addOnClickedListener(() ->
System.out.println("Happy Birthday"));
}
you can move System.out.println("some words")statement to your MyBirthdayEventconstructor
it didn't show in your console because you haven't invoke the method
Is there a way to always execute a function before any other function of a class is called?
I have a class where I need to refresh some fields always before any function is called:
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
Because it seems to be bad programming, I don't want to call refresh at the beginning of every other function. Since other persons are going to work on this project as well, there would be the danger, that somebody extends the calls and doesn't call refresh.
JUnit has a solution for this with the #Before-Annotation. Is there a way to do this in other classes as well?
And by the way: If you know a programming pattern wich solves this problem in another way than executing a function everytime any function is called, that would be very helpful, too!
Use a dynamic proxy in which you can filter to those methods before which your specific "before" method should be called. And call it in those cases before dispatching the call. Please see the answer from How do I intercept a method invocation with standard java features (no AspectJ etc)?
UPDATE:
An interface is needed to be separated for the proxy. The refresh() method cannot remain private. It must be public and part of the interface (which is not nice here) to be able to be called from the proxy.
package CallBefore;
public interface ExampleInterface {
void function1();
void function2();
void otherFunction();
void refresh();
}
Your class implements that interface:
package CallBefore;
public class Example implements ExampleInterface {
#Override
public void function1() {
System.out.println("function1() has been called");
}
#Override
public void function2() {
System.out.println("function2() has been called");
}
#Override
public void otherFunction() {
System.out.println("otherFunction() has been called");
}
#Override
public void refresh() {
System.out.println("refresh() has been called");
}
}
The proxy which does the trick. It filters the needed methods and calls refresh().
package CallBefore;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ExampleProxy implements InvocationHandler {
private ExampleInterface obj;
public static ExampleInterface newInstance(ExampleInterface obj) {
return (ExampleInterface) java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new ExampleProxy(obj));
}
private ExampleProxy(ExampleInterface obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try {
if (m.getName().startsWith("function")) {
obj.refresh();
}
result = m.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
The usage:
package CallBefore;
public class Main {
public static void main(String[] args) {
ExampleInterface proxy = ExampleProxy.newInstance(new Example());
proxy.function1();
proxy.function2();
proxy.otherFunction();
proxy.refresh();
}
}
Output:
refresh() has been called
function1() has been called
refresh() has been called
function2() has been called
otherFunction() has been called
refresh() has been called
This may not solve your exact problem but at least could be a starting point if you are allowed considering a re-design. Below is a simple implementation but with some small touches I believe you can achieve a more elegant solution. BTW, this is called Dynamic Proxy Pattern.
First thing you need is an interface for your class.
public interface Interface {
void hello(String name);
void bye(String name);
}
public class Implementation implements Interface {
#Override
public void hello(String name) {
System.out.println("Hello " + name);
}
#Override
public void bye(String name) {
System.out.println("Bye " + name);
}
}
Then java.lang.reflect.Proxy class comes to help. This class is able to create an instance for a given interface at runtime. It also accepts an InvocationHandler which helps you to capture method calls and looks like this.
public class InvocationHandlerImpl implements InvocationHandler {
private final Object instance;
public InvocationHandlerImpl(Object instance) {
this.instance = instance;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
try {
System.out.println("Before");
result = method.invoke(instance, args);
System.out.println("After");
} catch (Exception e){
e.printStackTrace();
throw e;
} finally {
System.out.println("finally");
}
return result;
}
}
After all your client code will look like this.
Interface instance = new Implementation();
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[] { Interface.class },
new InvocationHandlerImpl(instance));
proxy.hello("Mehmet");
proxy.bye("Mehmet");
Output for this code is
Before
Hello Mehmet
After
finally
Before
Bye Mehmet
After
finally
I would define getters for every field and do the refreshment inside the getter. If you want to avoid unrefreshed access to your private fields at all, put them in a superclass (together with the getters which call refresh).
Depending on your project structure, it may be also sensible to introduce a separate class for all data that is regularly refreshed. It can offer getters and avoid that anyone accesses the non-refreshed fields.
Not in Java SE, but if you are using Java EE, you could use interceptors.
For standalone applications, you could consider using a bytecode manipulation framework, like javassist.
You can have a protected getter method for data. Access getData method instead of using data field. Child classes will see only getData and will have updated data every time.
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
protected int getData(){
refresh();
return data;
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
It is better to write another method which will be made protected(accessible to the child classes) which will call first the refresh method and then call the function.
This way the data would be refreshed before the function is called everytime(As per your requirement).
eg:
protected void callFunction1(){
refresh();
function();
}
Thanks,
Rajesh
You should use Decorator in this case. Decorator is a good choice for something like interceptor. Example here: https://msdn.microsoft.com/en-us/library/dn178467(v=pandp.30).aspx
I'm new to Java and is trying to learn the concept of inner class. I saw the code below from Java tutorial Oracle. My question is, for
String name = "world";
#Override
public void greet() {
greetSomeone("world");
}
Can greetSomeone("world") be replaced by greetSomeone(name). The reason why I'm asking this question is because I have noticed if greetSomeone("world") is indeed replaced by greetSomeone(name), inside the public void greetSomeone() method, the passed "name" argument will be set to itself. I was just wondering if there are side effect to code like this?
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
class EnglishGreeting implements HelloWorld {
String name = "world";
#Override
public void greet() {
greetSomeone("world");
}
#Override
public void greetSomeone(String someone) {
name = someone;
System.out.println("hello " + name);
}
}
HelloWorld eg1 = new EnglishGreeting();
eg1.greet();
}
public static void main(String[] args) {
HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
First of all why is that #Override annotation there?
You will use Override when you want to change the behaviour of the parent's methods. Your parent's methods have no behaviour as it is an interface. As a further note I guess that it will teach you that the signature of an overriden method must always match the one from the parent.
Secondly the design is kind of dodgy. It can be simplified.
Thirdly yes you can refer to the String object name as it is defined in that class and you can access the object's primitive just by calling 'name'. Why will you not get the reference printed when System.out? Because the String object handles that for you ensuring the toString will show you the primitive. When you do System.out.print(myObject); The console will show you the Object default or the overriden toString method.
So if you create an object and you do System.out.print(myObject) you will see the reference. If you override toString returning "test" you will see test.
Technically, name can be passed and name = name; is valid Java.
However, this is a horrible design and was probably used for demonstrative purposes only. Don't do this.
In Java, is it possible to override member data in a subclass and have that overridden version be the data used in a super class's implementation?
In other words, here's what I am trying to get to happen, and it's not happening:
abstract public class BasicStuff {
protected String[] stuff = { "Pizza", "Shoes" };
public void readStuff() {
for(String p : stuff) {
system.out.println(p);
}
}
}
..
public class HardStuff extends BasicStuff {
protected String[] stuff = { "Harmonica", "Saxophone", "Particle Accelerator" };
}
This invocation:
HardStuff sf = new HardStuff();
sf.readStuff();
... prints Pizza and Shoes. I want it to print the latter instead.
I recognise that this is rather poor hierarchical OO practice; I needed it for a very specific case as I am doing something with XML configuration and reflection.
Is there a modifier that can make this happen?
And yes, I do recognise that there are wrappers one can use to get around this problem in my subclass, i.e. by indicating that the contents of stuff[] are now stored in an array with a different name, for instance. I'm just trying to keep this simple, and am curious in principle.
Thanks a lot in advance!
I believe you must interpose an accessor method, i.e., use:
for(String p : getStuff()) {
in the superclass, and add:
protected String[] getStuff() { return stuff; }
wherever you have a protected String[] stuff redefinition.
Overriding really applies to methods, not data (at least, that is so in the Java model; some other languages do things differently), and so to get the override effect you must interpose a method (typically a dirt-simple accessor, like here). It doesn't really complicate things at all, it's just a very simple way to instruct the Java compiler to use, intrinsically, the "extra level of indirection" that your desired behavior requires.
This way you are hiding the parent variable stuff with the defined stuff.
Try giving value to stuff in the initialization block (or in the constructor):
abstract public class BasicStuff {
protected String[] stuff;
{
stuff = new String[] { "Pizza", "Shoes" };
}
public void readStuff() {
for(String p : stuff) {
System.out.println(p);
}
}
}
..
public class HardStuff extends BasicStuff {
{
stuff = new String[] { "Harmonica", "Saxophone", "Particle Accelerator" };
}
}
If you want to print the array of the String Stuff defined in derived class then you need to override the method readStuff in the class HardStuff by redefining the method in the class HardStuff. As the method readStuff was defined in the abstract class BasicStuff, hence it would only print the members of the class BasicStuff. Hence, add the same method in the derieved class too.
Below you can find the complete code..
class BasicStuff {
protected String[] stuff = { "Pizza", "Shoes" };
public void readStuff() {
for(String p : stuff) {
System.out.println(p);
}
}
}
public class HardStuff extends BasicStuff {
protected String[] stuff =
{ "Harmonica",
"Saxophone",
"Particle Accelerator"
};
public void readStuff() {
for(String p : stuff) {
System.out.println(p);
}
}
public static void main(String []arg)
{
HardStuff sf = new HardStuff();
sf.readStuff();
}
}