Component-Based Software Engineering Designing the Remote Interface Paul Krause.
-
Upload
julian-dickerson -
Category
Documents
-
view
216 -
download
0
Transcript of Component-Based Software Engineering Designing the Remote Interface Paul Krause.
Component-Based Component-Based Software EngineeringSoftware Engineering
Designing the Remote InterfaceDesigning the Remote Interface
Paul KrausePaul Krause
Why is it important?Why is it important?
““Every program has (at least) two purposes: Every program has (at least) two purposes: the one for which it was written, and the one for which it was written, and
another for which it wasn’t”another for which it wasn’t”
Alan PerlisAlan Perlis
First cut at AccountFirst cut at Account
public interface Account extends Remote {public interface Account extends Remote {
public Money getBalance() throws RemoteException;public Money getBalance() throws RemoteException;
public void MakeDeposit(Money amount) throws public void MakeDeposit(Money amount) throws
RemoteException, NegativeAmountException;RemoteException, NegativeAmountException;
public void MakeWithdrawal(Money amount) throws public void MakeWithdrawal(Money amount) throws
RemoteException, NegativeAmountException,RemoteException, NegativeAmountException,
OverdraftException;OverdraftException;
}}
Or, use “method objects”Or, use “method objects”
public interface Account extends Remote {public interface Account extends Remote {
public Money getBalance() throws RemoteException;public Money getBalance() throws RemoteException;
public void public void
postTransaction(Transaction postTransaction(Transaction transaction)transaction)
throws RemoteException,throws RemoteException,
TransactionException;TransactionException;
}}Transaction
Withdrawal Deposit ??…
CautionCaution
Using method objects without thinking Using method objects without thinking carefully about the security implications carefully about the security implications can be dangerouscan be dangerous
If not you this approach becomes an open If not you this approach becomes an open invitation to load a virus into the mission-invitation to load a virus into the mission-critical part of the applicationcritical part of the application
Discount this for now:Discount this for now:
Consider adding a method to transfer money Consider adding a method to transfer money between accountsbetween accounts
public void public void transferMoneyTo(Account account, Money amount) transferMoneyTo(Account account, Money amount) throws RemoteException, OverdraftException, throws RemoteException, OverdraftException, NegativeAmountException, InvalidAccountException;NegativeAmountException, InvalidAccountException;
account1.transferMoneyTo(account2, money);account1.transferMoneyTo(account2, money);
Or:Or:TransferMoney transferMoney TransferMoney transferMoney
= new TransferMoney(account2, money);= new TransferMoney(account2, money);account1.postTransaction(transferMoney);account1.postTransaction(transferMoney);
General ruleGeneral rule
““If it isn’t an object on the Client side, then If it isn’t an object on the Client side, then it shouldn’t be an object on the interface”it shouldn’t be an object on the interface”
Otherwise, in this case we have to:Otherwise, in this case we have to: Display a form to get data from the userDisplay a form to get data from the user Enter data to build the transaction objectEnter data to build the transaction object Send the Send the TransactionTransaction object to the Server object to the Server Clear the reference to the Clear the reference to the TransactionTransaction
objectobject
Passing values or objects?Passing values or objects?
public void makeDeposit(Money amount) throws public void makeDeposit(Money amount) throws RemoteException, RemoteException,
NegativeAmountExceptionNegativeAmountException
The choice is between sending a primitive The choice is between sending a primitive argument: float or int.argument: float or int.
Or wrapping up the value as an object: Or wrapping up the value as an object: Money.Money.
Pro: flexibilityPro: flexibility Con: bandwidthCon: bandwidth
E.g. Money as an integerE.g. Money as an integer
An integer is 4 bytes longAn integer is 4 bytes long Consider:Consider:
NaiveMoney – straightforward wrapperNaiveMoney – straightforward wrapper SmartMoney – more efficient use of serialisationSmartMoney – more efficient use of serialisation
Serializing first instance of NaiveMoneySerializing first instance of NaiveMoney 235 bytes235 bytes
Serializing subsequent instances …Serializing subsequent instances … 40 per instance40 per instance
Serializing first instance of SmartMoneySerializing first instance of SmartMoney 162 bytes162 bytes
Serializing subsequent instances …Serializing subsequent instances … 15 per instance15 per instance
Who wins now?Who wins now?
““If it isn’t an object on the client side, it If it isn’t an object on the client side, it shouldn’t be an object in the interface”shouldn’t be an object in the interface”
Change to:Change to: ““If it isn’t an object on the client side, it If it isn’t an object on the client side, it
shouldn’t be an object in the interface …shouldn’t be an object in the interface … unlessunless the object is a natural collection of the object is a natural collection of
a set of related values”a set of related values”““If you have a procedure with ten If you have a procedure with ten
parameters, you probably missed someparameters, you probably missed some.”.”
Money as an object?Money as an object?
Money as a float: dddd.ccccMoney as a float: dddd.cccc VeryVery bad news as this introduces potential for bad news as this introduces potential for
floating point errors into accountingfloating point errors into accounting Money as a String: “dddd Dolars and cc Money as a String: “dddd Dolars and cc
Cents”Cents” Needs a parser to extract each part, and this Needs a parser to extract each part, and this
may need to be changed if we change may need to be changed if we change currencycurrency
Answer: Allow a range of Money classesAnswer: Allow a range of Money classes
Return values?Return values?
Should we receive objects or primitive Should we receive objects or primitive values?values?
Generally, this is easy as we only have a Generally, this is easy as we only have a single return valuesingle return value So make it an objectSo make it an object
Possible exception if returning a boolean Possible exception if returning a boolean success flag: success flag: public boolean doThis();public boolean doThis(); But can be better to return void and throw an But can be better to return void and throw an
exception if the operation failsexception if the operation fails
Applying to AccountApplying to Account
getBalance()getBalance() returns an object ( returns an object (MoneyMoney))
makeDeposit()makeDeposit() and and makeWithdrawal()makeWithdrawal() return return voidvoid With informative exceptions if they failWith informative exceptions if they fail
Do method calls waste Do method calls waste bandwidth?bandwidth?
Warning with serialisationWarning with serialisation Deep copiesDeep copies
Returning multiple valuesReturning multiple values
public interface MortgageSalesHelper extends Remote public interface MortgageSalesHelper extends Remote
{{
public ArrayList public ArrayList
getAllAccountswithBalanceOver(Money getAllAccountswithBalanceOver(Money amount) amount)
throws RemoteException;throws RemoteException;
// …// …
}}
Could return any number of accounts Could return any number of accounts greater than the specified amountgreater than the specified amount All in one goAll in one go
ProblemsProblems
Degrades perceived client performanceDegrades perceived client performance Increases performance varianceIncreases performance variance Large all-at-once network hitLarge all-at-once network hit Large commitment to a single client by serverLarge commitment to a single client by server Penalizes client mistakesPenalizes client mistakes
Solution:Solution: Use an iterator in this case to return manageable Use an iterator in this case to return manageable
(and interruptible) chunks of data(and interruptible) chunks of data
Conceptual OperationsConceptual Operations
Is each conceptual operation a single Is each conceptual operation a single method call?method call?
Consider a Printer service:Consider a Printer service:public int getNumberOfSheetsInPaperFeeder() throws…public int getNumberOfSheetsInPaperFeeder() throws…
public int getTonerLevel() throws…public int getTonerLevel() throws…
public int getTimeTillPaperRunsOut() throws…public int getTimeTillPaperRunsOut() throws…
……
Much better to group together frequently Much better to group together frequently performed sequences of commandsperformed sequences of commands
Revised Printer exampleRevised Printer example
public class PrinterStatus extends Serializable {public class PrinterStatus extends Serializable {
public int numberOfSheetInPaperFeeder;public int numberOfSheetInPaperFeeder;
public int tonerLevel;public int tonerLevel;
public int estimatedTimeToPaperRunOut();public int estimatedTimeToPaperRunOut();
// …// …
}}
public interface Printer extends Remote {public interface Printer extends Remote {
public PrinterStatus getStatus() throws public PrinterStatus getStatus() throws
RemoteException;RemoteException;
// …// …
}}
Applied to AccountApplied to Account
This favours including This favours including transferMoney()transferMoney() in the interface in preference to just using in the interface in preference to just using the sequence the sequence makeWithdrawal(); makeWithdrawal(); makeDepositmakeDeposit();();
Exposing MetadataExposing Metadata
Does the interface expose the right Does the interface expose the right amount of metadata?amount of metadata? Functional methodsFunctional methods Descriptive methodsDescriptive methods
E.g. with a printer, can you find out:E.g. with a printer, can you find out: Types and sizes of paper handledTypes and sizes of paper handled Does it handle foils?Does it handle foils? Can it print in colour?Can it print in colour?
Applied to AccountApplied to Account
No problem here. Individual accounts are No problem here. Individual accounts are registered in the naming serviceregistered in the naming service The client must already know the server’s The client must already know the server’s
metadatametadata