



台大杜鵑節

台北北門


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Component({ selector: 'sub-task', directives: [MODAL_DIRECTIVES, SELECT_DIRECTIVES, NgClass], providers: [SubtaskService, UserService, IssueService, ProjectService], templateUrl: 'sub.task.html' }) export class SubTaskComponent implements OnInit { @Input() issue: Issue; @Input() watchers: Watcher[]; @Output() refreshIssueEvent = new EventEmitter(); callParent() { this.refreshIssueEvent.emit(this.issue.id); } //... } |
1 2 3 | <div class="container" *ngIf="issue.id"> <sub-task [issue]="issue" [watchers]="issue.watchers" (refreshIssueEvent)="refreshIssue($event)"></sub-task> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Component({ selector: 'issue-detail', templateUrl: 'issue.detail.html', providers: [IssueService] }) export class IssueDetailComponent implements OnInit, OnDestroy { refreshIssue(issueId: number){ this.issueService.getIssue(issueId.toString()).subscribe( data => { this.issue = data; } ); } //... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | @Component({ selector: 'sub-task', directives: [MODAL_DIRECTIVES, SELECT_DIRECTIVES, NgClass], providers: [SubtaskService, UserService, IssueService, ProjectService], templateUrl: 'sub.task.html' }) export class SubTaskComponent implements OnInit { @Input() issue: Issue; @Input() watchers: Watcher[]; // ... } |
1 2 3 | <div class="container" *ngIf="issue.id"> <sub-task [issue]="issue" [watchers]="issue.watchers"></sub-task> </div> |
雖然在一般遇到的案例裡,使用 if - then - else 比多型更實用些,但絕大多數用 polymorphism 的寫作風格會讓程式碼更精簡、更易讀,且更少脆弱的程式碼。所以在我們的程式碼裡,要是錯過使用 polymorphism 的機會,便會逐漸增加 if - then - else 敘述句的數量。試試 command pattern 吧
package albert.practice.designpattern.command; import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; @AllArgsConstructor @Data @Slf4j public class Robot { private String robotName; public void goAhead() { log.debug(robotName + " 前進 !"); } public void turnLeft() { log.debug(robotName + " 左轉 !"); } public void turnRight() { log.debug(robotName + " 右轉 !"); } public void turnBack() { log.debug(robotName + " 後退 !"); } }
package albert.practice.designpattern.command; public enum CommandEnum { GO_HEAD, TURN_BACK, TURN_RIGHT, TURN_LEFT; }
package albert.practice.designpattern.command; public class RobotTestClient { public static void main(String[] args) { Robot robot = new Robot("瓦力"); RobotTestClient client = new RobotTestClient(); client.executeRobot(robot, CommandEnum.GO_HEAD); client.executeRobot(robot, CommandEnum.TURN_LEFT); client.executeRobot(robot, CommandEnum.TURN_RIGHT); } public void executeRobot(Robot robot, CommandEnum command) { if (CommandEnum.GO_HEAD == command) { robot.goAhead(); } else if (CommandEnum.TURN_BACK == command) { robot.turnBack(); } else if (CommandEnum.TURN_LEFT == command) { robot.turnLeft(); } else if (CommandEnum.TURN_RIGHT == command) { robot.turnRight(); } } }
package albert.practice.designpattern.command; public interface Command { void execute(); }
package albert.practice.designpattern.command; public class GoAheadCommand implements Command { private Robot robot; public GoAheadCommand(Robot robot) { super(); this.robot = robot; } @Override public void execute() { this.robot.goAhead(); } }
package albert.practice.designpattern.command;
public class TurnBackCommand implements Command {
private Robot robot;
public TurnBackCommand(Robot robot) {
super();
this.robot = robot;
}
@Override
public void execute() {
this.robot.turnBack();
}
}
package albert.practice.designpattern.command; public class TurnLeftCommand implements Command { private Robot robot; public TurnLeftCommand(Robot robot) { super(); this.robot = robot; } @Override public void execute() { this.robot.turnLeft(); } }
package albert.practice.designpattern.command; public class TurnRightCommand implements Command { private Robot robot; public TurnRightCommand(Robot robot) { super(); this.robot = robot; } @Override public void execute() { this.robot.turnRight(); } }
package albert.practice.designpattern.command; public class RobotTestClient { public static void main(String[] args) { Robot robot = new Robot("瓦力"); new GoAheadCommand(robot).execute(); new TurnLeftCommand(robot).execute(); new TurnRightCommand(robot).execute(); } }
1 2 3 4 5 6 7 8 9 | String url = "http://192.168.0.1/users/" + userId + "/edit"; Document document = Jsoup.connect(url).get(); Elements mailNotificationElements = document.select("[name=user[mail_notification]]").select("option"); for (Element element : mailNotificationElements) { if ("selected".equals(element.attr("selected"))) { log.debug("the mail_notification value = " + element.val()); break; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | String url = "http://192.168.0.1/users/" + userId + "/edit"; // Connect to redmine url and get HTML document Document document = Jsoup.connect(url).get(); // Find elements that match [name=user[admin]] Elements adminElements = document.select("[name=user[admin]]"); for (Element element : adminElements) { // if the element has checked="checked" attribute, it means this user is administrator, // or this user is a normal user if ("checked".equals(element.attr("checked"))) { log.debug("this user is admin"); break; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | <div class="row" *ngIf="roles"> <div> <label>角色</label> </div> <div *ngFor="let role of roles" style="display: inline-block"> <div class="checkbox"> <label style="padding-right:10px; padding-left:10px" > <input type="checkbox" [(ngModel)]="role.isSelected" (change)="checkRole(role)"> {{ role.name }} </label> </div> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <div class="row" *ngIf="roles"> <div> <label>角色</label> </div> <div *ngFor="let role of roles" style="display: inline-block"> <div class="checkbox"> <label style="padding-right:10px; padding-left:10px" > <input type="checkbox" [(ngModel)]="role.isSelected" (change)="checkRole(role)"> <span class="checkbox-material"><span class="check"></span></span> {{ role.name }} </label> </div> </div> </div> |
@Data @ToString public static class DsnDto { @JsonProperty("public") private String publicStr; private String secret; private String csp; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Caused by: liquibase.exception.LockException: Could not acquire change log lock. Currently locked by albert-PC (10.11.22.33) since 2016/9/26 下午 2:06 at liquibase.lockservice.StandardLockService.waitForLock(StandardLockService.java:190) ~[liquibase-core-3.5.1.jar:na] at liquibase.Liquibase.update(Liquibase.java:196) ~[liquibase-core-3.5.1.jar:na] at liquibase.Liquibase.update(Liquibase.java:192) ~[liquibase-core-3.5.1.jar:na] at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:434) ~[liquibase-core-3.5.1.jar:na] at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:391) ~[liquibase-core-3.5.1.jar:na] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] ... 160 common frames omitted |
UPDATE DATABASECHANGELOGLOCK SET LOCKED=FALSE, LOCKGRANTED=null, LOCKEDBY=null where ID=1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <div class="row"> <div class="col-sm-12"> <div class="form-group" style="display:inline"> <label>即時應用系統異常追蹤整合</label> <div> <input type="radio" name="sentryOption" [checked]="newProject.sentryOption==='0'" (click)="newProject.sentryOption='0'">立即建立專案關聯 <span style="padding-left:20px"> <input type="radio" name="sentryOption" [checked]="newProject.sentryOption==='1'" (click)="newProject.sentryOption='1'">選擇既有的關聯 </span> <span style="padding-left:5px"> <select class="form-control" name="sentryProjectId" [(ngModel)]="newProject.sentryProjectId" [style.width.px]="50" *ngIf="newProject.sentryOption==='1'" > <option value="" selected> 請選擇 </option> <option *ngFor="let sp of sentryProjects" [ngValue]="sp.slug">{{sp.slug}}</option> </select> </span> </div> </div> </div> </div> |
display:inline-block
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <div class="row"> <div class="col-sm-12"> <div class="form-group" style="display:inline"> <label>即時應用系統異常追蹤整合</label> <div> <input type="radio" name="sentryOption" [checked]="newProject.sentryOption==='0'" (click)="newProject.sentryOption='0'">立即建立專案關聯 <span style="padding-left:20px"> <input type="radio" name="sentryOption" [checked]="newProject.sentryOption==='1'" (click)="newProject.sentryOption='1'">選擇既有的關聯 </span> <span style="padding-left:5px"> <select class="form-control" name="sentryProjectId" [(ngModel)]="newProject.sentryProjectId" [style.width.px]="50" *ngIf="newProject.sentryOption==='1'" style="display:inline-block;"> <option value="" selected> 請選擇 </option> <option *ngFor="let sp of sentryProjects" [ngValue]="sp.slug">{{sp.slug}}</option> </select> </span> </div> </div> </div> </div> |