Wednesday, 16 December 2015

Design Pattern

1. builder pattern
  • instead of using many constructors, it use builder to handle multiple parameters
public class Pizza {
    private int size; 
    private boolean cheese; 
    private boolean pepperoni; 
    private boolean bacon; 

    public static class Builder { 
        private final int size; 
        private boolean cheese = false; 
        private boolean pepperoni = false; 
        private boolean bacon = false; 

        public Builder(int size) { this.size = size; } 
        public Builder cheese(boolean value) { cheese = value; return this; } 
        public Builder pepperoni(boolean value) { pepperoni = value; return this; } 
        public Builder bacon(boolean value) { bacon = value; return this; } 

        public Pizza build() { return new Pizza(this);}  //build pizza from builder
    }

    private Pizza(Builder builder) { 
        size = builder.size; 
        cheese = builder.cheese; 
        pepperoni = builder.pepperoni; 
        bacon = builder.bacon; 
    } 
}

Pizza pizza = new Pizza.Builder(12).cheese(true).pepperoni(true).bacon(true).build();




2. adapter pattern
  • translate one interface to another
public interface Duck { 
    public void quack();
    public void fly();
}

public interface Turkey { 
    public void gobble();
    public void fly();
}

public class TurkeyAdapter implements Duck {
    Turkey turkey;

    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }

    public void quack() {
        turkey.gobble();
    }

    public void fly() {
        turkey.fly();
    }
}

public static void main(String[] args) {
    WildTurkey turkey = new WildTurkey();
    Duck turkeyAdapter = new TurkeyAdapter(turkey);

    turkeyAdapter.quack();
    turkeyAdapter.fly();
}


3. bridge pattern
  • decouple abstraction from its implementation
  • prefer composition over inheritance
  • very similar to strategy pattern
/** abstraction */ 
abstract class Shape { 
    protected DrawingAPI drawingAPI; 
    protected Shape(DrawingAPI drawingAPI){ this.drawingAPI = drawingAPI; } 
}

class CircleShape extends Shape {  
    public CircleShape(DrawingAPI drawingAPI) { super(drawingAPI); } 
}

/** implementor */
interface DrawingAPI { public void drawCircle(double x, double y, double radius); }

class DrawingAPI1 implements DrawingAPI { 
    public void drawCircle(double x, double y, double radius) {} 

class DrawingAPI2 implements DrawingAPI { 
    public void drawCircle(double x, double y, double radius) {} 

public static void main(String[] args) {  
    Shape s1 = new CircleShape(1, 2, 3, new DrawingAPI1()); 
    Shape s2 = new CircleShape(5, 7, 9, new DrawingAPI2()); 
}


4. command pattern
  • 'command' object include 'receiver' and an 'execute' method on 'receiver'
  • 'client' create 'command' object and store them in 'invoker' (a list or queue)
public interface Command { void execute(); }  //command interface

public class Light {   //receiver
    public void on() { }
    public void off() { }

public class onCommand implements Command {   //on command
    private Light light; 
    public onCommand (Light light) { this.light = light; } 
    @Override public void execute() { light.on(); } 
}

public class Switch {      //invoker
    private List<Command> l = new ArrayList<Command>();
    public void storeAndExecute(Command cmd) { 
        this.l.add(cmd); 
        cmd.execute(); }  // optional
}

public class offCommand implements Command {   //off command
    private Light light;
    public offCommand(Light light) { this.light = light; }
    @Override public void execute() { light.off(); }

public class TestSwitch { 
    public static void main(String[] args){ 
        Light lamp = new Light(); 
        Command on = new onCommand(lamp); 
        Command off = new offCommand(lamp); 

        Switch mySwitch = new Switch(); 
        switch(args[0]) { 
            case "ON": 
                mySwitch.storeAndExecute(on); 
                break; 
            case "OFF": 
                mySwitch.storeAndExecute(off); 
                break; 
            default: break; 
        } 
    } 
}


5. mvc pattern
  • controller 'observe' and interact with view
  • controller 'observe' and interact with model
  • for security reason, view not necessarily 'observe' and interact with model (e.g. secure database)
6. singleton pattern
  • using enum


reference:
1. when would you use the builder pattern?
2. bridge pattern
3. java singleton using enum

Wednesday, 9 December 2015

git

1. vocabulary
  • working directory/staging area/repository
  • origin: when you clone another repository, git automatically creates a remote named "origin" and points to it
  • master: the main branch

2. git config
  • /etc/gitconfig, ~/.gitconfig, .git/config, one override another
  • git config --list
  • .gitignore specify files not committed to repo, for eclipse project, can be target/, .classpath, .project, .settings/

3. common git command
  • git init
  • git clone
  • git config 
  • git checkout -b new_branch             //create new branch and checkout 
  • git checkout -track -b origin/daves_branch           //create local branch to track remote
  • git commit -m 'initial commit'
  • git add --all
  • git commit --amend                          //combine commit and change comment
  • git reset HEAD
  • git reset --soft HEAD^
  • git reset --soft HEAD~1
  • git reset -- hard HEAD^ 
  • git clean -f -d                                    //remove permanently untracked directory and file
  • git reset                                             //unstage all 
  • git revert <commit>                         //undo a commit in the history
  • git rebase -i HEAD~2                      //combine 2 commits into 1
  • git checkout <feature_branch>
  • git merge <master_branch>            //3-way merge, create new commit C
          A---B feature
         /
   D---E---F---G master
 
