Looking for a pattern to solve double-sided dependency

Hi,
i'm facing a problem in which i have the following code:
public class A {
       public B createB(Class<? extends B> kindOfB, String information1, int information2, Object information3, int information4) {
              if (kindOfB.equals(B1.class)
                 return new B1(information1);
              if (kindOfB.equals(B2.class)
                 return new B2(information2);
              if (kindOfB.equals(B3.class)
                 return new B3(information3, information4);
              throw UnsupportedKindOfBException();
public class B {}
public class B1 extends B {
       public B1(String information1) {}
public class B2 extends B {
       public B2(int information2) {}
public class B3 extends B {
       public B2(Object information3, int information4) {}
}I'm looking for a way to convert this dirty code into something nice, anyone thinking of a pattern that could help me to do that? or maybe reflection could save me?
Thanks a lot

I was thinking about the abstract factory pattern, the class A is a factory for objects of type B.
But then I saw that each subclass of B is created with different types of objects.
If this is really what you want, my guess is that you first should put all these arguments in a separate class:
     public class Data {
          private String information1;
          private int information2;
          private Object information3;
          private int information4;
          // Omitted constructors and getters/setters
     }Then there are several ways you could proceed.
One way would be to throw away class A and simply create constructors in each Bi class which takes a Data object:
     public class B {}
     public class B1 extends B {
            public B1(Data data) {
                 this.information = data.getInformation1();
     public class B2 extends B {
            public B2(Data data) {
                 this.information = data.getInformation2();
     public class B3 extends B {
            public B2(Data data) {
                 this.information1 = data.getInformation3();
                 this.information2 = data.getInformation4();
     }The drawback of this is that each Bi gets coupled to the Data object of which it does not need everything.
So another way would be to keep Bi untouched and similar to what you had, but now replacing the parameters in A with the Data object:
     public class A {
            public B createB(Class<? extends B> kindOfB, Data data) {
                   if (kindOfB.equals(B1.class)
                      return new B1(data.getInformation1());
                   if (kindOfB.equals(B2.class)
                      return new B2(data.getInformation2());
                   if (kindOfB.equals(B3.class)
                      return new B3(data.getInformation3(), data.getInformation4());
                   throw UnsupportedKindOfBException();
     }Depending on your use case you can indeed refactor this to use the abstract factory pattern:
     public interface BFactory {
            B createB(Data data);
     public class B1Factory implements BFactory {
          public B createB(Data data) {
               return new B1(data.getInformation1());
     public class B2Factory implements BFactory {
          public B createB(Data data) {
               return new B2(data.getInformation2());
     public class B3Factory implements BFactory {
          public B createB(Data data) {
                return new B3(data.getInformation3(), data.getInformation4());
     }     This works particularly well if you have code that needs to create only one type of B at a time but it doesn't matter which type:
public class BStructureBuilder(BFactory bFactory) {
     createSomething(List<Data> datas) {
         someStructure.add(bFactory.createB(datas.get(i)));
}It has the added advantage that you can never request a B that doesn't exists because if class B4 comes along you would have to write a B4factory. Again depending on your usecase this can be a maintenance nightmare, so let me know if this helps and if it doesn't we could try to think of another pattern...

Similar Messages

  • Acrobat X Pro for Mac fails to scan double-sided

    Hello All,
    I am having trouble in scanning double-sided through Acrobat X Pro with a Canon MF4880dw installed on an iMac with Mountain Lion.
    Here is the procedure I follow:
    File > Create > PDF from scanner
    in the box "Sides", I select "Both Sides" and check the box for "Prompt for scanning more pages".
    When I scan the first side of a multi-page document, I am prompted to indicate whether the scan is complete or I want to scan more pages, but I am NOT prompted to indicate whether I want to scan the other side!
    Turning off the option "Prompt for scanning more pages" has the only result of completing the scanning procedure without asking anything else...
    I found the following note on the on-line help of Acrobat,
    http://help.adobe.com/en_US/acrobat/X/pro/using/WS58a04a822e3e50102bd615109794195ff-7f71.w .html
    Note: You can scan both sides of pages even on scanners that do not themselves support two-sided scanning. When Both Sides is selected, a dialog box appears after the first sides are scanned. You can then reverse the original paper documents in the tray, and select the Scan Reverse Side (Put Reverse Of Sheets) option in that dialog box. This method produces a PDF with all pages in the proper sequence.
    This is indeed what I have always done on a Windows 7 computer with Acrobat 8 and a Samsung multifucntion printer, and never ever had any problem.
    In fact, I believe that the printer model is irrelevant, as this is an internal setting of Acrobat, and that this is a bug in the Acrobat X Pro for Mac, which must be fixed.
    Does anyone else have the same problem?
    Thank you,
    Salvatore

    Dear Mamak,
    Many thanks for the note.
    I followed your advice and dowloaded new drivers for my Canon MF4880dw.
    The filename was different than yours, because the model was different.
    However, I noticed that this last version I downloaded is pretty new (released in April), so I was hoping it would fix the problem. Also, it was the same file for all versions of Mac OS X from 10.5 through 10.8.
    Unfortunately, no luck: Acrobat still does not ask me to scan the reverse side. Maybe I should have uninstalled the printer before reinstalling it?
    I more or less solved the problem by scanning double-sided documents on Acrobat 7 for Windows (which I also have installed on my Mac), which is not optimal, but at least works.
    Any thoughts?
    Thank you again,
    Salvatore

  • Looking for RT61 scripts? [Solved Maybe!]

    Following this in wiki....
    http://wiki.archlinux.org/index.php/RT61_Wireless
    looking for scripts?
    Anyone know where I can find them?
    Edit Just looking at wicd...will read install notes looks like what I need!

    My setup is very similar to tomk's - minimal Arch install, LTS kernel, managed over SSH. It used to be my compiling setup (until my more powerful laptop came along), but it does a mighty fine job as an MPD server (connected to my stereo), torrent server and NFS file server (for my HTPC). Also runs a small webserver (ruTorrent frontend) but the webserver is starting to be employed as an FTP replacement - so I can access my OpenWrt builds from the LAN, and as an Arch package repo.
    I back up like once a month over eS-ATA. 1 TB & 2 TB HD's in my server, identical ones in my eS-ATA disks. 2 GB of RAM, but I could probably make do with 512 - on i686, that is. I would take out what you don't need, 4 GB sounds like overkill for just about any server unless you're gonna virtualise and stuff, and you shave a few Watts off your idle usage.
    RAID is not a backup, the best backups are off-line and (ideally) off-site. My eS-ATA disks are in another room, so far for off-site .
    Last edited by .:B:. (2011-09-12 22:33:11)

  • Looking for a way to solve permission problem in windows 7

    one of the biggest problems i have with this windows that even that i'm an administrator and the owner of the computer i always have permission problems folders i get a no access errors with files and folders even thoughe i should have full permisions i belive system restore doesn't work for me because permissions problem and i don't know what to do anymore i'v used uac i'v disable uac i downloaded a registry file to take owernship on files and folders and still problems so what can i do to solve all this problems?
    and to be honest i really don't like the way windows 7 behave with permisions this is my computer and i am an administrator why do i have to fight to access folders like System Volume Information,Recovery,Documents and Settings why do i get the lock icon when i take owenership and i'm on the users list but when i add users everyting is fine?
    10x in advance.:)

    Hello,
    This is by design. You cannot access the folder or files are protected by operation system even if your current user account is Administrator.
    System Volume Information is a hidden and protected system folder that the System Restore tools uses to store it information and restore points.
    In Recovery folder, there are two files: Winre.wim and boot.sdi. With these two files, you are able to boot the system to Windows Recovery Environment (WinRE) and do a repair without inserting a Windows 7 installation disc.
    If you want to access the protected folders like “System Volume Information”, use the following method, but I do not recommend you do this. It may cause some potential problems:
    1. Right click the System Volume Information folder and choose Properties.
    2. In Security tab, click Edit and then click Add. Type in “everyone”(without quote) and click Ok.
    3. Then “Everyone“ will be listed under ” Group or user names”, click Everyone, and check “allow” full control option.
    As BurrWalnut said, the “Documents and Settings”, it is a junction. A junction point is also a protected operating system folder that points to another folder. The junction point is an important part of application compatibility and does not contain any data or other files. In Windows Vista and Windows 7, the “Documents and Settings” folder has been replaced with “Users” folder. All of your user profiles are saved in C:\Users\User name folder.
    Thomas Lin

  • Data binding in swing (looking for some pattern or advice)

    My primary window class looks something like this:
    public class PrimaryWindow extends JFrame {
       private final Controller controller;
       // GUI components definition code
       public PrimaryWindow () {
               // GUI components initialization code
               // GUI components controller installation code
       private class Controller implements XXX, XXX, XXX {
             public void propertyChange(PropertyChangeEvent event) {
                   if (OPEN_NEW_DIALOG.equals(event.getPropertyName())) {
                       SomeDialog dialog = new SomeDialog(/* Some data is sent to the dialog */);
                       dialog.setVisible(true);
    }The problem I have here seems to be a classic one, but i'm not sure how to solve it.
    When my controller receives OPEN_NEW_DIALOG event it sends some data into the dialog that is showed up the user. When user performs some actions I do not know what is the best way to send that data back to the controller.
    Yes there are millions of ways of doing this but i'm not sure which option is better, which one is more scalable and maintainable as well? In future I might have a dozen of dialogs and rather complex data structure they deal with, so what is the best way to bind GUI components with data model?

    Hi,
    Just to make it clear:
    We do not parse the XML on the event bean after the Coherence. We do it on the JMS adapter on multiple threads in order to utilize all the server resources (CPUs) and then we put it in the replicated cache.
    The requirements from our application are:
    - There is an aggregative query that needs to "see" all events (this means that we need to pass all events thru a single processor and we cannot partition them to several processors).
    - Because this is a HA solution the events on both CEPs (primary and secondary) needs to be at the same order when reaching the HA inbound adapter and the processor.
    - A single thread JMS adapter is not reading the messages from the JMS fast enough mainly because it takes time to parse the XML to an event.
    - Using a multi-threaded adapter or many single threaded adapters with message selector will create a situation that the order of events on both CEPs will not be the same at the processor inbound.
    This is why we needed a mediator so we can read in multiple threads that will parse the XMLs in parallel without concerning on order of messages and on the other hand publish all the messages on a single thread to the processors on both CEPs from this shared mediator (we use a replicated cache that runs on both JVMs).
    We use queue instead of topic because if we read the messages from a topic on both CEPs it will be stored twice on the Coherence replicated cache. But if we use a queue, when server 1 read the message and put it in the Coherence replicated cache then server 2 will not read it because it was removed from the queue.
    If I understand correctly you are suggesting replacing the JMS adapter with an event bean that will read the messages from the JMS directly?
    Are you also suggesting that we will not use a replicated cache but instead a stand alone cache on each server? In this case how do we keep the same order of events on both CEPs (on both caches)?

  • Print A4 as A5 (double sided)?

    Hi
    I've got a document with two A4 artboards, which I'm printing double sided on one sheet of paper. Could anyone tell me the easiest way to print it at A5 size, so I'll get two double sided copies per A4 pages?
    Thanks!

    Make a pdf and print this from Acrobat. Acrobat has an option to print multiple pages per sheet, under page scaling. I do this all the time for printing manuals and brand standard guides, so I can fit them in my binder with less pages.
    For the double sided I cannot answer as every print driver has that menu in a different location. First make sure your hardware is capable of printing double sided, so you dont spend time looking for somehting your printer cannto do. If you have a fiery look for page setup >>fiery options >> double sided or possibly buried somewhere else(pends on your fiery verison/PPD) buried in your print options.

  • Double-sided driver replacement for LaserWriter 8 ?

    Greetings.
    I use a nice G4 tower with OS 9.2 in a very PC environment.
    Our networked printer is a HP4600dn which does very nice double-sided copies using the PC Windows XP drivers.
    The default OS 9 driver according to HP is LaserWriter 8; it works just fine except for the lack of a double-sided option.
    Is there another driver which will stimuate double-sided function with my G4?
    Thanks for your time!

    Hi, Bruce. When you're using LaserWriter 8, features that are offered by some printers but not all are made accessible by putting the proper PostScript Printer Description (ppd) file in your System Folder>Extensions>Printer Descriptions folder and selecting that ppd when setting up the printer in the Chooser. Do you have the HP Color LaserJet 4600 ppd file properly located in that folder, and have you selected it? If not, you can download the current version of it and other software for the 4600 here.
    If you'd like to see whether your results are different using another printer driver instead of LaserWriter 8, download AdobePS 8.7, Adobe's own PostScript Level 2 and 3 printer driver, on which Apple's is based. You will still need the proper ppd file.

  • How can I use SQL to search for a pattern within a field?

    Hello, Frank, Solomon, ect
    I am now faced with this particular scenario, I've got the SQL to search through a field to find text within the field, but I have to know what it is before it can look for it.
    What I have to do is this:
    Search through a field, for a pattern, and I won't know what the data is I am looking for. Can this be done in SQL?
    For instance, Here is my SQL this far, I was helped allot in order to get to this point.
    select table_name,
           column_name,
           :search_string search_string,
           result
      from (select column_name,
                   table_name,
                   'ora:view("' || table_name || '")/ROW/' || column_name || '[ora:contains(text(),"%' || :search_string || '%") > 0]' str
              from cols
             where table_name in ('TABLE1', 'TABLE2')),
           xmltable (str columns result varchar2(10) path '.')
    When you execute the above SQL, you have to pass in a value. What I really need is to alter the above SQL, to make it search for a pattern that exist's within the text of the field itself.
    Like for instance, lets say the pattern I am looking for is this" xx-xxxxx-xxxx" and it's somewhere in a field.
    I need to alter this SQL to take this pattern and search through all the schemas and tables to look for this pattern match.
    Can be done?

    When you use something dynamically within a function or procedure, roles do not apply and privileges must be granted directly.  So, you need to grant select on dba_tab_cols directly.  If you want to do pattern matching then you should use regular expressions.  The following example grants the proper privileges and uses regexp_instr to find all values containing the pattern xxx-xxxx-xxxx, where /S is used for any non-space character.  I limited the tables in order to save time and output for the test, but you can eliminate that where clause.
    SYS@orcl> CREATE USER test IDENTIFIED BY test
      2  /
    User created.
    SYS@orcl> ALTER USER test QUOTA UNLIMITED ON USERS
      2  /
    User altered.
    SYS@orcl> GRANT CREATE SESSION, CREATE TABLE TO test
      2  /
    Grant succeeded.
    SYS@orcl> GRANT SELECT ON dba_tab_cols TO test
      2  /
    Grant succeeded.
    SYS@orcl> CONNECT test/test
    Connected.
    TEST@orcl> SET LINESIZE 90
    TEST@orcl> CREATE TABLE table1
      2    (tab1_col1  VARCHAR2(60))
      3  /
    Table created.
    TEST@orcl> INSERT ALL
      2  INTO table1 (tab1_col1) VALUES ('xxx-xxxx-xxxx')
      3  INTO table1 (tab1_col1) VALUES ('matching abc-defg-hijk data')
      4  INTO table1 (tab1_col1) VALUES ('other data')
      5  SELECT * FROM DUAL
      6  /
    3 rows created.
    TEST@orcl> CREATE TABLE table2
      2    (tab2_col2  VARCHAR2(30))
      3  /
    Table created.
    TEST@orcl> INSERT ALL
      2  INTO table2 (tab2_col2) VALUES ('this BCD-EFGH-IJKL too')
      3  INTO table2 (tab2_col2) VALUES ('something else')
      4  SELECT * FROM DUAL
      5  /
    2 rows created.
    TEST@orcl> VAR search_string VARCHAR2(24)
    TEST@orcl> EXEC :search_string := '\S\S\S-\S\S\S\S-\S\S\S\S'
    PL/SQL procedure successfully completed.
    TEST@orcl> COLUMN "Searchword"     FORMAT A24
    TEST@orcl> COLUMN "Table"     FORMAT A6
    TEST@orcl> COLUMN "Column/Value" FORMAT A50
    TEST@orcl> SELECT DISTINCT SUBSTR (:search_string, 1, 24) "Searchword",
      2               SUBSTR (table_name, 1, 14) "Table",
      3               SUBSTR (t.column_value.getstringval (), 1, 50) "Column/Value"
      4  FROM   dba_tab_cols,
      5          TABLE
      6            (XMLSEQUENCE
      7           (DBMS_XMLGEN.GETXMLTYPE
      8              ( 'SELECT ' || column_name ||
      9               ' FROM ' || table_name ||
    10               ' WHERE REGEXP_INSTR
    11                     (UPPER (' || column_name || '),''' ||
    12                  UPPER (:search_string) || ''') > 0'
    13              ).extract ('ROWSET/ROW/*'))) t
    14  WHERE  table_name IN ('TABLE1', 'TABLE2')
    15  ORDER  BY "Table"
    16  /
    Searchword               Table  Column/Value
    \S\S\S-\S\S\S\S-\S\S\S\S TABLE1 <TAB1_COL1>matching abc-defg-hijk data</TAB1_COL1>
    \S\S\S-\S\S\S\S-\S\S\S\S TABLE1 <TAB1_COL1>xxx-xxxx-xxxx</TAB1_COL1>
    \S\S\S-\S\S\S\S-\S\S\S\S TABLE2 <TAB2_COL2>this BCD-EFGH-IJKL too</TAB2_COL2>
    3 rows selected.

  • Help! double sided printing.

    Hi, i recently purchased my first macbook air (os x 10.9.2) and have loaded my printer on however can not find any options or buttons to print double sided or duplex printing in word (office for mac 2011). I know my Brother MFC-J6510DW CUPS does do the double sided printing as i used to always do it it on my previous laptop.

    I have an Epson double-sided printer, so what I'm about to suggest will hopefully apply.
    If, for example, I wanted to double-sided print from Safari, I would do File > Print from Safari's menu.  Then a box would pop up showing paper orientation, etc.  Toward the bottom is a clickable row that says "Safari".  Click that and choose "Output Settings".   That's where the two sided options appear.

  • Spinning Beach Ball Delay with "Look for Shared Photos" Checked

    We installed iLife '06 on our school computers - all 500 of them - this fall. It is version 6.0.4. However, upon launch, there is a long delay of about 2-4 minutes with a spinning beach ball that we've determined takes place because iphoto is looking for shared libraries. We have one shared library on the network at this time, but sometimes teachers turn on sharing, or have in the past.
    Last year, we were using iPhoto '04 and had no problems like this at all -shared libraries appeared immediately, just as quickly as shared libraries in itunes still do.
    Has anyone experienced this - is there a known issue? Or should I look for a network problem.

    Solved this problem myself. It was a dns issue. For some reason, when iphoto looks for shared photo's, it does a reverse lookup on the ip of any machine it finds that has sharing turned on. If there is no reverse lookup zone on your dns server running OS X then it locks up as it repeatedly sends the request. Simply creating a reverse zone for the ip address range of your clients makes the bug go away. Why it needs to do a reverse lookup is beyond me.

  • "Looking for printer...." problem

    Out of the blue, all of the machines in our office are now reporting "Looking for printer...." when users try to print to our network connected HP4200. The message is appearing in the printer app.
    The printer itself seems fine, and i can print to it from a windows machine. Restarting the printer has no effect on the problem.
    I've already tried the various solutions I've found in the forums here. Clearing the caches, deleting and reinstalling the printer driver, etc. works for a document or 2, but then the machine falls back into the looking for printer pattern again.
    This is happening on Tiger, Leopard, and Snow Leopard.

    This problem went away as mysteriously as it arrived. Sadly, today it is back again and the proposed fix didn't help any better than all the rest of the changes we've tried. The only thing that works is to delete and reinstall the printer. However that is only good for a print or 2 before we have to do it again.
    No changes have happened on the printers, the network or the macs to account for the problem coming and going.

  • Looking for a replacement battery charger/AC Adaptor Powerbook G4

    The model number is M8407. I can't find any items on Ebay whose charger works with this labtop.
    Can you tell me what I need to look for?

    hi
    first off all it depends on the size of your powerbook. (for battery) is it 17" or 15"
    you can have a llok for battery on http://www.bluescale.co.uk/categories/APPLE-Laptop-Batteries/
    for the charger is http://www.bluescale.co.uk/categories/Apple-Laptop-AC-Adapter-Charger/
    hope that helps

  • Looking for background videos

    Hello all
    I'm on the hunt for various background videos, I have found IStockPhoto and Getty Images, but I was wondering what other options I may have and, was hoping for a few recommendations, I'm not really looking for anything specific cause it really all depends on what project I'm working on at the time....
    Thanks

    Is joke, yes?
    Anyone know where I can find a red and white swirling, falling into the vortex,
    There are several presets and prebuilts within Motion and LiveType.
    kinda cartoony looking type
    You mean text? Can't imagine text doing what you're describing without many carefully applied filters. Since the text is customized by the user, no.
    background to key?
    You mean key in front of? Or you want to key out the background? Huge difference and we cannot possibly read your mind.
    bogiesan
    Message was edited by: David Bogie Chq-1

  • TS1453 there is no "look for apple tv's " in preferences in itunes

    Hi i cant connect my itunes and apple tv together , it doesnt come up in devices and when looking in preferences it does not show the tab to" look for apple tv's" can anyone help

    That depends on how you set it all up. If you chose the "connect to iTunes" option then you should be able to sync content to the hard drive on the Apple TV. If you chose the "add shared library" option then you can only stream to the Apple TV.

  • New(?) pattern looking for a good home

    Hi everyone, this is my second post to sun forums about this, I initially asked people for help with the decorator and strategy pattern on the general Java Programming forum not being aware that there was a specific section for design pattern related questions. Since then I refined my solution somewhat and was wondering if anyone here would take a look. Sorry about the length of my post, I know it's best to keep it brief but in this case it just seemed that a fully functional example was more important than keeping it short.
    So what I'd like to ask is whether any of you have seen this pattern before and if so, then what is it called. I'm also looking for some fresh eyes on this, this example I wrote seems to work but there are a lot of subtleties to the problem so any help figuring out if I went wrong anywhere is greatly appreciated. Please do tell me if you think this is an insane approach to the problem -- in short, might this pattern have a chance at finding a good home or should it be put down?
    The intent of the pattern I am giving below is to modify behavior of an object at runtime through composition. In effect, it is like strategy pattern, except that the effect is achieved by wrapping, and wrapping can be done multiple times so the effect is cumulative. Wrapper class is a subclass of the class whose instance is being wrapped, and the change of behavior is accomplished by overriding methods in the wrapper class. After wrapping, the object "mutates" and starts to behave as if it was an instance of the wrapper class.
    Here's the example:
    public class Test {
         public static void main(String[] args) {
              double[] data = { 1, 1, 1, 1 };
              ModifiableChannel ch1 = new ModifiableChannel();
              ch1.fill(data);
              // ch2 shifts ch1 down by 1
              ModifiableChannel ch2 = new DownShiftedChannel(ch1, 1);
              // ch3A shifts ch2 down by 1
              ModifiableChannel ch3A = new DownShiftedChannel(ch2, 1);
              // ch3B shifts ch2 up by 1, tests independence from ch3A
              ModifiableChannel ch3B = new UpShiftedChannel(ch2, 1);
              // ch4 shifts ch3A up by 1, data now looks same as ch2
              ModifiableChannel ch4 = new UpShiftedChannel(ch3A, 1);
              // print channels:
              System.out.println("ch1:");
              printChannel(ch1);
              System.out.println("ch2:");
              printChannel(ch2);
              System.out.println("ch3A:");
              printChannel(ch3A);
              System.out.println("ch3B:");
              printChannel(ch3B);
              System.out.println("ch4:");
              printChannel(ch4);
         public static void printChannel(Channel channel) {
              for(int i = 0; i < channel.size(); i++) {
                   System.out.println(channel.get(i) + "");
              // Note how channel's getAverage() method "sees"
              // the changes that each wrapper imposes on top
              // of the original object.
              System.out.println("avg=" + channel.getAverage());
    * A Channel is a simple container for data that can
    * find its average. Think audio channel or any other
    * kind of sampled data.
    public interface Channel {
         public void fill(double[] data);
         public double get(int i);
         public double getAverage();
         public int size();
    public class DefaultChannel implements Channel {
         private double[] data;
         public void fill(double[] data) {
              this.data = new double[data.length];
              for(int i = 0; i < data.length; i++)
                   this.data[i] = data;
         public double get(int i) {
              if(i < 0 || i >= data.length)
                   throw new IndexOutOfBoundsException("Incorrect index.");
              return data[i];
         public double getAverage() {
              if(data.length == 0) return 0;
              double average = this.get(0);
              for(int i = 1; i < data.length; i++) {
                   average = average * i / (i + 1) + this.get(i) / (i + 1);
              return average;
         public int size() {
              return data.length;
    public class ModifiableChannel extends DefaultChannel {
         protected ChannelModifier modifier;
         public void fill(double[] data) {
              if (modifier != null) {
                   modifier.fill(data);
              } else {
                   super.fill(data);
         public void _fill(double[] data) {
              super.fill(data);
         public double get(int i) {
              if(modifier != null)
                   return modifier.get(i);
              else
                   return super.get(i);
         public double _get(int i) {
              return super.get(i);
         public double getAverage() {
              if (modifier != null) {
                   return modifier.getAverage();
              } else {
                   return super.getAverage();
         public double _getAverage() {
              return super.getAverage();
    public class ChannelModifier extends ModifiableChannel {
         protected ModifiableChannel delegate;
         protected ModifiableChannel root;
         protected ChannelModifier tmpModifier;
         protected boolean doSwap = true;
         private void pre() {
              if(doSwap) { // we only want to swap out modifiers once when the
                   // top call in the chain is made, after that we want to
                   // proceed without it and finally restore doSwap to original
                   // state once ChannelModifier is reached.
                   tmpModifier = root.modifier;
                   root.modifier = this;
                   if(delegate instanceof ChannelModifier)
                        ((ChannelModifier)delegate).doSwap = false;
         private void post() {
              if (doSwap) {
                   root.modifier = tmpModifier;
              } else {
                   if(delegate instanceof ChannelModifier)
                             ((ChannelModifier)delegate).doSwap = true;
         public ChannelModifier(ModifiableChannel delegate) {
              if(delegate instanceof ChannelModifier)
                   this.root = ((ChannelModifier)delegate).root;
              else
                   this.root = delegate;
              this.delegate = delegate;
         public void fill(double[] data) {
              pre();
              if(delegate instanceof ChannelModifier)
                   delegate.fill(data);
              else
                   delegate._fill(data);
              post();
         public double get(int i) {
              pre();
              double result;
              if(delegate instanceof ChannelModifier)
                   result = delegate.get(i);
              else
                   result = delegate._get(i);
              post();
              return result;
         public double getAverage() {
              pre();
              double result;
              if(delegate instanceof ChannelModifier)
                   result = delegate.getAverage();
              else
                   result = delegate._getAverage();
              post();
              return result;
         public int size() {
              //for simplicity no support for modifying size()
              return delegate.size();
    public class DownShiftedChannel extends ChannelModifier {
         private double shift;
         public DownShiftedChannel(ModifiableChannel channel, final double shift) {
              super(channel);
              this.shift = shift;
         @Override
         public double get(int i) {
              return super.get(i) - shift;
    public class UpShiftedChannel extends ChannelModifier {
         private double shift;
         public UpShiftedChannel(ModifiableChannel channel, final double shift) {
              super(channel);
              this.shift = shift;
         @Override
         public double get(int i) {
              return super.get(i) + shift;
    Output:ch1:
    1.0
    1.0
    1.0
    1.0
    avg=1.0
    ch2:
    0.0
    0.0
    0.0
    0.0
    avg=0.0
    ch3A:
    -1.0
    -1.0
    -1.0
    -1.0
    avg=-1.0
    ch3B:
    1.0
    1.0
    1.0
    1.0
    avg=1.0
    ch4:
    0.0
    0.0
    0.0
    0.0
    avg=0.0

    jduprez wrote:
    Hello,
    unless you sell your design better, I deem it is an inferior derivation of the Adapter pattern.
    In the Adapter pattern, the adaptee doesn't have to be designed to support adaptation, and the instance doesn't even know at runtime whether it is adapted.
    Your design makes the "modifiable" class aware of the modification, and it needs to be explicitly designed to be modifiable (in particular this constrains the implementation hierarchy). Overall DesignPattern are meant to provide flexibility, your version offers less flexibility than Adapter, as it poses more constraint on the modifiable class.
    Another sign of this inflexibility is your instanceof checks.
    On an unrelated note, I intensely dislike your naming choice of fill() vs _fill()+, I prefer more explicit names (I cannot provide you one as I didn't understand the purpose of this dual method, which a good name would have avoided, by the way).
    That being said, I haven't followed your original problem, so I am not aware of the constraints that led you to this design.
    Best regards,
    J.
    Edited by: jduprez on Mar 22, 2010 10:56 PMThank you for your input, I will try to explain my design better. First of all, as I understand it the Adapter pattern is meant to translate one interface into another. This is not at all what I am trying to do here, I am trying to keep the same interface but modify behavior of objects through composition. I started thinking about how to do this when I was trying to apply the Decorator pattern to filter some data. The way I would do that in my example here is to write an AbstractChannelDecorator that delegates all methods to the Channel it wraps:
    public abstract class AbstractChannelDecorator implements Channel {
            protected Channel delegate;
    ...// code ommitted
         public double getAverage() {
              return delegate.getAverage();
    ...// code ommitted
    }and then to filter the data I would extend it with concrete classes and override the appropriate methods like so:
    public class DownShiftedChannel extends AbstractChannelDecorator {
         ...// code ommitted
         public double get(int i) {
              return super.get(i) - shift;
           ...// code ommitted
    }(I am just shifting the data here to simplify the examples but a more realistic example would be something like a moving average filter to smooth the data).
    Unfortunately this doesn't get me what I want, because getAverage() method doesn't use the filtered data unless I override it in the concrete decorator, but that means I will have to re-implement the whole algorithm. So that's pretty much my motivation for this, how do I use what on the surface looks like a Decorator pattern, but in reality works more like inheritance?
    Now as to the other points of critique you mentioned:
    I understand your dislike for such method names, I'm sorry about that, I had to come up with some way for the ChannelModifier to call ModifiableChannel's super's method equivalents. I needed some way to have the innermost wrapped object to initiate a call to the topmost ChannelModifier, but only do it once -- that was one way to do it. I suppose I could have done it with a flag and another if/else statement in each of the methods, or if you prefer, the naming convention could have been fill() and super_fill(), get() and super_get(), I didn't really think that it was that important. Anyway, those methods are not meant to be used by any other class except ChannelModifier so I probably should have made them protected.
    The instanceof checks are necessary because at some point ChannelModifier instance runs into a delegate that isn't a ChannelModifier and I have to somehow detect that, because otherwise instead of calling get() I'd call get() which in ModifiableChannel would take me back up to the topmost wrapper and start the whole call chain again, so we'd be in infinite recursion. But calling get() allows me to prevent that and go straight to the original method of the innermost wrapped object.
    I completely agree with you that the example I presented has limited flexibility in supporting multiple implementations. If I had two different Channel implementations I would need two ModifiableChannel classes, two ChannelModifiers, and two sets of concrete implementations -- obviously that's not good. Not to worry though, I found a way around that. Here's what I came up with, it's a modification of my original example with DefaultChannel replaced by ChannelImplementation1,2:
    public class ChannelImplementation1 implements Channel { ... }
    public class ChannelImplementation2 implements Channel { ... }
    // this interface allows implementations to be interchangeable in ChannelModifier
    public interface ModifiableChannel {
         public double super_get(int i);
         public double super_getAverage();
         public void setModifier(ChannelModifier modifier);
         public ChannelModifier getModifier();
    public class ModifiableChannelImplementation1
              extends ChannelImplementation1
              implements ModifiableChannel {
         ... // see DefaultChannel in my original example
    public class ModifiableChannelImplementation2
              extends ChannelImplementation1
              implements ModifiableChannel { ...}
    // ChannelModifier is a Channel, but more importantly, it takes a Channel,
    // not any specific implementation of it, so in effect the user has complete
    // flexibility as to what implementation to use.
    public class ChannelModifier implements Channel {
         protected Channel delegate;
         protected Channel root;
         protected ChannelModifier tmpModifier;
         protected boolean doSwap = true;
         public ChannelModifier(Channel delegate) {
              if(delegate instanceof ChannelModifier)
                   this.root = ((ChannelModifier)delegate).root;
              else
                   this.root = delegate;
              this.delegate = delegate;
         private void pre() {
              if(doSwap) {
                   if(root instanceof ModifiableChannel) {
                        ModifiableChannel root = (ModifiableChannel)this.root;
                        tmpModifier = root.getModifier();
                        root.setModifier(this);
                   if(delegate instanceof ChannelModifier)
                        ((ChannelModifier)delegate).doSwap = false;
         private void post() {
              if (doSwap) {
                   if(root instanceof ModifiableChannel) {
                        ModifiableChannel root = (ModifiableChannel)this.root;
                        root.setModifier(tmpModifier);
              } else {
                   if(delegate instanceof ChannelModifier)
                             ((ChannelModifier)delegate).doSwap = true;
         public void fill(double[] data) {
              delegate.fill(data);
         public double get(int i) {
              pre();
              double result;
              if(delegate instanceof ModifiableChannel)
    // I've changed the naming convention from _get() to super_get(), I think that may help show the intent of the call
                   result = ((ModifiableChannel)delegate).super_get(i);
              else
                   result = delegate.get(i);               
              post();
              return result;
         public double getAverage() {
              pre();
              double result;
              if(delegate instanceof ModifiableChannel)
                   result = ((ModifiableChannel)delegate).super_getAverage();
              else
                   result = delegate.getAverage();
              post();
              return result;
         public int size() {
              return delegate.size();
    public class UpShiftedChannel extends ChannelModifier { ...}
    public class DownShiftedChannel extends ChannelModifier { ... }

Maybe you are looking for

  • HTTP Status Code 500 Internal server error while passing complex object

    Hi When I am passing values through complex input parameter, I am getting "*HTTP Status Code 500 Internal server error: The server encountered an unexpected condition which prevented it from fulfilling the request*". Why I am getting this error? Any

  • JQuery UI tabs rendering issue in Internet Explorer

    jQuery UI tabs do not render rounded in Internet Explorer. Is there anyway I can fix that issue? Does anyone know how to apply custom image for jQuery UI tabs? Thanks. Andy

  • Down load from BSEG Table

    Hi Friends we have around 50 millions records in the Bseg table. i need to down load only 5 fields . one our friend suggested using ABAP code we can down load. But i would like to know from you is there any Transcation code to down load only 4 or 5 f

  • Profiles in PSE 8 vs. PSE 9

    I have downloaded profiles from the Internet for Hahnemuhle papers, and when printing to an Epson 3800 the profiles are not available with PSE 8. When using PSE9 the profiles are exactly where they are supposed to be. Is there a problem with PSE8 or

  • Get Info says C-Drive (256SSD) space is 80GB content/33.5 GB available - where is the missing 100+GB?

    Question is how do I determine where the invisible content is - and how can I clean/remove /move the content to clear space on the C-Drive? My MacPro C-drive is a 256 GB SSD and it has 80GB of program/system/library/User data burned into the four fol