I have created a class to interact with my database:
class MyDatabase {
connect() { /* ... */ }
}
And the database has two types of modes: admin and client. I would like to have different classes for each mode:
class MyDatabaseAdmin {}
class MyDatabaseClient {}
Both of them will implement the same interface, but with different underline implementations. I would like to know if there is a design pattern to instantiate the parent MyDatabase choosing one over the other. Something like:
const db = new MyDatabase({ mode: 'admin' })
db.connect() // parent calls MyDatabaseAdmin.connect
I don't need a perfect answer, just some direction to what I should search for.
Thanks.
If they have no code in common, then they are really just two separate classes. You probably don't even want the admin code to be present in the browser since it can't be used there anyway.
You could have a single factory function that looks at an admin parameter and instantiates the appropriate database object and returns it, but I don't think I even see why you'd bother with that.
Just have each client instantiate the appropriate DB object. If there's any common code, you can have both implementations inherit from a common base and put the common code in the base class.
Right! I forgot to mention, but there are some common code... the connection and authentication is exactly the same, for example. Do you happen to know any design pattern that would perfect fit for this use case? Should I research about Factories?
I think a common base class with inheritance solves the problem here. It gives you a natural place to put the common code without having to include server-side code in the client implementation. The browser implementation and the server implementation would each be a subclass that are present only on their respective platforms. The common base class would be present and used in both places.
You just have the client instantiate the appropriate leaf class and the shared code lives in the base class. If you want to hide the actual class constructors, you can use a factory function (it's just a simple function that looks at conditions and makes an appropriate object for you and returns it), but I'm not sure there's any compelling reason to use a factory function here. You would only include the appropriate leaf class on the platform for which it is intended so there's no place where you might use one or the other in the same code.
would you consider having only 'users'? then each user could have a 'role' that would be either 'user' or 'admin'. So based on that 'role' you will define the privileges for each user. I find this solution easier for this kind of stuff but let me know if it does not match your case.
Related
Can you recommend any great learning resources on inversify in typescript?
I have looked at http://inversify.io/ and have followed the example but am not grasping how it really works or why I need it.
A great video learning resource would be great or a simple easy beginner example.
Thanks for the help.
The idea of Inversion Of Control, aka dependency injection is that a class hands over control (read: responsibility) for instantiating dependent instances that the class needs to the container that will provide them with these instances instead.
So you would not do something like:
public constructor() {
this._katana = new Katana();
this._shuriken = new Shuriken();
}
I am not going to give a full example, because I would basically be copy-pasting the code that they clearly share on their website in the section 'The Basics'.
They give an example of constructor injection:
public constructor(
#inject(TYPES.Weapon) katana: Weapon,
#inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon
) {
this._katana = katana;
this._shuriken = shuriken;
}
This is specifically useful for:
Testing, since the dependent object can be mocked and injected
Injecting dependent objects based on variable parameters.
For example, depending on environment you may want to inject a different configuration object with different values. This is just one example.
Constructor injection is usually preferred over property injection, as the library also seems to support this.
Note that what is injected is an interface, not a concrete class type.
So the class just declares that it needs an object of type Weapon / ThrowableWeapon.
The concrete binding happens in inversify.config.ts:
container.bind<Weapon>(TYPES.Weapon).to(Katana)
So the reason why this is useful is that you have the ability to provide concrete classes at runtime. You don't need to pre-define (hardcode) them in the class.
I recently watched tutorial of my teacher, and he show us this code:
And he also said products array which is type of any [] IS NOT USING BENEFITS OF STRONGLY TYPE which is feature of TypeScript so it should be defined as INTERFACE, but I'm wondering now, why he did not create a class and that products array might be of that class type??
He said Interfaces purpose is to provide strongly typing and tooling support..
So he wrote this interface:
So I'm wondering why he did not create a class like :
export class Product .. and later he would use products : Product [] ..
So basically I can not figure out why is Interface as dataType better here instead of class?
Sorry for screenshots and not real code, that's because he hosted online video lessons..
Thanks
Check this text writen by James Henry maybe that will clarify you this issue. In short: Unlike classes, interfaces are completely removed during compilation and so they will not add any unnecessary bloat to our final JavaScript code.
Think of interfaces as a blueprint for your object — a brief set of instructions that guarantees that a certain set of fields / methods will be available on objects tagged with that interface. They provide you with a means of taking advantage of strong typing while keeping your code as lightweight as possible. As mentioned, the interface is removed and compile time because it doesn’t actually have any programmatic implications — it’s strictly to make the code less error-prone and easier to work with for you and whoever else.
If you need to specify implementation details, such as getter / setter / constructor logic or methods, that’s when you would use a class. In fact, if the logic for the calculateDiscount() method in your example is expected to remain the same across all Products, it’s possible that a class could make more sense in this case.
Classes can work as interfaces in TypeScript. Interfaces cannot work as classes. One of them can be chosen based on the principle of parsimony.
Things like
class SomeProductClass implements ProductClass {...}
and
const plainProduct: ProductClass = {...};
happen often.
However, when a class is defined, it's expected that it or its descendant will be instantiated. If it won't, this would be misleading, because this is what interfaces are for.
It's common in Angular to define abstract class that won't be instantiated, but that's because abstract classes can be used as both interfaces and dependency injection tokens.
I'm looking for an answer to what is the best practice to customize default sails.js CRUD blueprints. The simple example of what I mean is let's say I need to create SomeModel, using standard blueprint POST \someModel action, and also I want to get information about authenticated user from req object and set this property to req.body to use values.user.id in beforeCreate function:
module.exports = {
attributes: {
// some attributes
},
beforeCreate: function (values, cb) {
// do something with values.user.id
}
};
I'm very new to sails.js and don't want to use anti-patterns, so I'm asking for inputs on what is the right way to handle such cases. Also it would be great to have some good resources on that topic.
There are a few options open to you which you've identified, and as usual, it depends on your use case. Here are some thoughts on the three options you listed in your comment:
Override controller/create - Of the three, this is the best option because it doesn't clog up code in routes or policies for a single instance.
Write controller/action and add to config/routes.js - While this works, it defeats the purpose of using blueprints, and you have to do all the code in option 1 plus making your routes code messier.
Apply a policy for a single create action - To do this, you will not only have to clutter up your /policies folder but also your policies.js file. This is more code AND it puts the logic for one controller method in two separate places, neither of which is the controller.
Out of these three, option 1 is the best because it contains the code to its context (the controller) and minimizes written code. This is assuming that you only want to alter the create method for one model.
Side note:
As an example of how your use case determines your implementation, here is how I've set my Sails app up which has a few REST routes, each of which responds differently based on the user calling the route (with a valid Facebook token):
Only uses blueprint action routes (not blueprint REST routes)
First goes through the policies:
'*': ['hasFBToken', 'isTokenForMyApp', 'extractFBUser', 'extractMyAppUser'] which store fbuser, myappuser, and other variables in req.body
At this point, my controller function (e.g. controller.action()) is called and can access information about that user and determine if it has the correct permissions to do CRUD.
Pros of this system:
All code for each CRUD operation is contained within its controller function
Minimal to no code in routes.js (no code) or policies.js (one line) or /policies
Works well with API Versioning (e.g. controllers/v1.0/controller.js), which is much easier to do with versioned controllers than versioned models. That means that I can create a new API version and simply by creating a controller in /v2.0 with a function action(), calls such as POST /v2.0/controller/action will exist with no extra routing needed.
Hopefully this example helps illustrate how design decisions were made to offer functionality like API versioning and consolidate code in its specific context.
In my application, there are several components which will generate various different types of application-specific events. These events will be published out to a broker and be delivered to N number of clients. Some of these clients are other Java classes in my server-side app, but the main consumer is my javascript-based WebUI.
My current approach thus-far was to define an abstract event base class to encapsulate some common fields, then implement a specific event class for each event.
This has been working fine, except now I need to maintain the event on both the javascript and java side so either side can react to the others events.
I had a thought this morning that I could utilize Thrift (which the project already makes heavy use of) to define the event data structures and auto-generate the classes on either side. This not only handles the tedium of writing the class files, but ensures consistency.
My issue is that since data objects in thrifts are Structs (which can't be extended), I have no way of encapsulating the common fields nor can I pass the events along using a single base class.
The workaround I've come up with thus far is to define a struct inside the thrift IDL to act as a 'base' class, with an optional field for each and every event type that I define. This would still let me have a single class to refer to events generically while also letting me capture the relevant data when spawning events.
Maybe this is just me not being very familiar with thrift, but this feels like a hack. Am I way off, or is this an ok approach? Is there a better way to accomplish this?
Thrift as an serialization and RPC mechanism allows only for one-to-one connections, so that will not really solve the task. But you're not lost.
If you want to do one-to-many, you should use some messaging system. Thrift can be easily combined with messaging systems on various levels. The /contrib folder of the source tree holds a few examples on how to achieve that.
Using a Thrift union as the envelope to hold all you various data structures is a valid solution, because it allows to minimize the serialization and deserialzation code - you only need one pair of functions to deal with always the same Envelope structure (which of course may have different contents).
struct Foo { ... some member fields ... }
struct Bar { ... some member fields ... }
struct Baz { ... some member fields ... }
union Envelope {
1: Foo foo
2: Bar bar
3: Baz baz
}
I've started to wrap my functions inside of Objects, e.g.:
var Search = {
carSearch: function(color) {
},
peopleSearch: function(name) {
},
...
}
This helps a lot with readability, but I continue to have issues with reusabilty. To be more specific, the difficulty is in two areas:
Receiving parameters. A lot of times I will have a search screen with multiple input fields and a button that calls the javascript search function. I have to either put a bunch of code in the onclick of the button to retrieve and then martial the values from the input fields into the function call, or I have to hardcode the HTML input field names/IDs so that I can subsequently retrieve them with Javascript. The solution I've settled on for this is to pass the field names/IDs into the function, which it then uses to retrieve the values from the input fields. This is simple but really seems improper.
Returning values. The effect of most Javascript calls tends to be one in which some visual on the screen changes directly, or as a result of another action performed in the call. Reusability is toast when I put these screen-altering effects at the end of a function. For example, after a search is completed I need to display the results on the screen.
How do others handle these issues? Putting my thinking cap on leads me to believe that I need to have an page-specific layer of Javascript between each use in my application and the generic methods I create which are to be used application-wide. Using the previous example, I would have a search button whose onclick calls a myPageSpecificSearchFunction, in which the search field IDs/names are hardcoded, which marshals the parameters and calls the generic search function. The generic function would return data/objects/variables only, and would not directly read from or make any changes to the DOM. The page-specific search function would then receive this data back and alter the DOM appropriately.
Am I on the right path or is there a better pattern to handle the reuse of Javascript objects/methods?
Basic Pattern
In terms of your basic pattern, can I suggest modifying your structure to use the module pattern and named functions:
var Search = (function(){
var pubs = {};
pubs.carSearch = carSearch;
function carSearch(color) {
}
pubs.peopleSearch = peopleSearch;
function peopleSearch(name) {
}
return pubs;
})();
Yes, that looks more complicated, but that's partially because there's no helper function involved. Note that now, every function has a name (your previous functions were anonymous; the properties they were bound to had names, but the functions didn't, which has implications in terms of the display of the call stack in debuggers and such). Using the module pattern also gives you the ability to have completely private functions that only the functions within your Search object can access. (Just declare the functions within the big anonymous function and don't add them to pubs.) More on my rationale for that (with advantages and disadvantages, and why you can't combine the function declaration and property assignment) here.
Retrieving Parameters
One of the functions I really, really like from Prototype is the Form#serialize function, which walks through the form elements and builds a plain object with a property for each field based on the field's name. (Prototype's current – 1.6.1 – implementation has an issue where it doesn't preserve the order of the fields, but it's surprising how rarely that's a problem.) It sounds like you would be well-served by such a thing and they're not hard to build; then your business logic is dealing with objects with properties named according to what they're related to, and has no knowledge of the actual form itself.
Returning Values / Mixing UI and Logic
I tend to think of applications as objects and the connections and interactions between them. So I tend to create:
Objects representing the business model and such, irrespective of interface (although, of course, the business model is almost certainly partially driven by the interface). Those objects are defined in one place, but used both client- and server-side (yes, I use JavaScript server-side), and designed with serialization (via JSON, in my case) in mind so I can send them back and forth easily.
Objects server-side that know how to use those to update the underlying store (since I tend to work on projects with an underlying store), and
Objects client-side that know how to use that information to render to the UI.
(I know, hardly original!) I try to keep the store and rendering objects generic so they mostly work by looking at the public properties of the business objects (which is pretty much all of the properties; I don't use the patterns like Crockford's that let you really hide data, I find them too expensive). Pragmatism means sometimes the store or rendering objects just have to know what they're dealing with, specifically, but I do try to keep things generic where I can.
I started out using the module pattern, but then started doing everything in jQuery plugins. The plugins allow to pass page specific options.
Using jQuery would also let you rethink the way you identify your search terms and find their values. You might consider adding a class to every input, and use that class to avoid specifically naming each input.
Javascript is ridiculously flexible which means that your design is especially important as you can do things in many different ways. This is what probably makes Javascript feel less like lending itself to re-usability.
There are a few different notations for declaring your objects (functions/classes) and then namespacing them. It's important to understand these differences. As mentioned in a comment on here 'namespacing is a breeze' - and is a good place to start.
I wouldn't be able to go far enough in this reply and would only be paraphrasing, so I recommend buying these books:
Pro JavaScript Design Patterns
Pro Javascript techniques