          A---B---C feature
         /       /
    D---E---F---G  master 
 
          A---B feature          //fast forward
         /
   D---E- master 
 
    D---E---A---B  feature(master) 
 

  • git checkout <feature_branch>       // rebase move the STARTING POINT of  'feature' on
  • git rebase <master_branch>           // master, destroy A, B, C and create new commits A' B' C'          
          A---B---C feature
         /
   D---E---F---G master
 
                  A'--B'--C' feature
                 /
   D---E---F---G master
  • git remote add <name> <url> 
  • git remote -v
  • git fetch <remote> [branch]
  • git branch -r                                     //display remote branch
  • git branch
  • git pull = git fetch + git merge
  • git pull --rebase (by default it will perform merge, can force it to rebase) 
  • git push origin master
  • git push origin master -f           //overwrite remote branch
  • git log
  • git status
  • git diff
  • git rm
  • git mv
  • git reset --hard origin/master    //clean everything in repo

4. merge vs rebase
  • merging is always safe
  • rebasing is not (Golden Rule of Rebasing - never rebase public branches like 'master' to 'feature)

5. centralized work flow
  • single central repositary
  • work on local master branch
  • git clone
  • git pull --rebase origin master
  • git rebase -- continue
  • git push origin master

6. feature branch flow
  • work on local feature branch
  • git checkout -b feature_branch master
  • git push -u origin feature_branch
  • submit pull request in github or bitbucket (code review) 
  • git checkout master
  • git pull
  • git pull origin feature_branch
  • git push

7. gitflow workflow
  • master(release) branch and dev branch

8. stash(bitbucket) and github


9. local vs remote branch
  • always: work on local branch, rebase on remote branch, push to remote branch
  • local branch can track remote branch
  • after clone, local 'master' will track 'origin/master'
  • 'git fetch, git checkout remote-branch-name' will create local branch that track remote branch 'original/remote-branch-name', just like 'master'
  • or use 'git fetch, git checkout -b remote-branch-name origin/remote-branch-name'

10. clone with/without account
  • git clone git://github.com/SomeUser/SomeRepo.git    //without account
  • git clone git@github.com:UserName/OtherRepo.git

11. submodule
  • .gitmodules                                //define structure
  • git submodule init
  • git submodule update

12. add reviewer to github

Thursday, 3 December 2015

appium

1. use xcode to launch ios simulator
  • 'xcode' -> 'open developer tool' -> 'simulator', will run default simulator
  • now menu show simulator, 'file' to select other simulator if available

2. install ios app to simulator
  • find unsigned app in release, etc. iOS-Simulator-MyRNDemoApp.1.3.0-162.zip @https://github.com/saucelabs/my-demo-app-rn/releases
  • launch ios simulator
  • drag app to simulator,
  • or use cmd: xcrun simctl install BB6F3DD7-2BB6-428F-9673-562A23BE7480 ~/desktop/test.app

3. find device name, udid, platform version, bundle id for iso app
  • xcrun simctl list      //list available simulator with device name & udid, 'booted' means running
  • can find apple native app bundle id @https://support.apple.com/en-gb/guide/deployment/depece748c41/web
  • for custom app, find bundle id in its project, or ask developer

4. use appium inspector to inspect ios app
  • pre-requisite: run device/simulator, run appium server (cmd/ui)
  • specify 'desired capabilities'
  • can use 'bundleId' or 'app' in 'desired capability' to specify the app
  • when using 'bundleId', can find apple native app bundle id @https://support.apple.com/en-gb/guide/deployment/depece748c41/web
  • when using 'app', set 'appium:noReset' so that it will not reinstall app from filepath everytime
  • sample capability
{
  "appium:platformVersion": "13.3",
  "appium:deviceName": "iPhone 11 Pro Max",
  "appium:automationName": "XCUITest",
  "appium:bundleId": "com.apple.Preferences",
  "appium:platformName": "iOS"
}

5. use android studio to launch android simulator
  • 'more actions' -> 'sdk manager' to install sdk
  • 'more actions' -> 'virtual device manager' -> to create device
  • run device

6. install android app to android simulator
  • find .apk file in release
  • launch android simulator
  • drag apk to simulator

7. use appium inspector to inspect android app
  • similar to inspecting ios app
  • set 'ANDROID_HOME' in appium server configuration
  • sample capability
{
  "appium:appPackage": "com.saucelabs.mydemoapp.rn",
  "appium:deviceName": "emulator-5554",
  "appium:automationName": "UiAutomator2",
  "appium:appActivity": ".MainActivity",
  "appium:platformName": "android"
}

8. locator strategy
  • accessibilityId: content-desc (android), accessibility-id (ios)
  • className: class (android and ios)
  • id: id (android), name (ios)
  • name: name (android and ios)
  • xpath

5. get apk from phone
  • 'adb shell pm list packages' - list all packages
  • 'adb shell pm path com.example.someapp' - get full path in phone
  • 'adb pull /data/app/com.example.someapp-2.apk'

6. get AndroidManifest.xml
  •  apktool.bat d -f myapp.apk

7. cross platform - android/ios, mobile web/app
  • XCUITest - ios testing fw by apple for iOS 9.3 and above
  • UIAutomation - ios testing fw by apple for iOS 9.3 and lower
  • Espresso - android testing fw by google
  • UiAutomator/UiAutomator2 - android testing fw by google
  • appium use webdriver api, but it can have any of the above driver underneath, just like selenium, also use webdriver api, but can have chrome, firefox, safari driver